San*_*ari 6 android lazy-loading
我创建了一个gridview,它显示来自服务器的视频.GridItem有视频拇指图像和视频持续时间.用于加载视频的拇指我使用UniversalImageloader并通过使用asynctask.Lazyloading创建延迟加载来加载视频持续时间.但如果有人自由地滚动网格视图,则视频持续时间显示在错误的位置.用于创建Lazyloading我正在关注下面的链接
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final TextView durationTextView;
View view = null;
if (convertView == null) {
view = mInflater.inflate(R.layout.camera_roll_item, parent, false);
MediaItemViewHolder mediaItemViewHolder = new MediaItemViewHolder();
mediaItemViewHolder.highlightTagIcon = (ImageView) view.findViewById(R.id.iv_media_grid_item_highlight_tag);
mediaItemViewHolder.mediaTypeIcon = (ImageView) view.findViewById(R.id.iv_media_grid_item_type);
mediaItemViewHolder.mediaClipLength = (TextView) view.findViewById(R.id.tv_media_grid_item_length);
mediaItemViewHolder.mediaThumbnail = (ImageView) view.findViewById(R.id.iv_media_grid_item_thumbnail);
mediaItemViewHolder.cameraItemSelectedView = (RelativeLayout) view.findViewById(R.id.rl_item_selection_parent);
mediaItemViewHolder.progressContainer = (RelativeLayout) view.findViewById(R.id.rl_grid_loader_parent);
view.setTag(mediaItemViewHolder);
} else {
view = convertView;//(MediaItemViewHolder) convertView.getTag();
//mediaItemViewHolder.mediaClipLength.setText("");
Log.i(TAG, "set blank to ");
}
MediaItemViewHolder mediaItemViewHolder = (MediaItemViewHolder) convertView.getTag();
durationTextView = mediaItemViewHolder.mediaClipLength;
if (position >= mCameraMediaItems.size()) {
Log.d(TAG, "Index out of Bound, position:" + position + " - mCameraMediaItems.size():" + mCameraMediaItems.size());
return convertView;
}
MediaItemBean mediaItemBean = CameraMediaController.getInstance().getMediaItemByPosition(position);
mediaItemViewHolder.mediaClipLength.setVisibility(View.VISIBLE);
mediaItemViewHolder.highlightTagIcon.setVisibility(View.GONE);
if (mediaItemBean != null && mediaItemBean.getCameraMedia() != null) {
switch (mediaItemBean.getCameraMedia().getType()) {
case AppConstant.MEDIA_TYPE_VIDEO:
mediaItemViewHolder.mediaTypeIcon.setImageResource(R.drawable.icn_thumb_vid);
//VideoInfoAsyncTask loads data in this list
int videoDuration = mediaItemBean.getVideoDuration();
//mediaItemViewHolder.mediaClipLength.setTag(CameraMediaUtil.convertSecondsTimeToMinutesString(videoDuration));
Log.i(TAG, "VideoDuration " + videoDuration);
String resId = mediaItemBean.getCreatedId()+"video_media_duration_com.gopro.buckhorn";
Log.i(TAG, "RESID "+resId);
downloadDuration(resId, durationTextView, mediaItemViewHolder.highlightTagIcon, mediaItemBean);
break;
case MULTI_PHOTO:
String mulCount = String.valueOf(Controller.getInstance().getPhotoCountAtPosition(position));
Log.i("MULTI_SHOT_SECTION", "MultiShot "+mulCount);
mediaItemViewHolder.mediaTypeIcon.setImageResource(R.drawable.icn_thumb_burst);
mediaItemViewHolder.mediaClipLength.setText(mulCount);
break;
}
//Load image into image view from URL
String imageUri = mediaItemBean.getThumbnailUri().toString();
Log.i(TAG, "Thumb url :" + imageUri);
mediaItemViewHolder.progressContainer.setVisibility(View.VISIBLE);
DownloadImageUtil.getLoadImageInsatnce().downloadGridImage(imageUri,
mediaItemViewHolder.mediaThumbnail, R.drawable.thumb_load, mediaItemViewHolder.progressContainer);
}
return convertView;
}
private void downloadDuration(String resId, TextView textView, ImageView highlightTagIcon, MediaItemBean mediaItemBean) {
String duration = getVideoDurationFromCache(String.valueOf(resId));
Log.i(TAG, "downloadDuration " + duration);
if (duration == null) {
loadVideoDuration(resId, textView, highlightTagIcon, mediaItemBean);
textView.setText("");
} else {
cancelVideoDurationDownloaderTask(resId, textView);
if(mediaItemBean.getCameraMedia().getType() == AppConstant.MEDIA_TYPE_VIDEO){
textView.setText(duration);
if (mediaItemBean.isIsHighLightTags()) {
highlightTagIcon.setVisibility(View.VISIBLE);
}
}
}
}
private String getVideoDurationFromCache(String key) {
// First try the hard reference cache
synchronized (mMemoryCache) {
final String duration = mMemoryCache.get(key);
if (duration != null) {
// Bitmap found in hard cache
// Move element to first position, so that it is removed last
mMemoryCache.remove(key);
mMemoryCache.put(key, duration);
return duration;
}
}
return null;
}
private static class MediaItemViewHolder {
ImageView highlightTagIcon, mediaTypeIcon, mediaThumbnail;
TextView mediaClipLength;
RelativeLayout cameraItemSelectedView;
/* ProgressBar innerProgressBar;
ProgressBar outerProgressBar;*/
RelativeLayout progressContainer;
}
public class VideoDurationDownloaderTask extends AsyncTask<String, Void, String> {
private final WeakReference<TextView> videoDurationReference;
private final WeakReference<ImageView> hiliteTagImageViewWeakReference;
private String data = "";
private MediaItemBean mediaItemBean;
public VideoDurationDownloaderTask(TextView textView, ImageView hiliteTagIcon, MediaItemBean mediaItemBean) {
this.mediaItemBean = mediaItemBean;
videoDurationReference = new WeakReference<>(textView);
hiliteTagImageViewWeakReference = new WeakReference<>(hiliteTagIcon);
}
@Override
protected String doInBackground(String... params) {
data = params[0];
Log.i(TAG, "data in task "+data);
return downloadVideoDuration(mediaItemBean);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (isCancelled()) {
Log.i(TAG, "isCancelled " + result);
result = "";
}
addDurationToMemoryCache(data, result);
//noinspection ConstantConditions
if (videoDurationReference != null) {
TextView videoDuration = videoDurationReference.get();
Log.i(TAG, "videoDuration " + videoDuration);
VideoDurationDownloaderTask videoDurationDownloaderTask =
getTextViewDerationWorkerTask(videoDuration);
Log.i(TAG, "videoDurationDownloaderTask " + videoDurationDownloaderTask);
if (videoDuration != null) {
if (this == videoDurationDownloaderTask) {
if(mediaItemBean.getCameraMedia().getType() == AppConstant.MEDIA_TYPE_VIDEO) {
Log.i(TAG, "TAG VAL "+videoDuration.getTag());
videoDuration.setText(result);
videoDuration.setTag(new TextView(context));
if (mediaItemBean.isIsHighLightTags()) {
ImageView highlightTagIcon = hiliteTagImageViewWeakReference.get();
if (highlightTagIcon != null)
highlightTagIcon.setVisibility(View.VISIBLE);
}
}
}
}
}
}
}
private String downloadVideoDuration(MediaItemBean mediaItemBean) {
try {
if (media != null && mediaItemBean.getMedia() != null) {
int videoDuration = mediaItemBean.getVideoDuration();
Log.i(TAG, "Video has duration = " + videoDuration);
if (videoDuration == -1) {
CommandResult<Integer> duration =
media.getVideoDuration(mediaItemBean.getCameraMedia().getFilePath());
videoDuration = duration.getData();
mediaItemBean.setVideoDuration(videoDuration);
Log.i(TAG, "set Video Duration " + videoDuration);
}
return MediaUtil.convertSecondsTimeToMinutesString(videoDuration);
}
} catch (Exception e) {
Log.e(TAG, "Exception Occure while Getting video info:" + e.getMessage());
}
Log.i(TAG, "not fetch duration ");
return "";
}
public void loadVideoDuration(String resId, TextView textView, ImageView hiliteTagIcon, MediaItemBean mediaItemBean) {
if (cancelVideoDurationDownloaderTask(resId, textView)) {
final VideoDurationDownloaderTask task = new VideoDurationDownloaderTask(textView, hiliteTagIcon, mediaItemBean);
AsyncTextView asyncTextView = new AsyncTextView(context, task);
textView.setTag(asyncTextView);
task.execute(resId);
}
}
private boolean cancelVideoDurationDownloaderTask(String data, TextView textView) {
final VideoDurationDownloaderTask durationWorkerTask = getTextViewDerationWorkerTask(textView);
if (durationWorkerTask != null) {
final String textViewData = durationWorkerTask.data;
Log.i(TAG, textViewData + " textViewDataData, data " + data);
if (data != null && !textViewData.equalsIgnoreCase(data)) {
// Cancel previous task
Log.i(TAG, "Cancel previous task " + data);
durationWorkerTask.cancel(true);
} else {
// The same work is already in progress
Log.i(TAG, "same work is already in progress " + false);
return false;
}
}
// No task associated with the ImageView, or an existing task was
// cancelled
Log.i(TAG, "cancelVideoDurationDownloaderTask true");
return true;
}
static class AsyncTextView extends TextView {
private final WeakReference<VideoDurationDownloaderTask> textviewWorkerTaskReference;
public AsyncTextView(Context context, VideoDurationDownloaderTask textviewWorkerTask) {
super(context);
textviewWorkerTaskReference = new WeakReference<>(textviewWorkerTask);
}
public VideoDurationDownloaderTask getTextViewWorkerTask() {
return textviewWorkerTaskReference.get();
}
}
private static VideoDurationDownloaderTask getTextViewDerationWorkerTask(TextView textView) {
if(textView.getTag() != null){
Log.i(TAG, " textView.getTag() " + textView.getTag());
if (textView.getTag() instanceof AsyncTextView) {
Log.i(TAG, " Return Textview task");
final AsyncTextView asyncTextView = (AsyncTextView) textView.getTag();
return asyncTextView.getTextViewWorkerTask();
}
}
return null;
}
public void addDurationToMemoryCache(String key, String duration) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, duration);
}
}
Run Code Online (Sandbox Code Playgroud)
删除并按从方法中收到的方式view使用。convertView更改为以下内容
//final is optional but if you need to use in thread
final MediaItemViewHolder mediaItemViewHolder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.camera_roll_item, parent, false);
mediaItemViewHolder = new MediaItemViewHolder();
mediaItemViewHolder.highlightTagIcon = (ImageView) convertView.findViewById(R.id.iv_media_grid_item_highlight_tag);
mediaItemViewHolder.mediaTypeIcon = (ImageView) convertView.findViewById(R.id.iv_media_grid_item_type);
mediaItemViewHolder.mediaClipLength = (TextView) convertView.findViewById(R.id.tv_media_grid_item_length);
mediaItemViewHolder.mediaThumbnail = (ImageView) convertView.findViewById(R.id.iv_media_grid_item_thumbnail);
mediaItemViewHolder.cameraItemSelectedView = (RelativeLayout) convertView.findViewById(R.id.rl_item_selection_parent);
mediaItemViewHolder.progressContainer = (RelativeLayout) convertView.findViewById(R.id.rl_grid_loader_parent);
convertView.setTag(mediaItemViewHolder);
} else {
mediaItemViewHolder = (MediaItemViewHolder)convertView.getTag();
Log.i(TAG, "set blank to ");
}
Run Code Online (Sandbox Code Playgroud)
现在使用mediaItemViewHolder.durationTextView.setText(....)
更新1:我已经解决了这个问题。为什么延迟加载会在错误的 gridview 位置更新视频持续时间。如果您愿意,请丢弃以上内容
downloadDuration(resId, durationTextView, mediaItemViewHolder.highlightTagIcon, mediaItemBean);
Run Code Online (Sandbox Code Playgroud)
是罪魁祸首。以异步模式运行,并且它预先downloadDuration具有 in 的引用。durationTextView假设downloadDuration尚未完成并且用户滚动了ListView。滚动ListView downloadDuration完成后,durationTextView将使用该值进行更新,但项目位置错误ListView,而不是传入的位置downloadDuration。将其定final TextView durationTextView;
为最终版本也不能解决问题。解决方案可能是显示某种持续时间的空指示器,并让downloadDuration异步作业完成。durationTextView作为参数删除并position作为参数添加。异步作业完成后,您可以更新MediaItemBean该位置的类型的 bean 列表。现在通知适配器某些值已更改,并且适配器ListView将相应地更新自身。仅供 RecyclerView参考,项目更新比ListView.
更新2:您可以提前获取项目并将其映射到bean。异步只会运行一次。
更新 3:同时,您可以检查特定ListView项目的 bean 是否为 0。如果是 0,则在durationTextView.setText("00:00:00")else 调用中显示downloadDuration并让它完成并更新 bean 中的持续时间值。但您仍然需要notify更新项目。
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |