gpt4 book ai didi

android - Textview 延迟加载,setText 在 gridview 中的错误位置?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:08:13 24 4
gpt4 key购买 nike

我创建了一个 gridview,它显示来自服务器的视频。 GridItem 有视频缩略图和视频持续时间。为了加载视频的缩略图,我正在使用 UniversalImageloader 并通过使用 asynctask 创建延迟加载来加载视频持续时间。延迟加载工作正常。但如果有人频繁滚动 gridview,则视频持续时间显示在错误的位置。为了创建延迟加载,我在下面关注 link

@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);
}
}

最佳答案

摆脱 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 ");
}

现在使用 mediaItemViewHolder.durationTextView.setText(....)

更新 1: 我已经找到问题所在了。 为什么延迟加载会在错误的 gridview 位置更新视频持续时间如果需要,请丢弃以上内容

downloadDuration(resId, durationTextView, mediaItemViewHolder.highlightTagIcon, mediaItemBean);

是罪魁祸首。 downloadDuration 以异步模式运行,并且它事先有 durationTextView 的引用。假设 downloadDuration 未完成并且用户滚动 ListView。滚动 ListView downloadDuration 完成后,此 durationTextView 将更新为错误的 ListView 值项目位置,而不是这是在 downloadDuration 中传递的位置。制作 final TextView durationTextView;
final 也解决不了问题。解决方案可能是显示某种持续时间的空指示器,并让 downloadDuration 完成它的异步作业。删除 durationTextView 作为参数并添加 position 作为参数。异步作业完成后,您可以为该位置更新 MediaItemBean 类型的 bean 列表。现在通知适配器某些值已更改,ListView 将相应地更新自身。 仅供引用 RecyclerView 项目更新比 ListView 更优化。

更新 2:您可以提前获取项目并将其映射到 bean。只会运行一次异步。

更新 3:与此同时,您可以检查特定 ListView 项的 bean 是否为 0。如果在 durationTextView.setText("00:00:00") 中显示为 0,则调用 downloadDuration 并让它完成并更新 bean 中的持续时间值。但是您仍然需要通知更新项目。

关于android - Textview 延迟加载,setText 在 gridview 中的错误位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42297658/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com