web-dev-qa-db-fra.com

Aperçus de recyclage dans ViewPager

J'essaie de faire fonctionner cela: je veux essentiellement deux recyclerviews dans un ViewPager. J'ai suivi ce tutoriel: http://Android-Java-development.blogspot.de/2012/05/system.html , mais cela ne semble pas fonctionner. J'ai l'impression que le téléavertisseur de vue est vide et que la vue du recycleur ne s'affiche pas.

Voici mon code de mise en page:

<Android.support.v4.widget.SwipeRefreshLayout
        Android:id="@+id/pager_refresh_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:paddingTop="@dimen/tab_height">

        <Android.support.v4.view.ViewPager
            Android:id="@+id/pager"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:background="@color/accent"/>
    </Android.support.v4.widget.SwipeRefreshLayout>

Et mon PageAdapter:

public class NewsPagerAdapter extends PagerAdapter {
    private Context context;
    private Vector<RecyclerView> recyclerViewList;
    private String[] titles;

    public NewsPagerAdapter(Context context, int titlesId) {
        this.context = context;
        this.recyclerViewList = new Vector<>();

        setTitles(titlesId);
    }

    public void add(RecyclerView recyclerView) {
        recyclerViewList.add(recyclerView);
    }

    public RecyclerView.Adapter getAdapterForViewAtIndex(int index) {
        return recyclerViewList.get(index).getAdapter();
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(recyclerViewList.get(position),
                new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100)
        );
        return container;
    }

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

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles[position];
    }

    public void setTitles(int titles) {
        this.titles = context.getResources().getStringArray(titles);
    }
}

Et ma méthode onCreatView:

GridLayoutManager layoutManager1 = new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.news_column_count));

GridLayoutManager layoutManager2 = new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.news_column_count));

RecyclerView listView1 = new RecyclerView(getActivity());
RecyclerView listView2 = new RecyclerView(getActivity());
listView1.setLayoutManager(layoutManager1);
listView2.setLayoutManager(layoutManager2);

NewsAdapter adapter1 = new NewsAdapter(getActivity(), null);
NewsAdapter adapter2 = new NewsAdapter(getActivity(), null);
adapter1.setOnItemClickListener(this);
adapter2.setOnItemClickListener(this);

listView1.setAdapter(adapter1);
listView2.setAdapter(adapter2);

newsPagerAdapter.add(listView1);
newsPagerAdapter.add(listView2);

newsViewPager.setAdapter(newsPagerAdapter);

Ici, je passe l'objet curseur à l'adaptateur:

@Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        ((NewsAdapter) newsPagerAdapter.getAdapterForViewAtIndex(0)).swapCursor(data);
    }
12
tobs

Vous devez étendre FragmentPagerAdapter ou FragmentStatePagerAdapter pour intégrer facilement RecyclerView. Si vous prévoyez de mettre à jour le contenu de votre ViewPager pendant son cycle de vie, il est strictement recommandé d'utiliser FragmentStatePagerAdapter

Vous devrez créer une disposition de fragment supplémentaire, contenant RecyclerView.

Si vous souhaitez mettre à jour votre ViewPager avec SwipeRefreshLayout, ne l'enveloppez pas avec SwipeRefreshLayout. Au lieu de cela, vous devez avoir SwipeRefreshLayout à l'intérieur de la disposition des fragments.

Par conséquent, pour votre fragment, vous pouvez obtenir le xml suivant:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.SwipeRefreshLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/listRefresh"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/categoryList"
        Android:scrollbars="vertical"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>
</Android.support.v4.widget.SwipeRefreshLayout>

Et créez une classe Fragment supplémentaire, qui gonflera cette disposition et implémentera des méthodes, dont vous aurez besoin pour mettre à jour le statut de l'indicateur d'actualisation.

Un exemple un peu ancien se trouve ici: http://developer.Android.com/training/implementing-navigation/lateral.html

Si vous souhaitez connecter votre ViewPager avec la nouvelle bibliothèque de support TabLayout, il est facilement compatible avec:

tabLayout.setupWithViewPager(viewPager);

Enfin, si vous mettez à jour votre ViewPager "fragmenté", n'essayez pas de réinitialiser l'adaptateur, car les fragments sont gérés non pas avec l'adaptateur, mais avec FragmentManager. Il est plus sage de mettre à jour le contenu du RecyclerViews correspondant

public class MyFragmentedPagerAdapter extends FragmentStatePagerAdapter {
    private final TabLayout mTabLayout;
    private final SwipeRefreshLayout.OnRefreshListener mRefreshListener;
    private Vector<PriceListFragment> fragmentList;
    private Vector<String> titles;

    public MyFragmentedPagerAdapter(FragmentManager fm, MyComplexData data, OnCartActionListener listener, TabLayout tabLayout, SwipeRefreshLayout.OnRefreshListener refreshListener) {
        super(fm);
        mTabLayout = tabLayout;

        // external refresh listener, that will trigger an updateData() 
        mRefreshListener = refreshListener;

        fragmentList = new Vector<>();
        titles = new Vector<>();
        updateData(data);
    }

    public void updateData(MyComplexData data) {
        boolean updateTabs = false;
        boolean hasNewData = false;

        Vector<String> newTitles = new Vector<>();

        int position = 0;
        for(TabContents tabContents : data.getTabContents()) {

            if(tabContents.getListContents() == null)
                continue;
            hasNewData = true;
            boolean isNewFragment;

            MyFragment fragment;
            try {
                fragment = fragmentList.get(position);
                isNewFragment = false;
            } catch (ArrayIndexOutOfBoundsException e) {
                fragment = new MyFragment();
                isNewFragment = true;
            }
            // Update the data, title and hide update indicator of SwipeRefreshLayout
            fragment.setTabContents(tabContents);

            newTitles.add(tabContents.getName());

            if(isNewFragment) {
                fragment.setRefreshListener(mRefreshListener);
                fragmentList.add(fragment);
            }
            position++;
        }

        if(!hasNewData)
            return;

        // we need to decide, whether to update tabs
        if(titles.size() != newTitles.size()) {
            updateTabs = true;
        } else {
            for(position = 0; position < titles.size(); position++) {
                if(!titles.get(position).equals(newTitles.get(position))) {
                    updateTabs = true;
                    break;
                }
            }
        }

        titles = newTitles;
        notifyDataSetChanged();

        if(updateTabs)
            mTabLayout.setTabsFromPagerAdapter(this);
    }

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

    // You need to override this method as well
    @Override
    public int getItemPosition(Object object) {
        MyFragment fragment = (MyFragment) object;
        String title = (String) fragment.getTitle();
        int position = titles.indexOf(title);

        if (position >= 0) {
            return position;
        } else {
            return POSITION_NONE;
        }
    }

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

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

Votre classe MyFragment doit implémenter la méthode getTitle().

13