Android Viewpager和FragmentPagerAdapter:页面视图删除
我正在使用Android Viewpager和FragmentPagerAdapter:页面视图删除,android,android-fragments,android-viewpager,Android,Android Fragments,Android Viewpager,我正在使用Viewpager和FragmentPagerAdapter来允许添加和删除页面。每个页面显示从internet获得的数据 当添加一个新页面时,一个新片段与该页面相关联。数据通过AsyncTask获得并显示在片段中。当用户选择删除页面时,其想法是销毁页面和相关片段 总的来说,这一切都很好。我看到的问题如下: // Destroy fragment for this page DataListFragment curFrag = getFragmentByName(curre
Viewpager
和FragmentPagerAdapter
来允许添加和删除页面。每个页面显示从internet获得的数据
当添加一个新页面时,一个新片段与该页面相关联。数据通过AsyncTask获得并显示在片段中。当用户选择删除页面时,其想法是销毁页面和相关片段
总的来说,这一切都很好。我看到的问题如下:
// Destroy fragment for this page
DataListFragment curFrag = getFragmentByName(currentPage);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(curFrag).commit();
fm.executePendingTransactions();
curFrag = null;
// Remove page and update adapter
mPageTitles.remove(position);
mAdapter.notifyDataSetChanged();
“我的活动”中的页面删除代码如下:
// Destroy fragment for this page
DataListFragment curFrag = getFragmentByName(currentPage);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(curFrag).commit();
fm.executePendingTransactions();
curFrag = null;
// Remove page and update adapter
mPageTitles.remove(position);
mAdapter.notifyDataSetChanged();
使用调试器,它显示在调用executePendingTransactions()
之后从FragmentManager
中删除片段。但是在FrampePagerAdapters
调用中,mAdapter.notifyDataSetChanged()
,片段被重新添加,然后在创建新页面时显示
我尝试使用FrameStatePagerAdapter,因为这应该允许销毁片段,但它不起作用。在FragmentPagerAdapter的getItemPosition()
方法中,我使用返回FragmentAdapter.POSITION\u NONE正如我在另一篇SO文章中指出的那样
似乎该页面的视图没有被破坏,而是被添加回新页面。我尝试在新页面的视图上使用removeViewAt()
方法,但没有成功
作为新手,我确信我缺少了一些明显的东西…您应该扩展FragmentStatePagerAdapter
并从适配器中的项目列表中删除相应的项目,而不是尝试从活动中删除片段。删除适配器中的项目后,不要忘记调用适配器。notifyDataSetChanged()
。完成后,ViewPager
和FragmentStatePagerAdapter
将处理其余部分。请参见getCount()方法返回ViewPager中的确切项数。是的,碎纸机也很重要 我最终找到了一个解决方案,它结合了以下基于经验的知识:
- 您可以在尾部添加一个新的
片段
- 您无法读取以前删除的
,因为它会导致片段
,因此您必须克隆它java.lang.IllegalStateException:有时无法更改片段的标记
- 要删除
,必须在方法片段
中返回getItemPosition(Object Object)
,然后从PagerAdapter.POSITION\u NONE
中删除片段管理器
片段
- 如果您在不同于尾部的其他位置添加/删除/替换,则必须从要更改的位置删除所有内容,直到结束,然后读取您删除的(克隆的)
片段
FragmentActivity
代码,带有FragmentPagerAdapter
,它有3种添加、删除和替换选项卡的方法:
public class TabTestActivity extends FragmentActivity implements
ActionBar.TabListener {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private static int tabCount = 0;
private static String labelString = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
labelString = getString(R.string.title_section);
setContentView(R.layout.activity_tab_test);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(final int position) {
(new Handler()).postDelayed(new Runnable() {
@Override
public void run() {
actionBar.setSelectedNavigationItem(position);
}
}, 1);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.tab_test, menu);
return true;
}
public void addNewTab() {
int position = (mSectionsPagerAdapter.getCount() > 0 ? mViewPager.getCurrentItem() : 0);
mSectionsPagerAdapter.insertFragment(position);
mViewPager.setCurrentItem(position, true);
}
public void removeTab() {
if (mSectionsPagerAdapter.getCount() > 0) {
int position = mViewPager.getCurrentItem();
mSectionsPagerAdapter.removeFragment(position);
}
}
public void replaceTab() {
if (mSectionsPagerAdapter.getCount() > 0) {
int position = mViewPager.getCurrentItem();
mSectionsPagerAdapter.replaceFragment(position);
mViewPager.setCurrentItem(position, false);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_tab:
addNewTab();
return true;
case R.id.action_remove_tab:
removeTab();
return true;
case R.id.action_replace_tab:
replaceTab();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> currentFragments;
private FragmentManager fragmentManager;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
fragmentManager = fm;
currentFragments = new ArrayList<Fragment>();
}
public void insertFragment(int position) {
// Remove fragments from position
List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size()));
int i = currentFragments.size() - 1;
int j = -1;
int k = i;
while (i >= position) {
currentFragments.remove(i);
i--;
j++;
}
notifyDataSetChanged();
final ActionBar actionBar = getActionBar();
while (k >= position) {
actionBar.removeTabAt(k);
k--;
}
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
while (j >= 0) {
Fragment fragmentToRemove = fragmentsToRemove.get(j);
transaction.detach(fragmentToRemove);
transaction.remove(fragmentToRemove);
j--;
}
transaction.commit();
fragmentManager.executePendingTransactions();
notifyDataSetChanged();
// Add new fragment
Fragment fragment = new DummySectionFragment();
currentFragments.add(position, fragment);
notifyDataSetChanged();
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(position))
.setTabListener(TabTestActivity.this), position);
// Readd fragments
if (fragmentsToRemove.size() > 0) {
i = 1;
for (Fragment fragmentToRemove : fragmentsToRemove) {
currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragmentToRemove));
notifyDataSetChanged();
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(position + i))
.setTabListener(TabTestActivity.this), position + i);
i++;
}
}
}
public void removeFragment(int position) {
// Remove fragments from position
List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size()));
int i = currentFragments.size() - 1;
int j = -1;
int k = i;
while (i >= position) {
currentFragments.remove(i);
i--;
j++;
}
notifyDataSetChanged();
final ActionBar actionBar = getActionBar();
while (k >= position) {
actionBar.removeTabAt(k);
k--;
}
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
while (j >= 0) {
Fragment fragmentToRemove = fragmentsToRemove.get(j);
transaction.detach(fragmentToRemove);
transaction.remove(fragmentToRemove);
j--;
}
transaction.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
notifyDataSetChanged();
// Readd fragments (except one)
if (fragmentsToRemove.size() > 1) {
i = 0;
for (Fragment fragment : fragmentsToRemove.subList(1, fragmentsToRemove.size())) {
currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragment));
notifyDataSetChanged();
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(position + i))
.setTabListener(TabTestActivity.this), position + i);
i++;
}
}
}
public void replaceFragment(int position) {
// Remove fragments from position
List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size()));
int i = currentFragments.size() - 1;
int j = -1;
int k = i;
while (i >= position) {
currentFragments.remove(i);
i--;
j++;
}
notifyDataSetChanged();
final ActionBar actionBar = getActionBar();
while (k >= position) {
actionBar.removeTabAt(k);
k--;
}
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
while (j >= 0) {
Fragment fragmentToRemove = fragmentsToRemove.get(j);
transaction.detach(fragmentToRemove);
transaction.remove(fragmentToRemove);
j--;
}
transaction.commit();
fragmentManager.executePendingTransactions();
notifyDataSetChanged();
// Add new fragment
Fragment fragment = new DummySectionFragment();
currentFragments.add(position, fragment);
notifyDataSetChanged();
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(position))
.setTabListener(TabTestActivity.this), position);
// Readd fragments (except one)
if (fragmentsToRemove.size() > 0) {
i = 1;
for (Fragment fragmentToRemove : fragmentsToRemove.subList(1, fragmentsToRemove.size())) {
currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragmentToRemove));
notifyDataSetChanged();
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(position + i))
.setTabListener(TabTestActivity.this), position + i);
i++;
}
}
}
@Override
public Fragment getItem(int position) {
if (currentFragments == null) {
currentFragments = new ArrayList<Fragment>();
}
while (currentFragments.size() <= position) {
currentFragments.add(null);
}
if (currentFragments.get(position) != null) {
return currentFragments.get(position);
}
Fragment fragment = new DummySectionFragment();
currentFragments.set(position, fragment);
return fragment;
}
@Override
public int getCount() {
return currentFragments.size();
}
@Override
public int getItemPosition(Object object) {
int position = currentFragments.indexOf(object);
if (position == -1) {
return PagerAdapter.POSITION_NONE;
}
return position;
}
@Override
public CharSequence getPageTitle(int position) {
return ((DummySectionFragment)getItem(position)).getTitle();
}
}
public static class DummySectionFragment extends Fragment {
private int sectionNumber;
public DummySectionFragment() {
super();
sectionNumber = ++tabCount;
}
public static DummySectionFragment cloneExistingFragment(DummySectionFragment fragment) {
DummySectionFragment cloned = new DummySectionFragment();
// Hack for avoiding autoincrement
--tabCount;
cloned.sectionNumber = fragment.getSectionNumber();
return cloned;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tab_test_dummy,
container, false);
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.setText(String.format(labelString, sectionNumber));
return rootView;
}
public int getSectionNumber() {
return sectionNumber;
}
public String getTitle() {
return String.format(labelString, sectionNumber);
}
}
}
公共类TabTestActivity扩展了FragmentActivity实现
ActionBar.TabListener{
私人部门SPAGERAAdapter MSECTIONSPAGERAAdapter;
私有视图寻呼机mViewPager;
私有静态int tabCount=0;
私有静态字符串labelString=null;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
labelString=getString(R.string.title_部分);
setContentView(R.layout.activity\u tab\u test);
最终ActionBar ActionBar=getActionBar();
actionBar.setNavigationMode(actionBar.NAVIGATION\u MODE\u选项卡);
mSectionsPagerAdapter=新节spageradapter(
getSupportFragmentManager());
mViewPager=(ViewPager)findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(新的ViewPager.SimpleOnPageChangeListener(){
@凌驾
已选择页面上的公共无效(最终整型位置){
(新的处理程序()).postDelayed(新的可运行(){
@凌驾
公开募捐{
actionBar.setSelectedNavigationItem(位置);
}
}, 1);
}
});
对于(int i=0;i0?mviewpage.getCurrentItem():0);
mSectionsPagerAdapter.insertFragment(位置);
mViewPager.setCurrentItem(位置,true);
}
公共无效删除选项卡(){
如果(msActionSpagerAdapter.getCount()>0){
int position=mViewPager.getCurrentItem();
mSectionsPagerAdapter.removeFragment(位置);
}
}
公共void replaceTab(){
如果(msActionSpagerAdapter.getCount()>0){
int position=mViewPager.getCurrentItem();
mSectionsPagerAdapter.replaceFragment(位置);
mViewPager.setCurrentItem(位置,false);