动态更新ViewPager?

336

我无法更新ViewPager中的内容。

在FragmentPagerAdapter类中,方法instantiateItem()和getItem()的正确使用方式是什么?

我之前只使用了getItem()来实例化和返回我的fragment:

@Override
public Fragment getItem(int position) {
    return new MyFragment(context, paramters);
}

这个方法很有效,但我无法更改内容。
所以我找到了这个:ViewPager PagerAdapter not updating the View

“我的方法是在instantiateItem()方法中为任何实例化的视图使用setTag()方法”

现在我想要实现instantiateItem()来做到这一点。但我不知道我必须返回什么(类型为Object),以及getItem(int position)之间的关系是什么?
我阅读了reference
  • public abstract Fragment getItem (int position)

    返回与指定位置相关联的Fragment。

  • public Object instantiateItem (ViewGroup container, int position)

    为给定的位置创建页面。适配器负责将视图添加到此处给定的容器中,尽管它只需确保在从finishUpdate(ViewGroup)返回时完成此操作。

    参数

    container 要显示该页的包含视图。 position 要实例化的页面位置。

    返回值

    返回表示新页面的对象。这不必是View,但可以是页面的其他容器。

但我仍然不理解。

这是我的代码。我正在使用support package v4。

ViewPagerTest

public class ViewPagerTest extends FragmentActivity {
    private ViewPager pager;
    private MyFragmentAdapter adapter; 

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

        pager = (ViewPager)findViewById(R.id.slider);

        String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};

        adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        pager.setAdapter(adapter);

        ((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                reload();
            }
        });
    }

    private void reload() {
        String[] data = {"changed1", "changed2", "changed3", "changed4", "changed5", "changed6"};
        //adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        adapter.setData(data);
        adapter.notifyDataSetChanged();
        pager.invalidate();

        //pager.setCurrentItem(0);
    }
}

我的Fragment适配器

class MyFragmentAdapter extends FragmentPagerAdapter {
    private int slideCount;
    private Context context;
    private String[] data;

    public MyFragmentAdapter(FragmentManager fm, int slideCount, Context context, String[] data) {
        super(fm);
        this.slideCount = slideCount;
        this.context = context;
        this.data = data;
    }

    @Override
    public Fragment getItem(int position) {
        return new MyFragment(data[position], context);
    }

    @Override
    public int getCount() {
        return slideCount;
    }

    public void setData(String[] data) {
        this.data = data;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

我的Fragment

public final class MyFragment extends Fragment {
    private String text;

    public MyFragment(String text, Context context) {
        this.text = text;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.slide, null);
        ((TextView)view.findViewById(R.id.text)).setText(text);

        return view;
    }
}

这里还有一个人遇到了类似的问题,但没有答案。 http://www.mail-archive.com/android-developers@googlegroups.com/msg200477.html


为了更好地理解涉及的组件,阅读我的有关带有单独后退导航历史记录的选项卡ViewPager的教程可能会有所帮助。它附带了GitHub上的工作示例和其他资源:https://medium.com/@nilan/separate-back-navigation-for-a-tabbed-view-pager-in-android-459859f607e4 - marktani
遇到了一些问题:http://stackoverflow.com/questions/40149039/viewpager-recyclerview-issue - albert
你可以在GitHub上查看这个示例。希望这个示例能对你有所帮助。 - Cabezas
好的简单解决方案:stackoverflow.com/a/35450575/2162226 - Gene Bo
Google最近推出了ViewPager2,它简化了动态Fragment/View的更新。您可以在https://github.com/googlesamples/android-viewpager2或此答案https://dev59.com/QGw05IYBdhLWcg3wZBAC#57393414上查看示例。 - Yves Delerm
21个回答

0

我已经阅读了上面所有的答案以及其他一些帖子,但仍然找不到适合我的解决方案(因为我使用了不同的片段类型,并且动态添加和删除选项卡)。顺便说一下,以下方法是对我有效的(如果有人遇到相同的问题可以尝试一下)。

public class MyFragmentStatePageAdapter extends FragmentStatePagerAdapter {
    private static final String TAB1_TITLE = "Tab 1";
    private static final String TAB2_TITLE = "Tab 2";
    private static final String TAB3_TITLE = "Tab 3";

    private ArrayList<String> titles = new ArrayList<>();
    private Map<Fragment, Integer> fragmentPositions = new HashMap<>();


    public MyFragmentStatePageAdapter(FragmentManager fm) {
        super(fm);
    }


    public void update(boolean showTab1, boolean showTab2, boolean showTab3) {
        titles.clear();

        if (showTab1) {
            titles.add(TAB1_TITLE);
        }
        if (showTab2) {
            titles.add(TAB2_TITLE);
        }
        if (showTab3) {
            titles.add(TAB3_TITLE);
        }
        notifyDataSetChanged();
    }


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

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;

        String tabName = titles.get(position);
        if (tabName.equals(TAB1_TITLE)) { 
            fragment =  Tab1Fragment.newInstance();
        } else if (tabName.equals(TAB2_TITLE)) {
            fragment =  Tab2Fragment.newInstance();
        } else if (tabName.equals(TAB3_TITLE)) {
            fragment =  Tab3Fragmen.newInstance();
        } 

        ((BaseFragment)fragment).setTitle(tabName);
        fragmentPositions.put(fragment, position);
        return fragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }

    @Override
    public int getItemPosition(Object item) {
        BaseFragment fragment = (BaseFragment)item;
        String title = fragment.getTitle();
        int position = titles.indexOf(title);

        Integer fragmentPosition = fragmentPositions.get(item);
        if (fragmentPosition != null && position == fragmentPosition) {
            return POSITION_UNCHANGED;
        } else {
            return POSITION_NONE;
        }
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
        fragmentPositions.remove(object);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接