How to use AsyncTask inside instantiateItem method of PagerAdapter

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I wanted to use ViewPager to display some encrypted images. For that I created an extension of PagerAdapter and put my decryption code inside instantiateItem method. But the problem is that the process of decryption takes too long. So, I used AsyncTask inside instantiateItem method to show a progress dialog.

Now, ViewPager displays a blank screen at first and I should swipe to view the first image. Moreover setCurrentItem() does not work.

My Code:

public class FullScreenImageAdapter extends PagerAdapter {      private Activity _activity;     private ArrayList<String> _imagePaths;     private LayoutInflater inflater;     ImageView imgDisplay;      // constructor     public FullScreenImageAdapter(Activity activity,             ArrayList<String> imagePaths) {         this._activity = activity;         this._imagePaths = imagePaths;     }      @Override     public int getCount() {         return this._imagePaths.size();     }      @Override     public boolean isViewFromObject(View view, Object object) {         return view == ((RelativeLayout) object);     }      @Override     public Object instantiateItem(ViewGroup container, int position) {         inflater = (LayoutInflater) _activity                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);         View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,                 false);          imgDisplay = (ImageView) viewLayout.findViewById(R.id.img_axew);          new DisplayFile().execute(_imagePaths.get(position));          ((ViewPager) container).addView(viewLayout);          return viewLayout;     }      private class DisplayFile extends AsyncTask<String, Integer, Integer> {          ProgressDialog progress;         String path;         Bitmap bitmap;          @Override         protected Integer doInBackground(String... arg0) {             path = arg0[0];              File file = new File(path);             try {                 bitmap = AxerProcessor.getBitmapFromByte(AxerProcessor.decryptBytes(AxewActivity.password, AxerProcessor.decompressBytes(AxerProcessor.getFileBytes(file))));             } catch (Exception e) {                 Toast.makeText(_activity, _activity.getString(R.string.error_wrong_password).replace("%s", file.getName()), Toast.LENGTH_LONG).show();             }              return null;         }          @Override         protected void onPreExecute() {             progress = ProgressDialog.show(_activity, _activity.getString(R.string.alert_decrypt_progress),                      _activity.getString(R.string.alert_decrypt_progress_msg), false);         }          @Override         protected void onPostExecute(Integer result) {             progress.dismiss();             imgDisplay.setImageBitmap(bitmap);         }      }      @Override     public void destroyItem(ViewGroup container, int position, Object object) {         ((ViewPager) container).removeView((RelativeLayout) object);      } } 

回答1:

I think you are missing a call to PagerAdapter.notifyDataSetChanged() - http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#notifyDataSetChanged()

You can call notifyDataSetChanged():

  • Right after your call to .addView() [in which case you have a blank screen at first], or
  • You can move more code (inflate view, addView) into onPostExecute so that nothing happens until the image is fully ready to be rendered.


回答2:

Thanks to @rtsai2000, I finally used get() method of AsyncTask to return the true result. The solution was to wait for the result (viewLayout). So my codes changed to:

public class FullScreenImageAdapter extends PagerAdapter {      private Activity _activity;     private ArrayList<String> _imagePaths;     private LayoutInflater inflater;     ImageView imgDisplay;     View viewLayout;     private ViewGroup container;      // constructor     public FullScreenImageAdapter(Activity activity,             ArrayList<String> imagePaths) {         this._activity = activity;         this._imagePaths = imagePaths;     }      @Override     public int getCount() {         return this._imagePaths.size();     }      @Override     public boolean isViewFromObject(View view, Object object) {         return view == ((RelativeLayout) object);     }      @Override     public Object instantiateItem(ViewGroup container, int position) {         this.container = container;          DisplayFile df = new DisplayFile();         df.execute(_imagePaths.get(position));          View result = null;          try {             result = df.get();         } catch (InterruptedException e) {         } catch (ExecutionException e) {         }          return result;     }      private class DisplayFile extends AsyncTask<String, View, View> {          ProgressDialog progress;         String path;         Bitmap bitmap;          @Override         protected View doInBackground(String... arg0) {             path = arg0[0];              File file = new File(path);             try {                 bitmap = AxerProcessor.getBitmapFromByte(AxerProcessor.decryptBytes(AxewActivity.password, AxerProcessor.decompressBytes(AxerProcessor.getFileBytes(file))));             } catch (Exception e) {                 Toast.makeText(_activity, _activity.getString(R.string.error_wrong_password).replace("%s", file.getName()), Toast.LENGTH_LONG).show();             }              return viewLayout;         }          @Override         protected void onPreExecute() {             progress = ProgressDialog.show(_activity, _activity.getString(R.string.alert_decrypt_progress),                      _activity.getString(R.string.alert_decrypt_progress_msg), false);              inflater = (LayoutInflater) _activity                     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);             viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,                     false);         }          @Override         protected void onPostExecute(View result) {             progress.dismiss();              imgDisplay = (ImageView) result.findViewById(R.id.img_axew);              imgDisplay.setImageBitmap(bitmap);             ((ViewPager) container).addView(result);         }      }      @Override     public void destroyItem(ViewGroup container, int position, Object object) {         ((ViewPager) container).removeView((RelativeLayout) object);      } } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!