替换ViewPager中另一个片段中的片段

时间:2013-10-14 17:42:35

标签: android android-viewpager fragment fragmentstatepageradapter

我是Android编程的新手,我很难让它工作(我很接近,但我遗漏了一些重要的东西)。

我有一个名为PatientPagerActivity的活动,该活动通过患者信息片段进行分页。在每个PatientFragment中,我有一个按钮,当点击时,除了患者信息之外,还会提供一些杂项信息。因此,我计划在PatientPagerActivity中做的是用PatientWithMiscFragment替换PatientFragment(其中包含患者信息和杂项部分)。

activity_pager.xml文件:

<android.support.v4.view.ViewPager 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/viewPager"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />

PatientPagerActivity文件:

public class PatientPagerActivity extends FragmentActivity
implements PatientPagerActivityCallbacks {
private ViewPager mViewPager;
private List<Patient> mQuizProblemList;

private int mCurrentIndex;
private List<PatientFragment> mPatientFragmentList;
private List<PatientWithMiscFragment> mPatientWithMiscFragmentList;

private static final String EMPTY_TEXT = "";


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pager);

    mViewPager = (ViewPager) findViewById(R.id.viewPager);

    mPatientList = 
               PatientManager.getInstance(this).getPatients();

    FragmentManager fm = getSupportFragmentManager();
    mViewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
        @Override
        public int getCount() {
            return mPatientList.size();
        }

        @Override
        public Fragment getItem(int location) {
            Patient patient = mPatientList.get(location);
            PatientFragment fragment = 
                                    PatientFragment.newInstance(patient);
            PatientWithMiscFragment miscFragment = 
                                    PatientWithMiscFragment.newInstance(patient);

            if(mPatientFragmentList== null) {
                mPatientFragmentList = 
                                          new ArrayList<PatientFragment>();
            }
            mPatientFragmentist.add(fragment);

            if(mPatientWithMiscFragmentList == null) {
                mPatientWithMiscFragmentList = 
                                       new ArrayList<PatientWithMiscFragment>();
            }
            mPatientWithMiscFragmentList.add(miscFragment);

            return fragment;
        }
    });

    mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageSelected(int counter) {
            setTitle("Patient: " + (counter + 1));
            mCurrentIndex = counter;
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            hideMiscInformation();
        }
    });

    long patientID =
                   getIntent().getLongExtra(PatientFragment.EXTRA_PATIENT_ID, -1);
    for(int counter = 0; counter < mPatientList.size(); counter++) {
        if(mPatientList.get(counter).getPatient().getID() == patientID) {
            mViewPager.setCurrentItem(counter);
            setTitle("Patient: " + (counter + 1));
            mCurrentIndex = counter;
            break;
        }
    }
}

@Override
public void onMiscSelected() {
    if(findViewById(R.id.viewPager) != null) {
        FragmentManager fm  = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

                    //Find the current PatientInformation
        Fragment oldFragment = mPatientFragmentList.get(mCurrentIndex);
        //And Remove it 
        if(oldFragment != null) {
            ft.remove(oldFragment);
            ft.commit();
        }
                    //Notify the adapter that data set has changed.
        notifyAdapterDataSetChanged();

        ft = fm.beginTransaction();
                    //Replace it with the corresponding fragment that also has misc
        ft.add(R.id.viewPager,
                           mPatientWithMiscFragmentList.get(mCurrentIndex));
        ft.commit();    
        notifyAdapterDataSetChanged();
    }
}

public void hideMiscInformation() {
    if(findViewById(R.id.viewPager) != null) {
        FragmentManager fm  = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        //Remove the misc information
        Fragment oldMiscFragment =
                         fm.findFragmentById(R.id.viewPager);           
        if(oldMiscFragment != null) {
            ft.remove(oldMiscFragment);
            ft.commit();
        }
                    //Replace it with ONLY the patient information.
                    ft = fm.beginTransaction();
        ft.add(R.id.viewPager, mPatientFragmentList.get(mCurrentIndex));
        ft.commit();
        notifyAdapterDataSetChanged();
    }
}
    :
    :
}

当用户对其他信息感兴趣时,PagerActivity会发生回调,而onMiscSelected()会将PatientFragment替换为PatientWithMiscFragment。但是,就我而言,这种情况并没有发生。

请帮我弄清楚我哪里出错了。

谢谢!

2 个答案:

答案 0 :(得分:0)

正如其他帖子中所记载的,当您处理FragmentStatePageAdapter时,您需要注意以下事项: 1.使用新片段替换旧片段后,通过调用FragmentStatePageAdapter.notifyDataSetChanged()通知适配器底层数据已更改。 2.您需要覆盖getItemPosition()。在此方法中,如果位于特定位置的片段未更改,并且您返回POSITION_NONE,则会得到不正确的结果。

包含更改的代码如下:

public class PatientPagerActivity extends FragmentActivity implements PatientPagerActivityCallbacks {
    private ViewPager mViewPager;
    private List<Patient> mPatientList;

    private int mCurrentIndex;
    private List<PatientFragment> mPatientFragmentList;
    private List<PatientWithMiscFragment> mPatientWithMiscFragmentList;

    private static final String EMPTY_TEXT = "";


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pager);

        mViewPager = (ViewPager) findViewById(R.id.viewPager);

        mPatientList = 
                PatientManager.getInstance(this).getPatients();

        FragmentManager fm = getSupportFragmentManager();
        mViewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
            @Override
            public int getCount() {
                return mPatientList.size();
            }

            @Override
            public Fragment getItem(int location) {
                Patient patient = mPatientList.get(location);
                PatientFragment fragment = 
                        PatientFragment.newInstance(patient);
                PatientWithMiscFragment miscFragment = 
                        PatientWithMiscFragment.newInstance(patient);

                if(mPatientFragmentList== null) {
                    mPatientFragmentList = 
                            new ArrayList<PatientFragment>();
                }
                mPatientFragmentist.add(location, fragment);

                if(mPatientWithMiscFragmentList == null) {
                    mPatientWithMiscFragmentList = 
                            new ArrayList<PatientWithMiscFragment>();
                }
                mPatientWithMiscFragmentList.add(location, miscFragment);

                return fragment;
            }
            @Override
            public int getItemPosition(Object object) {
                PatientFragment fragment = (PatientFragment) object;
                if(mPatientFragmentList.get(mCurrentIndex).getCurrentPatient() != null && 
                    fragment.getCurrentPatient().getID().
                        equals(mPatientFragmentList.get(
                        mCurrentIndex).getCurrentPatient().getID())) {
                    return POSITION_NONE;
                } else if(mPatientFragmentList.get(mCurrentIndex).getCurrentPatient() == null) {
                    return POSITION_NONE;
                } else {
                    return POSITION_UNCHANGED;
                }

            }
        });

        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int counter) {
                setTitle("Patient: " + (counter + 1));
                mCurrentIndex = counter;
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                hideMiscInformation();
            }
        });

        long patientID =
                getIntent().getLongExtra(PatientFragment.EXTRA_PATIENT_ID, -1);
        for(int counter = 0; counter < mPatientList.size(); counter++) {
            if(mPatientList.get(counter).getPatient().getID() == patientID) {
                mViewPager.setCurrentItem(counter);
                setTitle("Patient: " + (counter + 1));
                mCurrentIndex = counter;
                break;
            }
        }
    }

    @Override
    public void onMiscSelected() {
        if(findViewById(R.id.viewPager) != null) {
            FragmentManager fm  = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();

            //Find the current PatientInformation
            Fragment oldFragment = mPatientFragmentList.get(mCurrentIndex);
            //And Remove it 
            if(oldFragment != null) {
                ft.remove(oldFragment);
                ft.commit();
            }


            ft = fm.beginTransaction();
            //Replace it with the corresponding fragment that also has misc
            ft.add(R.id.viewPager,
                    mPatientWithMiscFragmentList.get(mCurrentIndex));
            ft.commit();    
            notifyAdapterDataSetChanged();
        }
    }

    public void hideMiscInformation() {
        if(findViewById(R.id.viewPager) != null) {
            FragmentManager fm  = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();

            //Remove the misc information
            Fragment oldMiscFragment =
                    fm.findFragmentById(R.id.viewPager);           
            if(oldMiscFragment != null) {
                ft.remove(oldMiscFragment);
                ft.commit();
            }
            //Replace it with ONLY the patient information.
            ft = fm.beginTransaction();
            ft.add(R.id.viewPager, mPatientFragmentList.get(mCurrentIndex));
            ft.commit();
            notifyAdapterDataSetChanged();
        }
    }

}

答案 1 :(得分:-1)

您可以使用简单的“FrameLayout”将其与您的片段一起充气。所以最新的片段将取代之前的片段。

here就是一个例子

祝你好运!