ViewPager中的片段未刷新

时间:2016-07-26 11:08:40

标签: android android-fragments android-viewpager fragmentpageradapter

这是我使用camera2basic(谷歌样本)捕获图像的片段。

enter image description here

我用这个方法用最新捕获的图片更新图库:

private void refreshGallery(File file)
    {
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.fromFile(file));
        getActivity().sendBroadcast(intent);
    }

这是Gallery Fragment,我将显示存储在SD卡中的所有图像:

enter image description here

这里的MainActivity有一个ViewPager,它有5个片段

  • FragmentHome
  • FragmentGallery
  • FragmentCamera
  • FragmentStar
  • FragmentProfile

在FragmentGallery内部,还有另一个ViewPager(GalleryViewPager)有2个片段

  • FragmentPhotos
  • FragmentVideos

现在您可以看到,CameraFragment位于MainActivity的ViewPager中,FragmentPhotos(显示图库的所有照片)位于FragmentGallery内的另一个ViewPager中。 现在,当我点击照片并导航到FragmentPhotos(在FragmentGallery内)时,画廊会更新,最近点击的图片会显示(仅限第一次)但是当我点击更多图片并返回FragmentPhotos(在FragmentGallery内)时图库没有更新 !!!此外,当我移动到另一个选项卡(Tab1,Tab2和Tab3除Tab4或Tab5除外),即当ViewPager被解除时,画廊每次都会更新,没有任何问题! 请帮帮我,如何更新ViewPager中的片段。 虽然我尝试使用notifysetchanged更新它,但它没有效果。

要启动Gallery,我将从选项卡选项上的MainActivity调用initGallery()(当选定的选项卡是Gallery Fragment时),如下所示:

ViewPager viewPager = (ViewPager) findViewById(R.id.pagerGallery);
                    GalleryViewPagerAdapter adapter = (GalleryViewPagerAdapter) viewPager.getAdapter();
                    for (int i = 0; i < adapter.getCount(); i++) {
                        Fragment fragmentObject = (Fragment) viewPager.getAdapter().instantiateItem(viewPager, i);
                        if (fragmentObject instanceof FragmentPhotos) {
                            FragmentPhotos fragment = (FragmentPhotos) fragmentObject;
                            if (fragment != null) {
                                ((FragmentPhotos) fragment).initGallery();
                                Log.e("", "Gallery called");
                            }
                        }
                    }

以下是我的PagerAdpater:

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 int getItemPosition(Object object) {
        return POSITION_NONE;
    }

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

以下是initGallery():

public void initGallery()
    {
        {
            new GetImagesFromCard().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
    }

和GetImagesFromCard如下:

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)
                {
                    new ShowImagesEnlarged(i).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                }
                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();
        }
    }

3 个答案:

答案 0 :(得分:1)

在你扩展FragmentPagerAdapter或FragmentStatPagerAdapter

的地方写下这一行
       @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

在viewPager中将一个片段滑动到另一个片段时会自动刷新片段,否则你可以像这样附加和分离片段

这将刷新当前片段:

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(this).attach(this).commit();

注意:您必须将此代码放入一次性事件中,例如刷新数据时,否则您的应用程序将挂起太多..只是不要写入onCreat和onCreatView方法

答案 1 :(得分:0)

好的,我建议你创建一个这样的界面:

public interface IContentRefreshableFragment {
    void refreshContent()
}

所有碎片应该实现此接口,例如:

public class FragmentPhoto implements IContentRefreshableFragment {
    @Override
    public void refreshContent() {
        // You have to refresh your dataset here and push it into your
        // adapter, don't forget to call adapter.notifiyDataSetChanged();
        initGallery();
    }
}

然后你启动你的Intent用ResultCode拍照:

public static final String PHOTO_TAKEN = "PHOTO_TAKEN";    
startActivityForResult(PhotoActivity.class, PHOTO_TAKEN);

在您的Activity中的onActivityResult(...)之后,检查ResultCode并触发内容刷新:

@Override
public void onActivityResult(..., String requestCode) {
     if(requestCode.equals(PHOTO_TAKEN) {
        adapter.refreshContent();
     }
}

在您的适配器中:

public class GalleryViewPagerAdapter extends FragmentStatePagerAdapter {
    private List<IContentRefreshableFragment> mFragments;

    public void refreshContent() {
        for(IContentRefreshableFragment fragment : mFragments) {
            fragment.refreshContent();
        }
    }
}

因此,您可以处理大量ViewPager Fragments内容刷新,而无需每次从上下文中的任何位置重新创建片段。 此外,如果稍微修改方法,您可以为片段添加标签并刷新单个片段。

答案 2 :(得分:0)

在ViewPagerAdapter的构造函数中使用getChildFragmentManager()

ViewPager viewPager = (ViewPager) findViewById(R.id.pagerGallery);
                GalleryViewPagerAdapter adapter = new GalleryViewPagerAdapter(getChildFragmentManager());
                for (int i = 0; i < adapter.getCount(); i++) {
                    Fragment fragmentObject = (Fragment) viewPager.getAdapter().instantiateItem(viewPager, i);
                    if (fragmentObject instanceof FragmentPhotos) {
                        FragmentPhotos fragment = (FragmentPhotos) fragmentObject;
                        if (fragment != null) {
                            ((FragmentPhotos) fragment).initGallery();
                            Log.e("", "Gallery called");
                        }
                    }
                }

https://code.google.com/p/android/issues/detail?id=55068

中的一些提示存在问题