访问fragmentpageradapter

时间:2017-01-27 10:17:11

标签: android android-fragments android-viewpager android-bitmap fragmentpageradapter

我有一个包含fagmentpageradapter和viewpager的父片段。每个页面显示另一个包含imageview的片段。为了避免outofmemoryerrors我只想要当前显示的片段在imageview中加载其图像。因此,我必须在当前显示的片段中加载imageview,并在未显示的片段中回收图像。

Parentfragment:

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

Fragmentpageradapter:

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()函数返回显示的片段的新实例。因此,视图尚未创建,mImageView为null。我需要一种方法来访问分页器中显示的片段,以便在此片段中加载图像。

从我的ViewPager OnPageSelected:

@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

为正确的片段调用Pause和Resume,但mImageView为null

2 个答案:

答案 0 :(得分:1)

有一些工作,

如果您的片段扩展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
    }
}

或者您可以关注其他解决方案copy elision此链接,进行界面和回调,以便您现在可以在onResume()中使用哪个片段。

对于第二个解决方案,onResume()第一次在onCreateView之前调用,因此您需要在片段中对lodingFirstTime = true进行布尔检查,在加载方法检查中全局设置它

(!lodingFirstTime) {
  //loadfoto method
}

和你的第一个片段的onCreateView

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

答案 1 :(得分:0)

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

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