跨平台

React Native之组件2

2019-02-14  本文已影响15人  平安喜乐698
  1. ScrollView 滚动视图
import { ScrollView } from 'react-native';
放置在ScrollView中的所有组件都会被渲染(即使超出屏幕),所以适合用来显示数量不多的滚动元素。

必须有一个确定的高度,一般使用flex: 1(父视图宽高必须确定)

属性

keyboardDismissMode
  用户拖拽滚动视图的时候,是否要隐藏软键盘。
    'none' (默认值),不隐藏
    'on-drag',隐藏
    'interactive',[iOS] 隐藏且上滑恢复键盘。

keyboardShouldPersistTaps
  点击scrollview后是否收起键盘
    'never' (默认值),收起。此时子元素不会收到点击事件。
    'always',不收起,ScrollView也不会捕捉点击事件,但子组件可以捕获。
    'handled',当点击事件被子组件捕获时,键盘不会自动收起。这样切换TextInput时键盘可以保持状态。

scrollEnabled
  是否允许滚动。默认值为true
pagingEnabled
  是否分页。默认值为false。垂直分页在Android上不支持

contentContainerStyle
  将样式应用到子视图。

horizontal
  是否水平排列。默认值为false。
showsHorizontalScrollIndicator
  是否显示一个水平方向的滚动条。
showsVerticalScrollIndicator
  是否显示一个垂直方向的滚动条。

refreshControl
  下拉刷新。只能用于垂直视图,即horizontal不能为true。

stickyHeaderIndices
  一个子视图下标的数组,用于决定哪些成员会在滚动之后固定在屏幕顶端。举个例子,传递stickyHeaderIndices={[0]}会让第一个成员固定在滚动视图顶端。这个属性不能和horizontal={true}一起使用。

decelerationRate
  当用户抬起手指之后,滚动视图减速停下的速度。
    'normal': iOS上是0.998,Android上是0.985(默认值)
    'fast': 0.99

removeClippedSubviews
(实验特性):当此属性为true时,屏幕之外的子视图(子视图的overflow样式需要设为hidden)会被移除。这个可以提升大列表的滚动性能。默认值为true。

onContentSizeChange
  contentSize发生变化时调用,参数(contentWidth, contentHeight)
onMomentumScrollBegin
  滚动动画开始时调用
onMomentumScrollEnd
  滚动动画结束时调用

onScroll
  在滚动的过程中,每帧最多调用一次此回调函数。调用的频率可以用scrollEventThrottle属性来控制。
onScrollBeginDrag
  当用户开始拖动此视图时调用
onScrollEndDrag
  当用户停止拖动此视图时调用
alwaysBounceVertical
  [iOS]纵向总是可弹性(即使内容比滚动视图小)。
  当horizontal={true}时,默认值为false否则为true。

alwaysBounceHorizontal
  [iOS]横向总是可弹性(即使内容比滚动视图小)。当horizontal={true}时默认值为true,否则为false。

canCancelContentTouches
  [iOS] 当值为false时,一旦有子节点响应触摸操作,即使手指开始移动也不会拖动滚动视图。默认值为true。

centerContent
  [iOS] 如果滚动视图的内容比视图本身小,是否将内容居中放置。当内容比滚动视图大的时候,此属性没有作用。默认值为false。

contentInsetAdjustmentBehavior
  [iOS] enum('automatic', 'scrollableAxes', 'never默认', 'always')

contentInset
  [iOS] 内容范围相对滚动视图边缘的坐标。默认为{top: 0, left: 0, bottom: 0, right: 0}。

contentOffset
  [iOS]偏移坐标。默认值为{x: 0, y: 0}。

indicatorStyle
  [iOS]滚动条样式
    'default' 默认值,等同black。
    'black',黑色滚动条。
    'white',白色滚动条。

zoomScale
  [iOS]缩放比例。默认值为1.0。
maximumZoomScale
  [iOS]最大缩放比例。默认值为1.0。
minimumZoomScale
  [iOS]最小缩放比例。默认值为1.0。

bouncesZoom
  [iOS]当值为true时,使用手势缩放内容可以超过min/max的限制,然后在手指抬起之后弹回min/max的缩放比例。否则的话,缩放不能超过限制

bounces
  [iOS]当值为true时,如果内容范围比滚动视图本身大,在到达内容末尾的时候,可以弹性地拉动一截。如果为false,尾部的所有弹性都会被禁用,即使alwaysBounce属性为true。默认值为true。

automaticallyAdjustContentInsets
  [iOS]当滚动视图放在一个导航条或者工具条后面的时候,iOS系统是否要自动调整内容的范围。默认值为true。

pinchGestureEnabled
  [iOS]是否允许用户使用双指缩放操作。默认值为true。

scrollsToTop
  [iOS]点击状态栏时是否滚动到顶部。默认值为true。

scrollIndicatorInsets
  [iOS]决定滚动条距离视图边缘的坐标。默认值为{0, 0, 0, 0}。 {top: number, left: number, bottom: number, right: number}

scrollEventThrottle
  [iOS]滚动时scroll事件被调用的频率(单位是每秒事件数量)。更小的数值能够更及时的跟踪滚动位置,不过可能会带来性能问题,因为更多的信息会通过bridge传递。由于JS事件循环需要和屏幕刷新率同步,因此设置1-16之间的数值不会有实质区别。默认值为0,意味着每次视图被滚动,scroll事件只会被调用一次。

directionalLockEnabled
  [iOS]是否锁定只有垂直或水平方向可以滚动。默认值为false

scrollPerfTag
  [Android]

endFillColor
  [Android]有时候滚动视图会占据比实际内容更多的空间。这种情况下可以使用此属性,指定以某种颜色来填充多余的空间,以避免设置背景和创建不必要的绘制开销。一般情况下并不需要这种高级优化技巧。

overScrollMode
  [Android]覆盖默认的Scroll模式
    'auto' - 默认值,允许用户在内容超出视图高度之后可以滚动视图。
    'always' - 无论内容尺寸,用户始终可以滚动视图。
    'never' - 始终不允许用户滚动视图。

nestedScrollEnabled
  [Android]在5.0以上启用嵌套滚动。iOS上默认支持嵌套滚动。

方法

scrollTo(([x]: number), ([y]: number), ([animated]: boolean));
  滚动到指定的x, y偏移处,是否启用平滑滚动动画

scrollToEnd(([options]: object));
  滚动到视图底部(水平方向的视图则滚动到最右边)。
  scrollToEnd({animated: true})则启用平滑滚动动画,或是调用scrollToEnd({animated: false})来立即跳转。

flashScrollIndicators();
  短暂地显示滚动指示器
  1. 网页 WebView
import { WebView } from 'react-native';

例1

import React, { Component } from 'react';
import { WebView } from 'react-native';

export default class MyWeb extends Component {
  render() {
    return (
      <WebView
        originWhitelist={['*']}
        source={{ html: '<h1>Hello world</h1>' }}
        source={{uri: 'https://github.com/facebook/react-native'}}
        style={{marginTop: 20}}
      />
    );
  }
}

属性

style
  样式
    
source
  地址。uri、method、headers、body,html、baseUrl。
    
automaticallyAdjustContentInsets:
  默认为true。

originWhitelist:
  白名单列表

renderLoading:
  设置一个函数,返回一个加载指示器。前提: startInLoadingState 属性设置为 true。
renderError:
  设置一个函数,返回一个视图用于显示错误。
onLoadStart:
  加载开始后调用。
onLoadEnd:
  加载结束后调用(无论成功)。
onLoad:
  加载成功后调用。      
onError:
  加载失败后调用。

onNavigationStateChange:
  当导航状态发生变化的时候调用。
onShouldStartLoadWithRequest:
  [iOS]是否允许请求。
   
onMessage:
  在 webview 内部的网页中调用 window.postMessage 方法时可以触发此属性对应的函数,从而实现网页和 RN 之间的数据交换。 设置此属性的同时会在 webview 中注入一个 postMessage 的全局函数并覆盖可能已经存在的同名实现。网页端的 window.postMessage 只发送一个参数 data,此参数封装在 RN 端的 event 对象中,即 event.nativeEvent.data。data 只能是一个字符串。
    

    
nativeConfig:
  覆盖渲染 WebView 的原生组件。component (any)、props (object)、viewManager (object)

injectedJavaScript:
  在网页加载之前注入的一段 JS 代码。
injectJavaScript:
  注入后会立即执行。
useWebKit:
[iOS]是否使用WKWebView替代UIWebView
    
scrollEnabled:
[iOS]是否可滚动

scalesPageToFit:
控制网页内容是否自动适配视图的大小,同时启用用户缩放功能。默认为true
    
contentInset:
[iOS]内边距,默认为{top: 0, left: 0, bottom: 0, right: 0}
    
bounces:
[iOS]边缘是否可弹性,默认:true

decelerationRate:
[iOS]设置在用户停止触摸之后,此视图应以多快的速度停止滚动。normal: 0.998、fast: 0.99 (ios web view 默认)

startInLoadingState:
第一次加载时是否显示加载视图(如指示器),前提:renderLoading时必须为true 
    
mediaPlaybackRequiresUserAction:
控制 HTML5 音频和视频播放前是否需要用户点击。默认为true。
    
dataDetectorTypes:
[iOS]是否将指定内容转为可点击URL。可选值:phoneNumber、link、address、calendarEvent、none、all,WKWebView 有额外的3个:trackingNumber、flightNumber、lookupSuggestion。数组或字符串

allowsInlineMediaPlayback:
[iOS]内部播放还是全屏播放,默认:false

userAgent:
[Android]

thirdPartyCookiesEnabled:
[Android]是否启用第三方 cookie,默认:true
    
mixedContentMode:
[Android]WebView 是否应该允许安全链接(https)页面中加载非安全链接(http)的内容。never (默认) - 不允许、always - 允许、compatibility - 和浏览器一致

javaScriptEnabled:
[Android]是否启用 JavaScript。IOS 默认为启用 JavaScript
    
domStorageEnabled:
[Android]是否开启 DOM 本地存储
    
allowUniversalAccessFromFileURLs:
[Android]是否允许任何权限。默认:false
    
allowFileAccess:
[Android]是否可以访问文件系统。默认:false
    
geolocationEnabled:
[Android]是否可以访问位置。默认:false

方法

stopLoading():
  停止加载
    
reload():
  刷新
    
goBack():
  后一页
    
goForward():
  前一页
    
extraNativeComponentConfig():static
  1. FlatList 列表
import { FlatList } from 'react-native';

如果需要分组,请使用<SectionList>

  完全跨平台。
  支持水平布局模式。
  行组件显示或隐藏时可配置回调事件。
  支持自定义行间分隔线。
  支持单独的头部、尾部组件。
  支持上拉加载、下拉刷新。
  支持跳转到指定行(ScrollToIndex)

2个必要属性:
  data是列表的数据源,
  renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。

例1

<FlatList
  data={[{key: 'a'}, {key: 'b'}]}
  renderItem={({item}) => <Text>{item.key}</Text>}
/>

例2

<FlatList
  ItemSeparatorComponent={Platform.OS !== 'android' && ({highlighted}) => (
    <View style={[style.separator, highlighted && {marginLeft: 0}]} />
  )}
  data={[{title: 'Title Text', key: 'item1'}]}
  renderItem={({item, separators}) => (
    <TouchableHighlight
      onPress={() => this._onPress(item)}
      onShowUnderlay={separators.highlight}
      onHideUnderlay={separators.unhighlight}>
      <View style={{backgroundColor: 'white'}}>
        <Text>{item.title}</Text>
      </View>
    </TouchableHighlight>
  )}
/>

例3

import React, { Component } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';

export default class FlatListBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={[
            {key: 'Devin'},
            {key: 'Jackson'},
            {key: 'James'},
            {key: 'Joel'},
            {key: 'John'},
            {key: 'Jillian'},
            {key: 'Jimmy'},
            {key: 'Julie'},
          ]}
          renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})

属性

data
  目前只支持普通数组。
  如果需要使用其他特殊数据结构,例如 immutable 数组,请直接使用更底层的VirtualizedList

extraData
  除data以外的数据用在列表中(不论是用在renderItem还是头部或者尾部组件中)。
  同时此数据在修改时也需要先修改其引用地址(比如先复制到一个新的 Object 或者数组中),然后再修改其值,否则界面很可能不会刷新。

renderItem({ item: Object, index: number, separators: { highlight: Function, unhighlight: Function, updateProps: Function(select: string, newProps: Object) } }) => ?React.Element
  从data中挨个取出数据并渲染到列表中

ItemSeparatorComponent
  分隔线组件。不会出现在第一行之前和最后一行之后。
ListEmptyComponent
  列表为空时渲染该组件。component, function, element
ListHeaderComponent
  头部组件。component, function, element
ListFooterComponent
  尾部组件。component, function, element


initialNumToRender
  初始渲染的元素数量,最好刚刚够填满一个屏幕,这样保证了用最短的时间给用户呈现可见的内容。
  注意这第一批次渲染的元素不会在滑动过程中被卸载,这样是为了保证用户执行返回顶部的操作时,不需要重新渲染首批元素。

initialScrollIndex
  初始渲染的屏幕顶端元素下标。
  如果设置了这个属性,则第一批initialNumToRender范围内的元素不会再保留在内存里,而是直接立刻渲染位于 initialScrollIndex 位置的元素。
  需要先设置 getItemLayout 属性。


getItemLayout
  对于元素较多的列表(几百行)来说,添加getItemLayout可以极大地提高性能。注意如果你指定了ItemSeparatorComponent,请把分隔线的尺寸也考虑到 offset 的计算之中。
(data, index) => {length: number, offset: number, index: number}getItemLayout是一个可选的优化,用于避免动态测量内容尺寸的开销,不过前提是你可以提前知道内容的高度。如果你的行高是固定的,getItemLayout用起来就既高效又简单,类似下面这样:
  getItemLayout={(data, index) => (
    {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
  )}

keyExtractor
(item: object, index: number) => string;
  此函数用于为给定的 item 生成一个不重复的 key。Key 的作用是使 React 能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为 key 值。若item.key也不存在,则使用数组下标。

horizontal
  是否为水平布局模式

numColumns
  多列布局只能在非水平模式下使用,即必须是horizontal={false}。组件内元素必须是等高的——暂时还无法支持瀑布流布局。

columnWrapperStyle
  如果设置了多列布局(即将numColumns值设为大于 1 的整数),则可以额外指定此样式作用在每行容器上


onEndReachedThreshold
  滚动至底部当多远时触发onEndReached回调。
  注意此参数是一个比值而非像素单位。比如,0.5 表示距离内容最底部的距离为当前列表可见长度的一半时触发

onEndReached
  (info: {distanceFromEnd: number}) => void
  滚动至距离内容最底部不足onEndReachedThreshold的距离时调用。

onRefresh
  在列表头部添加一个标准的下拉刷新RefreshControl控件。同时你需要正确设置`refreshing`属性。

refreshing
  在等待加载新数据时设为 true,列表就会显示出一个正在加载的符号。

onViewableItemsChanged
(info: {
    viewableItems: array,
    changed: array,
  }) => void
在可见行元素变化时调用。可见范围和变化频率等参数的配置请设置viewabilityConfig属性

inverted
翻转滚动方向。实质是将 scale 变换设置为-1。



removeClippedSubviews
对于大列表启用本属性可能可以提高性能。
注意:有些情况下会有 bug(比如内容无法显示)。请谨慎使用。

viewabilityConfigCallbackPairs
当满足相应的ViewAbilityConfig条件时,将调用特定的OnViewableItemsChanged

viewabilityConfig
  minimumViewTime. 在激活可视性回调之前,项必须在物理上可查看的最短时间(毫秒)。高数字意味着不停止滚动浏览内容不会将内容标记为可查看。
  viewAreaCoveragePercentThreshold (必要或有itemVi...) 必须被部分遮挡项目覆盖的视区百分比,计为“可视”,0-100。完全可见的项目总是被认为是可视的。值为0表示视区中的单个像素使项目可见,值为100表示项目必须完全可见或覆盖整个视区才能算为可见。
  itemVisiblePercentThreshold(必要或有viewAr...). 与ViewAreaPercentThreshold类似,但考虑的是可见项的百分比,而不是它所覆盖的可视区域的分数。
  waitForInteraction   在用户滚动或在呈现后调用RecordInteraction之前,不认为任何内容都是可见的。
  

legacyImplementation
  没有完整的功能奇偶校验,用于调试和性能比较

progressViewOffset
  [Android] 在指定的偏移处显示加载指示器。

方法

scrollToEnd([params]);
  滚动到底部。
  如果不设置getItemLayout属性的话,可能会比较卡。
  参数(对象):是否动画 animated(Defaults to true)

scrollToIndex(params);
  如果不设置getItemLayout属性的话,无法跳转到当前渲染区域以外的位置。
  参数(对象):
    index(必要)
    viewOffset(必要)
    viewPosition(0顶部、0.5中部、1底部)
    animated(Defaults to true)

scrollToItem(params);
  如果不设置getItemLayout属性的话,无法跳转到当前渲染区域以外的位置。
  参数(对象):
    item(必要)
    animated(Defaults to true)
    viewPosition

scrollToOffset(params);
  滚动列表到指定的偏移(以像素为单位),等同于ScrollView的scrollTo方法
  参数(对象):
    offset(必要,horizontal为true则x,否则y)
    animated(Defaults to true)

recordInteraction();
  主动通知列表发生了一个事件,以使列表重新计算可视区域。比如说当waitForInteractions为 true 并且用户没有滚动列表时。一般在用户点击了列表项或发生了导航动作时调用

flashScrollIndicators();
  短暂地显示滚动指示器
  1. SectionList 分组列表视图
import { SectionList } from 'react-native';

例1

import React, { Component } from 'react';
import { SectionList, StyleSheet, Text, View } from 'react-native';

export default class SectionListBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <SectionList
          sections={[
            {title: 'D', data: ['Devin']},
            {title: 'J', data: ['Jackson', 'James', 'Jillian', 'Jimmy', 'Joel', 'John', 'Julie']},
          ]}
          renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
          renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
          keyExtractor={(item, index) => index}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  sectionHeader: {
    paddingTop: 2,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 2,
    fontSize: 14,
    fontWeight: 'bold',
    backgroundColor: 'rgba(247,247,247,1.0)',
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})
  完全跨平台。
  行组件显示或隐藏时可配置回调事件。
  支持单独的头部、尾部组件。
  支持自定义行间分隔线。
  支持分组的头部组件。
  支持分组的分隔线。
  支持多种数据源结构
  支持上拉加载、下拉刷新。

本组件实质是基于VirtualizedList组件的封装。此外还有下面这些需要注意的事项:
  当某行滑出渲染区域之外后,其内部状态将不会保留。请确保你在行组件以外的地方保留了数据。
  本组件继承自PureComponent而非通常的Component,这意味着如果其props在浅比较中是相等的,则不会重新渲染。所以请先检查你的renderItem函数所依赖的props数据(包括data属性以及可能用到的父组件的state),如果是一个引用类型(Object或者数组都是引用类型),则需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。
  为了优化内存占用同时保持滑动的流畅,列表内容会在屏幕外异步绘制。这意味着如果用户滑动的速度超过渲染的速度,则会先看到空白的内容。这是为了优化不得不作出的妥协,而我们也在设法持续改进。
  默认情况下每行都需要提供一个不重复的key属性。你也可以提供一个keyExtractor函数来生成key。

属性

sections
  数据(必要)

initialNumToRender
  初始渲染的元素数量,最好刚刚够填满一个屏幕,这样保证了用最短的时间给用户呈现可见的内容。注意这第一批次渲染的元素不会在滑动过程中被卸载,这样是为了保证用户执行返回顶部的操作时,不需要重新渲染首批元素。

stickySectionHeadersEnabled
  组头视图是否悬停

keyExtractor
  此函数用于为给定的item生成一个不重复的key。Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。注意这只设置了每行(item)的key,对于每个组(section)仍然需要另外设置key
(item: Item, index: number) => string

renderItem
  用来渲染每一个section中的每一个列表项的默认渲染器。可以在section级别上进行覆盖重写。必须返回一个react组件。
  item
  index
  section
  separators
    highlight
    unhighlight
    updateProps
      select
      newProps

onEndReachedThreshold
  决定当距离内容最底部还有多远时触发onEndReached回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发

onEndReached
  当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用
(info: {distanceFromEnd: number}) => void

extraData
  如果有除data以外的数据用在列表中(不论是用在renderItem还是Header或者Footer中),请在此属性中指定。同时此数据在修改时也需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。

temSeparatorComponent
  行与行之间的分隔线组件。不会出现在第一行之前和最后一行之后
  component, function, element

ListHeaderComponent
  头部组件。component, function, element
ListFooterComponent
  尾部组件。component, function, element

renderSectionFooter
  每个组的尾部组件(info: {section: SectionT}) => ?React.Element

renderSectionHeader
  在每个section的头部渲染。在iOS上,这些headers是默认粘接在ScrollView的顶部的(info: {section: SectionT}) => ?React.Element

ListEmptyComponent
  当列表数据为空时渲染的组件 component, function, element

onRefresh
  在列表头部添加一个标准的RefreshControl控件,以便实现“下拉刷新”的功能。同时你需要正确设置`refreshing`属性。

onViewableItemsChanged
  在可见行元素变化时调用。可见范围和变化频率等参数的配置请设置viewabilityConfig属性。
    viewableItems
    changed

refreshing
  在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号

inverted
  是否翻转滚动方向。实质是将scale变换设置为-1

SectionSeparatorComponent
  在每个section的顶部和底部渲染(区别于ItemSeparatorComponent,它仅在列表项之间渲染)。它的作用是为了从视觉上把section与它上方或下方的headers区别开来,从这个意义上讲,它的作用和ItemSeparatorComponent是一样的. 它也接受highlighted, [leading/trailing][Item/Separator]这两个默认提供的属性或其他通过separators.updateProps添加的自定义属性

legacyImplementation

removeClippedSubviews

方法

flashScrollIndicators();
  短暂地显示滚动指示器

recordInteraction();
  主动通知列表发生了一个事件,以使列表重新计算可视区域。比如说当waitForInteractions 为 true 并且用户没有滚动列表时,就可以调用这个方法。不过一般来说,当用户点击了一个列表项,或发生了一个导航动作时,我们就可以调用这个方法。

scrollToLocation(params);
  将可视区内位于特定sectionIndex 或 itemIndex (section内)位置的列表项,滚动到可视区的制定位置。比如说,viewPosition 为0时将这个列表项滚动到可视区顶部 (可能会被顶部粘接的header覆盖), 为1时将它滚动到可视区底部, 为0.5时将它滚动到可视区中央。
  注意: 如果没有设置getItemLayout或是onScrollToIndexFailed,就不能滚动到位于外部渲染区的位置。
  参数(对象):
    animated(Defaults to true)
    itemIndex(必要)
    sectionIndex(必要)
    viewOffset
    viewPosition(0顶部1底部)
上一篇下一篇

猜你喜欢

热点阅读