2017-02-17 11 views
6

मैंने एक ग्रिडव्यू बनाया है, जो सर्वर से वीडियो दिखाता है। ग्रिडइटम में वीडियो अंगूठे की छवि और वीडियो अवधि है। वीडियो के अंगूठे को लोड करने के लिए मैं यूनिवर्सल इमेजलोडर का उपयोग कर रहा हूं और एसिंकैक्ट का उपयोग करके आलसी लोडिंग बनाकर वीडियो अवधि लोड कर रहा हूं। लाज़ीलोडिंग ठीक काम करती है। लेकिन अगर कोई ग्रिडव्यू को अक्सर स्क्रॉल करता है, तो वीडियो अवधि गलत स्थिति में दिखाई देती है। मैं अनुसरण कर रहा हूं Lazyloading बनाने के लिए bellow linkटेक्स्टव्यू Lazyloading, ग्रिडव्यू में गलत स्थिति पर setText?

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

ग्रिड व्यू प्रतिपादन के लिए कोड पोस्ट करें, डेटा बाध्यकारी और आलसी लोडिंग सामग्री? –

+0

@AnuragSingh क्या आप कार्यान्वयन देख सकते हैं? –

+0

नीचे दिए गए अनुसार नीचे दिए गए परिवर्तन करें। –

उत्तर

3

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: मैं इस समस्या पता लगा है। गलत ग्रिडव्यू स्थिति पर वीडियो अवधि को lazyloading अद्यतन क्यों करें। त्यागें ऊपर अगर आप चाहते हैं

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

दोषी है। downloadDuration एसिंक मोड में चलता है और इसमें पहले से durationTextView का संदर्भ है। मान लीजिए downloadDuration समाप्त नहीं हुआ है और उपयोगकर्ता ListView स्क्रॉल करता है। ListViewdownloadDuration स्क्रॉल करने के बाद, यह durationTextView मूल्य के साथ अपडेट किया जाएगा लेकिन गलत ListView आइटम स्थिति के लिए और यह नहीं कि किस स्थिति के लिए यह downloadDuration में पारित किया गया था। final TextView durationTextView; इसे अंतिम रूप में बनाना समस्या को हल नहीं करेगा। समाधान अवधि के लिए कुछ प्रकार के खाली संकेतक दिखाने के लिए किया जा सकता है और downloadDuration इसे एसिंक नौकरी खत्म करने दें। पैरामीटर के रूप में durationTextView हटाएं और पैरामीटर के रूप में position जोड़ें। Async नौकरी के बाद, आप उस स्थिति के लिए MediaItemBean प्रकार की बीन सूची अपडेट कर सकते हैं। अब एडाप्टर को सूचित करें कि कुछ मान बदल दिया गया है और ListView तदनुसार अपडेट हो जाएगा। FYIRecyclerView आइटम अपडेट ListView से अधिक अनुकूलित है।

अपडेट 2: आप आइटम को पहले से ही ला सकते हैं और इसे बीन पर मैप कर सकते हैं। केवल एक बार async चलाएगा।

अद्यतन 3: इस बीच आपआइटम के लिए बीन की जांच कर सकते हैं यदि यह 0 है या नहीं। यदि यह durationTextView.setText("00:00:00") में 0 शो है तो downloadDuration पर कॉल करें और इसे बीन में अवधि मान को समाप्त और अपडेट करने दें। लेकिन अभी भी आइटम को अपडेट करने के लिए आपको notify की आवश्यकता है।

+0

मैंने पहले ही यह कोशिश की है, मुझे लगता है कि यह समाधान नहीं है –

+0

यदि आपको (स्थिति> = mCameraMediaItems.size()) { Log.d (TAG) से छुटकारा पाना होगा , "बाउंड से बाहर सूचकांक, स्थिति:" + स्थिति + "- mCameraMediaItems.size():" + mCameraMediaItems.size()); वापसी कन्वर्ट व्यू; } भी। क्योंकि यदि आपने ऊपर के रूप में लागू किया है तो बाउंड से बाहर सूचकांक, स्थिति नहीं हो सकती है। –

+0

ठीक है, मैं वही कर रहा हूं –

संबंधित मुद्दे