【问题标题】:ImageAdapter extending BaseAdapter is not getting called after the Fragment is destroyed inside ViewPager在 ViewPager 中销毁 Fragment 后,不会调用扩展 BaseAdapter 的 ImageAdapter
【发布时间】:2016-07-13 06:58:26
【问题描述】:

FragmentPhotos:这是查看器中的片段,它本身位于活动查看器的片段中。情况是这样的:

我有一个活动,它有一个浏览器,在这个浏览器里面有 5 个片段。在第二个片段 (FRAGMENT_GALLERY) 内,我有另一个浏览器。在这个 VIEWPAGER 内部,我有一个名为 FRAGMENT_PHOTOS 的片段,在这个片段(FRAGMENT_PHOTOS)内部有一个网格视图,它仅在我第一次使用图像适配器打开应用程序时才会填充(图像适配器正在扩展 BASEADAPTER)。当我导航到下一个片段或上一个片段时,也会保持填充(显示图像)。但是,当我导航到其他一些片段(例如 #4 或 #5)并返回到此片段(片段照片)时,GridView 不会被填充或不显示图像(根据我的诊断,图像适配器不会再次被调用) )。它只被调用一次(当我们打开应用程序时)。请帮帮我...

  1. 当应用打开时,viewpager 的 Girdview 内部片段正常工作,并且 imageadapter 首次填充其中的图像。
  2. 现在,当我导航到下一个片段并返回到同一片段 (FragmentPhotos) 时,gridview 会正确显示图像..
  3. 但是当我导航到不同的片段(比如 #4 或 #5)时,FragmentPhotos 中的 gridview 不会显示图像。 根据我的诊断,图像适配器没有再次响应

    公共类 FragmentPhotos 扩展 Fragment {

    private GridView gridView;
    private Bitmap[] thumbnails;
    private ImageAdapter imageAdapter;
    private DisplayMetrics display;
    private ArrayList<String> imagesArrayList = new ArrayList<String>();
    private ArrayList<String> foldersArrayList = new ArrayList<String>();
    private View rootView;
    private final int REQUEST_CODE=1;
    private ImageView imgEnlarged;
    private GetImagesFromCard imagesFromCardTask;
    private Context context;
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_photos, container, false);
        initUI(rootView);
        return rootView;
    }
    
    public void initGallery()
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            requestPermissions(AppClass.INITIAL_PERMS, REQUEST_CODE);
        }
        else
        {
            if (imagesFromCardTask.getStatus().equals(AsyncTask.Status.RUNNING))
            {
    
            }
            else
            {
                imageAdapter = new ImageAdapter(context);
                gridView.setAdapter(imageAdapter);
                new GetImagesFromCard().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
        }
    }
    
    @Override
    public void onStart() {
        context = this.getActivity();
        imagesFromCardTask = new GetImagesFromCard();
        super.onStart();
    }
    
    public void disableGalleryTask()
    {
        if (imagesFromCardTask.getStatus()==GetImagesFromCard.Status.RUNNING)
        {
            imagesFromCardTask.cancel(true);
        }
    }
    
    private void initUI(View view) {
        display = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(display);
        gridView = (GridView) view.findViewById(R.id.gridGallery);
        imgEnlarged = (ImageView)view.findViewById(R.id.imgEnlarged);
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                showImageEnlarged(position);
            }
        });
        Log.e("","Gallery initialized");
    }
    
    private class GetImagesFromCard extends AsyncTask<Void,LoadedImage,Void>
    {
        Bitmap bitmap;
        ArrayList<LoadedImage> bitmapArrays=new ArrayList<LoadedImage>();
    
        @Override
        protected Void doInBackground(Void... params) {
            Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            String[] projection = {MediaStore.Images.Media.DATE_TAKEN,MediaStore.Images.Media._ID,MediaStore.Images.Thumbnails._ID,MediaStore.Images.Thumbnails.DATA,MediaStore.Images.Media.DATE_TAKEN};
            String orderBy = MediaStore.Images.Media.DATE_TAKEN + " DESC";
            Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, orderBy);
            int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
            int size = cursor.getCount();
            if (size==0)
            {
    
            }
            int imageId =0;
            int i=0;
            while (i<size && !isCancelled())
            {
                cursor.moveToPosition(i);
                imageId = cursor.getInt(columnIndex);
                uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + imageId);
                publishProgress(new LoadedImage(uri.toString()));
                if (i==0)
                {
                    showImageEnlarged(uri);
                }
                i++;
            }
            cursor.close();
            return null;
        }
    
        @Override
        protected void onProgressUpdate(LoadedImage... values) {
            super.onProgressUpdate(values);
            for (LoadedImage photo: values)
            {
                imageAdapter.addPhoto(photo);
                imageAdapter.notifyDataSetChanged();
                bitmapArrays.add(photo);
            }
        }
    
        @Override
        protected void onCancelled() {
            Log.e("","Task Cancelled");
            super.onCancelled();
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode)
        {
            case REQUEST_CODE:
            {
                for (int i=0;i<grantResults.length;i++)
                {
                    if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED)
                    {
                        Log.e("Permission Granted", permissions[i]);
                    }
                }
                new GetImagesFromCard().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                break;
            }
        }
    }
    

    }

以下是我的 ImageAdapter:

public class ImageAdapter extends BaseAdapter
{

    ImageLoader imageLoader;
    Context context;
    LayoutInflater inflater;
    private DisplayImageOptions options;
    ImageLoaderConfiguration config;
    ArrayList<LoadedImage> bitmapString;
    public ImageAdapter(Context context)
    {
        Log.e("","ImageAdapter called");
        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisc(true)
                .considerExifParams(true)
                .build();

        this.context = context;
        inflater = LayoutInflater.from(context);
        bitmapString = new ArrayList<LoadedImage>();

        config = new ImageLoaderConfiguration.Builder(context)
                .threadPriority(Thread.MAX_PRIORITY)
                .denyCacheImageMultipleSizesInMemory()
                .defaultDisplayImageOptions(options)
                .tasksProcessingOrder(QueueProcessingType.FIFO)
                .build();

    }

    public void addPhoto(LoadedImage photo)
    {
        bitmapString.add(photo);
    }

    public void clear()
    {
        bitmapString.clear();
    }

    public void remove(int index)
    {
        bitmapString.remove(index);
    }

    @Override
    public int getCount() {
        return bitmapString.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View view = convertView;
        final ViewHolder holder;
        if(convertView==null)
        {
            holder=new ViewHolder();
            view = inflater.inflate(R.layout.fragment_photos_grid_items,parent,false);
            holder.imageView = (ImageView)view.findViewById(R.id.imgGallery);
            holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            view.setTag(holder);
        }
        else
        {
            holder = (ViewHolder)view.getTag();
        }
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(config);
        imageLoader.displayImage(bitmapString.get(position).getImgString(),holder.imageView,options);
        return view;
    }

    class ViewHolder
    {
        ImageView imageView;
    }
}

以下是我的 ViewPager 适配器:

public class GalleryViewPagerAdapter extends FragmentStatePagerAdapter {
    private final List<Fragment> mFragments = new ArrayList<>();
    private final List<String> mFragmentTitles = new ArrayList<>();
    int numOfTabs;

    public GalleryViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    public void addFragment(Fragment fragment, String title)
    {
        mFragments.add(fragment);
        mFragmentTitles.add(title);
    }



    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitles.get(position);
    }
}

【问题讨论】:

  • 发布您的 Viewpager 适配器
  • 你从哪里调用你的 initGallery 方法?
  • 感谢 Akshay,但即使我通过 imageadapter(getActivity) 调用 ImageAdapter,gridview 也不会显示图像。 ??
  • 我正在从这个 viewpager(称为 GalleryViewPager)外部调用 initGallery()。我从活动中调用它。
  • 一旦携带此gridview的片段被销毁,ImageAdapter就不会填充gridview。请帮助我...

标签: android android-fragments gridview android-viewpager baseadapter


【解决方案1】:

在片段中的以下覆盖方法中调用您的 initGallery() 方法:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser){
       initGallery();
    }
}

【讨论】:

    【解决方案2】:

    不要在onCreateView() 中使用getActivity(),因为该活动可能尚未创建。在onActivityCreated() 中获取上下文。而且由于您的 InitUI(view) 方法使用上下文,因此您必须改为在 onActivityCreated() 中调用该方法。

    编辑 1: 在片段中调用initGallery() 中的onStart()onResume()。 并在片段中调用onPause() 中的disableGalleryTask()onStop()

    这样当视图对用户可见时,只会调用initGallery()

    【讨论】:

    • 我正在从这个 viewpager(称为 GalleryViewPager)外部调用 initGallery()。我从活动中调用它。
    • 片段重新创建时你是否调用initGallery()
    • 其实我是在这个ViewPager的onPageSelected中调用initGallery()
    • 因为我想在我们输入这个片段时启动填充异步任务的gridview..请帮助我..我需要提供更多信息吗..
    【解决方案3】:

    问题解决了!!!

    实际上,当我添加此片段(FragmentPhotos - 携带网格视图)时,以错误的方式添加到 viewpager -

    ViewPagerAdapter adapter = new ViewPagerAdapter(getFragmentManager()); //去掉这个

    //添加这个

    ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());

    非常感谢大家的帮助..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多