更改数据集时使用 ListView 和 TextureView "blinks" 的全屏视频源
Fullscreen video feed with ListView and TextureView "blinks" when dataset is changed
我正在尝试在 Android 上创建全屏视频源。
我决定使用 ListView
,每个项目都是 TextureView
。因为它是全屏的,所以在给定的时刻,我们总是只显示一个项目。
当 TextureView
可用时,我创建一个 MediaPlayer
并在 Surface 上播放视频。效果很好。
当我到达列表底部时,我从服务器加载更多数据。加载新数据后,我调用 BaseAdapter
的 notifyDataSetChanged()
并为每个可见项重新创建视图。
问题是它使当前视频"blink"(重新创建视图时,视频消失然后重新出现)。
我真的不知道如何解决这个问题:ListView
总是在数据集更改时重新创建项目视图。
我觉得在这里使用 ListView
是正确的解决方案,因为我显示了视频项目列表,但也许我走错了路...
- 如何停止这种闪烁? (有没有办法告诉
ListView
不要重新创建当前项目的视图?)
- 我应该使用
ListView
以外的东西吗?如果是,我应该看什么?
谢谢。
你应该使用View Holder pattern。在您的情况下,将当前显示的视频的 id 添加到 holder,如果它已经在显示视频,这将允许您 tu return convertView 不变。
这是一个展示想法的(未经测试的)代码示例:
public View getView (int position, View convertView, ViewGroup parent) {
Holder holder;
if(convertView != null) {
holder = (Holder) convertView.getTag();
if(holder.displayedContent == getContentToDisplay(position)) {
// the view we were asked to convert is already displaying
// the good video, no need to change anything to it !
return convertView;
} else {
// convert the view by displaying the new video
}
} else {
// create a new view !
}
}
private static class Holder {
int displayedContent;
// + references to the views
}
我正在尝试在 Android 上创建全屏视频源。
我决定使用 ListView
,每个项目都是 TextureView
。因为它是全屏的,所以在给定的时刻,我们总是只显示一个项目。
当 TextureView
可用时,我创建一个 MediaPlayer
并在 Surface 上播放视频。效果很好。
当我到达列表底部时,我从服务器加载更多数据。加载新数据后,我调用 BaseAdapter
的 notifyDataSetChanged()
并为每个可见项重新创建视图。
问题是它使当前视频"blink"(重新创建视图时,视频消失然后重新出现)。
我真的不知道如何解决这个问题:ListView
总是在数据集更改时重新创建项目视图。
我觉得在这里使用 ListView
是正确的解决方案,因为我显示了视频项目列表,但也许我走错了路...
- 如何停止这种闪烁? (有没有办法告诉
ListView
不要重新创建当前项目的视图?) - 我应该使用
ListView
以外的东西吗?如果是,我应该看什么?
谢谢。
你应该使用View Holder pattern。在您的情况下,将当前显示的视频的 id 添加到 holder,如果它已经在显示视频,这将允许您 tu return convertView 不变。
这是一个展示想法的(未经测试的)代码示例:
public View getView (int position, View convertView, ViewGroup parent) {
Holder holder;
if(convertView != null) {
holder = (Holder) convertView.getTag();
if(holder.displayedContent == getContentToDisplay(position)) {
// the view we were asked to convert is already displaying
// the good video, no need to change anything to it !
return convertView;
} else {
// convert the view by displaying the new video
}
} else {
// create a new view !
}
}
private static class Holder {
int displayedContent;
// + references to the views
}