ViewPager中的片段没有被刷新

问题描述:

这是我使用camera2basic(google示例)捕获图像的片段。ViewPager中的片段没有被刷新

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

这是画廊片段我在哪里显示了存储的所有图片在SD卡中:

enter image description here

这里MainActivity由具有ViewPager,其具有5个片段

  • FragmentHome
  • FragmentGallery
  • FragmentCamera
  • FragmentStar
  • FragmentProfile

和内部FragmentGallery,有一个由具有2个片段另一个ViewPager(GalleryViewPager):

  • FragmentPhotos
  • FragmentVideos

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

要启动图库我打电话从MainActivity的initGallery()选项卡上的选择(当选择的标签是画廊片段),如:

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(); 
     } 
    } 
+0

一些提示一个问题,显示一些代码,请,我想你不刷新画廊片段内容你作出后一张照片。第一次创建图库片段时,它会加载图库中的所有信息,之后您看到的片段是适配器内的缓存图片...因此,请提供片段实例化代码和视图页适配器... – David

+0

现在,您可以帮助我@David –

写这条线,你延长FragmentPagerAdapter或FragmentStatPagerAdapter

 @Override 
     public int getItemPosition(Object object) { 
      return POSITION_NONE; 
     } 

当您在viewPager或轻扫一个片段到另一个它会自动刷新片段否则你可以像这样附加和分离片段

这将刷新当前片段:

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

记:你必须把这个代码,当数据被刷新就像一个一次性事件,否则您的应用程序会挂太多..只是不要在onCreat和onCreatView方法写

+0

这会工作,但根据我的经验,更有效的做法是创建一个内容可刷新片段的接口,并将其放入适配器,当需要刷新某些内容时,可以直接调用updateContent(),也许只是刷新画廊列表适配器的内容,所以不必重新创建片段。 – David

+0

不错的选择是你的..你问的问题,所以我只是给你一个解决方案,我认为是好的..快乐编码.. –

+0

我已经把getItemPosition在FragmentStatePagerAdapter,但它不工作! –

好吧我什么建议是,你创建一个这样的接口:

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

然后你开始你的意图拍照的用的ResultCode:

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

之后,在你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(); 
     } 
    } 
} 

所以,你可以处理一堆ViewPagerFragments内容refreshs无需重新创建日e每一次从你的上下文中的任何一个时间片段。 你也可以添加标签到你的片段,并刷新只是单一的,如果你修改方法一点。

使用getChildFragmentManager()在你的ViewPagerAdapter的构造

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