访问 fragmentpageradapter 中当前显示的片段

Getting access to the currently shown fragment in fragmentpageradapter

我有一个带有 fagmentpageradapter 和 viewpager 的父片段。每个页面显示另一个包含图像视图的片段。为了避免内存不足错误,我只希望当前显示的片段将其图像加载到图像视图中。所以我必须在当前显示的片段中加载图像视图,并在未显示的片段中回收图像。

父片段:

public class DatenFragment extends Fragment {

    private List<Data> mData;
    private ViewPaver mViewPager;
    private MyFragmentPagerAdapter mAdapter;

    public DatenFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_daten, container, false);

        mViewPager = (MyViewPager) rootView.findViewById(R.id.view_pager);
        mViewPager.setOnPageChangeListener(this);

        mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager(),mData);

        mViewPager.setAdapter(mAdapter);

        return rootView;
    }

    @Override
    public void onPageSelected(int position) {
        mAdapter.setCurrentPosition(position);
        mAdapter.loadFotos();
    }
}

片段页面适配器:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    private int mPos = -1;
    private List<Data> mData;

    public MyFragmentPagerAdapter(FragmentManager fm, List<Data> data) {
        super(fm);
        mData = data;
    }

    public void loadFotos(){
        EingabeFragment currentFragment;
        currentFragment = (EingabeFragment) getItem(mPos);
        currentFragment.loadFoto();
        currentFragment = (EingabeFragment) getItem(mPos-1);
        currentFragment.unloadFoto();
        currentFragment = (EingabeFragment) getItem(mPos+1);
        currentFragment.unloadFoto();
    }

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

    @Override
    public Fragment getItem(int position) {
        return EingabeFragment.createFrom(mData.get(position),position);
    }

    public void setCurrentPosition(int position) { mPos = position; }

}

viewpager 显示的片段:

public class EingabeFragment extends Fragment {

    private int mPos;
    private Data mData;
    private ImageView mImageView;

    public EingabeFragment() { }

    public void loadFoto(){
        if(mData.hasFoto()) {
            mImageView.setImageBitmap(Utils.loadFoto(mData.getFoto()));
            Log.d("DEBUG", "Foto loaded for " + mData.getId());
        }
    }
    public void unloadFoto(){
        if(mData.hasFoto()) {
            Drawable drawable = mImageView.getDrawable();
            if (drawable instanceof BitmapDrawable) {
                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
                Bitmap bitmap = bitmapDrawable.getBitmap();
                bitmap.recycle();
                Log.d("DEBUG","Foto unloaded for " + mData.getId());
            } 
        } 
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_eingabe, container, false);

        mImageView = (ImageView) rootView.findViewById(R.id.image_view);

        return rootView;
    }

    public int getPosition() { return mPos; }

    static public EingabeFragment createFrom(Data data, int fragmentPosition){
        EingabeFragment eingabeFragment = new EingabeFragment();
        eingabeFragment.mData = data;
        eingabeFragment.mPos = fragmentPosition;
        return eingabeFragment;
    }

}

在适配器的 loadFotos() 函数中,getItem() 函数 returns 显示的片段的新实例。所以视图尚未创建,mImageView 为空。我需要一种方法来访问寻呼机中显示的片段,以便在此片段中加载图像。

从我的 ViewPager 中选择的 OnPage:

@Override
public void onPageSelected(int position) {

    EingabeFragment f = (EingabeFragment) mAdapter.getItem(mAdapter.getCurrentPosition());
    f.onPauseFragment();

    EingabeFragment f2 = (EingabeFragment)  mAdapter.getItem(position);
    f2.onResumeFragment();

    mAdapter.setCurrentPosition(position);
}

Eingabefragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_eingabe, container, false);
    mRootView = rootView;

    imageViewFoto = (ImageView) rootView.findViewById(R.id.imageView_foto);

    //Load other UI...

    mInitialized = true;

    return rootView;
}

@Override
public void onPauseFragment() {
    Log.d("DEBUG",mMessung.getId().toString() + " Pause");
    if(mInitialized) {
        unloadFoto();
        Log.d("DEBUG",mMessung.getId().toString() + " Unloaded Foto");
    } else {
        Log.d("DEBUG",mMessung.getId().toString() + " View is null");
    }
}

@Override
public void onResumeFragment() {
    Log.d("DEBUG",mMessung.getId().toString() + " Resume");
    if(mInitialized) {
        loadFoto();
        Log.d("DEBUG",mMessung.getId().toString() + " Unloaded Foto");
    } else {
        Log.d("DEBUG",mMessung.getId().toString() + " View is null");
    }
}

现在我的日志在向右然后向左滑动后给我以下信息:

104 Pasue
104 View is null
105 Resume
105 View is null
105 Pause
105 View is null
104 Resume 
104 View is null

为正确的片段调用暂停和恢复,但 mImageView 为空

有一些解决方法,

如果您的 Fragment 扩展 android.support.v4.app.Fragment

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        //fragment is visible do what ever you want to do..
    }else {
       // handle here
    }
}

或者对于其他解决方案,您可以遵循 this 这个 link,创建一个接口和回调,这样您现在就可以知道哪个片段在 onResume()

对于第二种解决方案,onResume() 第一次在 onCreateView 之前调用,因此您需要在您的片段中进行布尔检查,例如 lodingFirstTime = true,将其设置为全局,在您的负载中方法检查

(!lodingFirstTime) {
  //loadfoto method
}

并在第一个片段的 onCreateView 中

(lodingFirstTime) {
      lodingFirstTime = false;
      //loadfoto method
    }

在寻呼机中实现 ViewPager.OnPageChangeListener 并在 OnPageChangeListener 的 onPageSelected() 方法的片段中加载图像

    @Override
    public void onPageSelected(int position) {
        //show image
        ((Your Fragment) mFragments.get(position)).loadImage();
    }