android viewpager用片段使用FragmentPageAdapter动态添加,删除

时间:2015-04-10 09:12:38

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

我有一个tabhost和viewpager的应用程序。 我有一个标签,片段固定。 我必须在第一个片段的radiogroup中单击单选按钮上动态添加制表符片段。

MyPagerAdapter类:

import java.util.ArrayList;
import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;

public class MyViewPageAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments = new ArrayList<Fragment>();
    FragmentManager fm;

    public List<Fragment> getFragments() {
        return fragments;
    }

    public void setFragments(List<Fragment> fragments) {
        this.fragments = fragments;
    }

    public MyViewPageAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fm = fm;
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

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

    public void addFragment(Fragment fragment) {
        this.fragments.add(fragment);
        notifyDataSetChanged();
    }

    public void removeFragments() {
        try {
            List<Fragment> newList = new ArrayList<Fragment>();
            Fragment general = fragments.get(0);
            newList.add(general);           
            this.fragments.clear();
            this.fragments = new ArrayList<Fragment>();
            this.fragments = newList;
            notifyDataSetChanged();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void removeItemFromFrament(ViewGroup container, int position, Object object) {
        try {
            try {
                container.removeViewAt(position);
                ((ViewPager) container).setCurrentItem(position - 1);               
            } catch (Exception e) {
                e.printStackTrace();
            }
            notifyDataSetChanged();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

MyPagerFragment类:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyViewPageFragment extends Fragment {

    private static View mView;

    public static final MyViewPageFragment newInstance(int layoutId) {
        MyViewPageFragment f = new MyViewPageFragment();
        Bundle b = new Bundle();
        b.putInt("layout", layoutId);
        f.setArguments(b);
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        int layout = getArguments().getInt("layout");
        try {
            mView = inflater.inflate(layout, container, false);
        } catch (Exception e) {
        }
        return mView;
    }

}

我试图像这样添加片段到适配器:

Fragment fragment = MyViewPageFragment.newInstance(R.layout.tab_content_layout);
((MyViewPageAdapter) mViewPager.getAdapter()).addFragment(fragment);

我的问题: 第一次,在删除所有视图(第一个片段除外)并尝试添加另一组选项卡,片段视图不可见以及getSupportFragmentmanager.getFragments()。size()不正确之后,页面被正确添加。

我尝试使用片段管理器

从viewpager中删除视图
FragmentManager manager = ((Fragment) object).getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove((Fragment) object);
trans.commit();

添加标签后,页面上的片段会滚动getSupportFragmentManager()。getFragments.get(arg0)返回null。

注意: 我必须保持第一个片段的状态,因此FragmentStatePagerAdapter和getItemPosition返回POSITION_NONE是不可接受的。

2 个答案:

答案 0 :(得分:1)

就像你从removeView() ListView专门拨打ListAdapter以取消某个项目一样,你不要直接删除来自Fragment的{​​{1}} FragmentManager

您必须覆盖FragmentPagerAdapter,但您必须提供更智能的实施,而不是一直只返回getItemPosition()

如果您的第一个片段永远不会更改,那么当该片段传递给POSITION_NONE时,始终会返回POSITION_UNCHANGED

将其视为您与getItemPosition() / ViewPager之间的对话。这是一个例子:

你:&#34;我需要改变周围的碎片。&#34; (致电FragmentPagerAdapter

适配器:&#34;抬起头来,我现在要改变一切。&#34; (回调notifyDataSetChanged

适配器:&#34;您想要多少个标签?&#34; (回调startUpdate

你是:三个。 (返回&#39; 3&#39;)

适配器:&#34;好的,你想让我对第一个做什么?&#34; (回调getCount()

你:&#34;我想把它保持在原处。&#34; (返回getItemPosition

适配器:&#34;太棒了,第二个呢?&#34; (回调POSITION_UNCHANGED

您:&#34;我想将其移至第三个标签页。&#34; (返回&#39; 2&#39;)

适配器:&#34;好吧,第三个怎么样?&#34; (回调getItemPosition

你:&#34;我想完全摆脱那个。&#34; (返回getItemPosition

适配器:&#34;好的,我有第二个标签的空间,你想让我使用什么片段?&#34; (回调POSITION_NONE

你:&#34;这一个。&#34; (返回位置== 1的片段)

适配器:&#34;我完成了所有改变,kthxbye。&#34; (回调getItem

我可能没有完全正确的通话顺序,但基本的想法就在那里。

如果您需要维护被踢出的片段的状态,可以覆盖finishUpdategetItem()来帮助您:

destroyItem()

您的片段需要实施private FragmentManager mFragmentManager; public MyPagerAdapter(FragmentManager fm) { super(fm); mFragmentManager = fm; } @Override public Fragment getItem(int position) { // figure out which fragment you want at this position Fragment fragment = new MyFragment(); // retrieve your savedState from wherever you put it fragment.setInitialSavedState(savedState); return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment) object; Fragment.SavedState savedState = mFragmentManager.saveFragmentInstanceState(fragment) // save your fragment state somewhere here super.destroyItem(container, position, object); } saveState()才能实现此目的。

答案 1 :(得分:0)

我使用FragmentStatePagerAdapter尝试了类似的要求。可能它可以帮助你。

添加新片段:

SIZE = SIZE +1;
adapter.instantiateItem(viewPager, SIZE-1);
adapter.notifyDataSetChanged();

在getItem()中,为“position”创建并返回新片段(我在这里使用了switch语句)

更新getCount()方法以返回新的SIZE。

如果您希望我分享代码,请与我们联系。