ogaclejapan / SmartTabLayout

A custom ViewPager title strip which gives continuous feedback to the user when scrolling
Apache License 2.0
7.09k stars 1.34k forks source link

getPage error #2

Closed crysan closed 9 years ago

crysan commented 9 years ago

Hi! If you change the position of an element can not be found.

    ..........
    ViewPagerItems.Creator items = ViewPagerItems.with(getActivity());
    for (String type : book_type) {
        items.add(ViewPagerItem.of(type, R.layout.books_list));
    }
    adaptertab = new ViewPagerItemAdapter(items.create());

    viewPager.setAdapter(adaptertab);
    viewPagerTab.setViewPager(viewPager);

Everything works fine until it:

    viewPagerTab.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
        @Override
        public void onPageScrollStateChanged(int state) { }

        @Override
        public void onPageSelected(int position) {
            View page = adaptertab.getPage(position);
            RecyclerView cardList = (RecyclerView) page.findViewById(R.id.cardList);   // ERROR
            cardList.setHasFixedSize(true);
            GridLayoutManager llm = new GridLayoutManager(getActivity(), 3);
            cardList.setLayoutManager(llm);
            adapter = new EventsAdapter();
            cardList.setAdapter(adapter);
        }
    });

Why?

ogaclejapan commented 9 years ago

Hi @crysan

I tried a simple sample, but the error did not occur. https://gist.github.com/ogaclejapan/57173ab483e176da078b

However, I think that we should take advantage of the Fragment-based ViewPager in cases such as you want to do.

crysan commented 9 years ago

page.xml should be:

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/cardList" />

ogaclejapan commented 9 years ago

Hi @crysan

The sample was modified to work with RecyclerView. https://gist.github.com/ogaclejapan/57173ab483e176da078b

RecyclerView error occurs when not initialized at the generation of view.


java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$LayoutManager.canScrollHorizontally()' on a null object reference

So, you need to'll initialized at the time of view generation by inheriting the ViewPagerItem.


        @Override
        public View initiate(LayoutInflater inflater, ViewGroup container) {
            View page = super.initiate(inflater, container);

            RecyclerView cardList = (RecyclerView) page.findViewById(R.id.cardList);
            cardList.setHasFixedSize(true);
            GridLayoutManager llm = new GridLayoutManager(page.getContext(), 3);
            cardList.setLayoutManager(llm);

            return page;
        }

http://stackoverflow.com/questions/27416834/app-crashing-when-trying-to-use-recyclerview-on-android-5-0

crysan commented 9 years ago

Give an example for public class MainFragment extends Fragment

ogaclejapan commented 9 years ago

See demo :+1: Demo app uses the Fragment-based PagerAdapter :)

crysan commented 9 years ago

Your example of the simplest case, and unfortunately, my case is not applicable. See, I have a basic Activity, which is replaced by a fragment of View. Further, in this passage is set SmartTabLayout, in which each tab I also call fragment containing RecyclerView. Each time you select a tab element SmartTabLayout I have to fill RecyclerView data from the database. Here's an my example:

public class AuthorFragment extends Fragment {

MyFunctions func;
Realm realm;
DBfunctions db;

Authors author;

ViewPagerItemAdapter adaptertab;
String author_url;

@InjectView(R.id.cardList) RecyclerView cardList;
@InjectView(R.id.viewpager) ViewPager viewPager;
@InjectView(R.id.viewpagertab) SmartTabLayout viewPagerTab;

public AuthorFragment() { }

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    func = new MyFunctions(getActivity());
    realm = Realm.getInstance(getActivity());
    db = new DBfunctions(realm);

    author_url = getArguments().getString("author_url", "");
}

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_author, container, false);
    page = inflater.inflate(R.layout.books_list, container, false);

    author = realm.where(Authors.class).equalTo("url_base", author_url).findFirst();
    final ArrayList<String> book_type = new <String>ArrayList();
    for (Books book : author.getBooks()) {
        book_type.add(book.getBook_type());
    }
    HashSet hs = new HashSet();
    hs.addAll(book_type);
    book_type.clear();
    book_type.addAll(hs);
    Collections.sort(book_type);

    viewPager = (ViewPager) v.findViewById(R.id.viewpager);
    viewPagerTab = (SmartTabLayout) v.findViewById(R.id.viewpagertab);

    ViewPagerItems.Creator items = ViewPagerItems.with(getActivity());
    for (String type : book_type) {
        items.add(ViewPagerItem.of(type, R.layout.books_list));
    }
    adaptertab = new ViewPagerItemAdapter(items.create());

    viewPager.setAdapter(adaptertab);
    viewPagerTab.setViewPager(viewPager);
    viewPagerTab.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
        @Override
        public void onPageScrollStateChanged(int state) { }

        @Override
        public void onPageSelected(int position) {
            View page = adapter.getPage(position);
            RecyclerView cardList = (RecyclerView) page.findViewById(R.id.cardList);   ---- ERROR ----
            cardList.setHasFixedSize(true);
            GridLayoutManager llm = new GridLayoutManager(page.getContext(), 3);
            cardList.setLayoutManager(llm);
        }
    });

    return v;
}

fragment_author.xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent">

<com.ogaclejapan.smarttablayout.SmartTabLayout
    android:id="@+id/viewpagertab"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:background="@color/toast_default"
    app:stl_indicatorAlwaysInCenter="false"
    app:stl_indicatorInFront="false"
    app:stl_indicatorInterpolation="smart"
    app:stl_indicatorColor="#40C4FF"
    app:stl_indicatorThickness="4dp"
    app:stl_indicatorCornerRadius="2dp"
    app:stl_underlineColor="#4D000000"
    app:stl_underlineThickness="1dp"
    app:stl_dividerColor="#00000000"
    app:stl_dividerThickness="100dp"
    app:stl_defaultTabTextColor="#FC000000"
    app:stl_defaultTabTextSize="12sp"
    app:stl_defaultTabTextHorizontalPadding="16dp"
    app:stl_defaultTabTextMinWidth="0dp"
    app:stl_distributeEvenly="false" />

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/viewpagertab" />

books_list.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/cardList"
    android:layout_marginLeft="12dp"
    android:layout_marginRight="12dp"
    android:layout_marginTop="16dp"/>

ogaclejapan commented 9 years ago

Hi @crysan

Why not use the ViewPager of Fragment? You should use the Fragment-based Adapter.


//Activity:

    FragmentPagerItemAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewpager_with_tab);

        List<String> book_type = new ArrayList<>();

        //load books

        FragmentPagerItems items = new FragmentPagerItems(this);
        for (String type : book_type) {
            Bundle args = new Bundler().putString("book_type", type).get();
            items.add(FragmentPagerItem.of(type, BookListFragment.class, args));
        }

        mAdapter = new FragmentPagerItemAdapter(getSupportFragmentManager(), items);

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);

        viewPager.setAdapter(mAdapter);
        viewPagerTab.setViewPager(viewPager);
        viewPagerTab.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                Fragment f = mAdapter.getPage(position);
                if (f instanceof BookListFragment) {
                    ((BookListFragment)f).update();
                }
            }
        });

}

//BookListFragment

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.books_list, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        RecyclerView cardList = (RecyclerView) view.findViewById(R.id.cardList);
        cardList.setHasFixedSize(true);
        GridLayoutManager llm = new GridLayoutManager(page.getContext(), 3);
        cardList.setLayoutManager(llm);

        //...

    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        update();
    }

    public void update() {
        //load data of booktype
    }

This is not a library side issue. This is the implementation side issues. I wish you the best. :+1:

crysan commented 9 years ago

Thank you! Everything turned out!