关键点:
list-visibility-utils module是独立的,其他项目也可以直接使用。
1、ItemsPositionGetter,只需要listview或者recyclerview就能根据position获取view、 根据view获取获取position,获取firstposition和lastposition。
2、获取View可见百分百,只要知道View对象即可,View.getLocalVisibleRect(Rect rect)。
3、设置listview或者recyclerview的OnScrollListener,根据ItemsPositionGetter可以知道滚动方向。
4、ListItemsVisibilityCalculator是一个关键类,封装了对OnScrollListener的处理,只把最终激活的view通过接口回调出去onActiveViewChangedActive。
5、界面创建时是不会执行OnScrollListener的,所以在onCreate或者onResume中需要手动执行 ListItemsVisibilityCalculator.onScrollStateIdle(ItemsPositionGetter itemsPositionGetter, int firstVisiblePosition, int lastVisiblePosition)方法,获取MostVisibleItem。
6、滚动停止时获取最大百分百view:是根据滚动方向,向上滚动的时候假设最后一个可见view是最大的,然后遍历比较;向下滚动的时候假设第一个可见view是最大的,然后遍历。
7、滚动过程中获取最大百分百view:根据滚动方向,计算相邻view是否有效,如果有效并且当前最大百分百view的显示比例小于70%,就切换成相邻的。
8、ListItemData类保存了当前最大百分百的item的信息包括position和view,滚动的时候和停止滚动的时候都会更新。
9、所有的数据model都实现ListItem接口,获取item百分百、setActive、deactivate,item激活或者实效 各自model自己内部处理。
video-player-manager
1、android.util.Pair类,存储一对值的简单工具类
2、MediaPlayerWrapper对MediaPlayer的封装有对播放过程中的各种状态处理、自动回调时间处理VideoStateListener、播放过程中的各种回调MainThreadMediaPlayerListener start() pause() stop() reset() release() setVolume()
3、MessagesHandlerThread 消息队列,采用生产者消费者模式,并且加入ReentrantLock锁机制保护列。所有的消息都实现Message接口。这个设计很值得思考,所有的动作都封装成一个Message,丢到队列里面顺序执行。
4、ReadyForPlaybackIndicator类保存是否可以播放的状态,有三种状态
mVideoSize:MediaPlayer.onVideoSizeChanged获取的视频的大小
mSurfaceTextureAvailable:TextureView.onSurfaceTextureAvailable表示SurfaceTexture是否可用 mFailedToPrepareUiForPlayback:当MediaPlayer.onVideoSizeChanged回调的width和height都是0时是true,此时不能播放,只能wait()。
5、VideoPlayerView主要对MediaPlayerWrapper是调用,以及TextureView.SurfaceTextureListener、MediaPlayerWrapper.MainThreadMediaPlayerListener、MediaPlayerWrapper.VideoStateListener等回调事件的处理。
值得借鉴的地方:
1、播放、暂停等动作采用消息队列的机制。回调用new Handler(Looper.getMainLooper()) Runnable在主线程执行。
2、MessagesHandlerThread 消息队列的写法,尤其是锁机制。
3、都回调事件的二次包装,MediaPlayerWrapper.MainThreadMediaPlayerListener、VideoPlayerView.mLocalSurfaceTextureListener
4、ListView和RecyclerView公用ViewHolder,对数据的更新写在model里面。
附上视频相关的知识:
1、腾讯视频播放器TXCloudVideoView能不能播放本地视频 --不能。可以通过VideoPlayerManager-master中的VideoPlayerView播放,这个组件也可以播放网络视频,但是需要向客服申请。
2、录制和播放不是统一概念,录制时采集摄像头信息,播放是播放视频源,需要不同的组件。
一般录制用的是SurfaceView,播放用的是TextureView。播放当然也可以用SurfaceView,但是缺点很多,比如不可以缩放等。
录制采用SurfaceView的例子:趣拍、仿微信小视频录制https://github.com/szitguy/RecordVideoDemo、https://github.com/normalhh/WeChatVideoRecordDemo
录制采用TextureView的例子:https://github.com/GeorgeMe/Camera2Video
播放采用TextureView的例子:VideoPlayerManager-master、Android-ScalableVideoView-master
播放采用SurfaceView的例子:VideoView