6

I am trying to make a TabLayout inside CardView, something like this:

TabLayout Inside CardView

enter image description here

but stuck in adding ViewPager adapter.

I followed the example on making the TabLayout from this site.

Since I use RecyclerView, I put the TabLayout and ViewPager in myViewHolder

public class MyViewHolder extends RecyclerView.ViewHolder {

TabLayout tabLayout;

public MyViewHolder(View itemView) {
    super(itemView);        

    tabLayout = (TabLayout) itemView.findViewById(R.id.tab_layout);
    tabLayout.addTab(tabLayout.newTab().setText("TAB 1"));
    tabLayout.addTab(tabLayout.newTab().setText("TAB 2"));
    tabLayout.addTab(tabLayout.newTab().setText("TAB 3"));
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);


    final ViewPager viewPager = (ViewPager) itemView.findViewById(R.id.pager);
    final PagerAdapter adapter = new PagerAdapter
            (getSupportFragmentManager(), tabLayout.getTabCount());
    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

         }
    });
}
}

But I get 'Cannot resolve method' on getSupportFragmentManager.

This is the PagerAdapter class.

public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;

public PagerAdapter(FragmentManager fm, int NumOfTabs) {
    super(fm);
    this.mNumOfTabs = NumOfTabs;
}

@Override
public Fragment getItem(int position) {

    switch (position) {
        case 0:
            Fragment1 tab1 = new Fragment1();
            return tab1;
        case 1:
            Fragment2 tab2 = new Fragment2();
            return tab2;
        case 2:
            Fragment3 tab3 = new Fragment3();
            return tab3;
        default:
            return null;
    }
}

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

I use FirebaseRecyclerAdapter to connect to Firebase

public abstract class FirebaseRecyclerAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {

Class<T> mModelClass;
protected int mModelLayout;
Class<VH> mViewHolderClass;
FirebaseArray mSnapshots;

ArrayList<HashMap<String, String>> dataList;

public FirebaseRecyclerAdapter(Class<T> modelClass, int modelLayout, Class<VH> viewHolderClass, Query ref) {
    mModelClass = modelClass;
    mModelLayout = modelLayout;
    mViewHolderClass = viewHolderClass;
    mSnapshots = new FirebaseArray(ref);

    mSnapshots.setOnChangedListener(new FirebaseArray.OnChangedListener() {
        @Override
        public void onChanged(EventType type, int index, int oldIndex) {
            switch (type) {
                case Added:
                    notifyItemInserted(index);
                    break;
                case Changed:
                    notifyItemChanged(index);
                    break;
                case Removed:
                    notifyItemRemoved(index);
                    break;
                case Moved:
                    notifyItemMoved(oldIndex, index);
                    break;
                default:
                    throw new IllegalStateException("Incomplete case statement");
            }
        }
    });
}

public FirebaseRecyclerAdapter(Class<T> modelClass, int modelLayout, Class<VH> viewHolderClass, Firebase ref) {
    this(modelClass, modelLayout, viewHolderClass, (Query) ref);
}

public void cleanup() {
    mSnapshots.cleanup();
}

@Override
public int getItemCount() {
    return mSnapshots.getCount();
}

public T getItem(int position) {
    return parseSnapshot(mSnapshots.getItem(position));
}

protected T parseSnapshot(DataSnapshot snapshot) {
    return snapshot.getValue(mModelClass);
}

public Firebase getRef(int position) { return mSnapshots.getItem(position).getRef(); }

@Override
public long getItemId(int position) {
    // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter
    return mSnapshots.getItem(position).getKey().hashCode();
}

@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
    ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(mModelLayout, parent, false);
    try {
        Constructor<VH> constructor = mViewHolderClass.getConstructor(View.class);
        return constructor.newInstance(view);
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
        System.out.println("cause: "+ e.getCause());
        throw new RuntimeException(e);
    } catch (InstantiationException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}
@Override
public void onBindViewHolder(VH viewHolder, int position) {
    T model = getItem(position);
    populateViewHolder(viewHolder, model, position);

}
abstract protected void populateViewHolder(VH viewHolder, T model, int position);

public void setFilter(ArrayList<HashMap<String, String>> countryModels) {
    dataList = new ArrayList<>();
    dataList.addAll(countryModels);
    notifyDataSetChanged();
}
}

Please help me resolve this issue. Thank you.

Kristiyan Varbanov
  • 2,439
  • 2
  • 17
  • 37
subcom
  • 61
  • 3

1 Answers1

0

This is because you're calling it from your ViewHolder which doesn't extend FragmentActivity from the support library, and therefore the method is not present in the superclass.

You can use the Activity's FragmentManager or pass it some other way to your ViewHolder (maybe as it's private field private FragmentManager fm; which is set in the constructor).

Something like this:

public class MyViewHolder extends RecyclerView.ViewHolder {

TabLayout tabLayout;
FragmentManager myFragmentManager; //beware that it's the FragmentManager from the support library

public MyViewHolder(View itemView, FragmentManager fm) {
    this.myFragmentManager = fm;
    super(itemView);

And wherever you're creating the ViewHolder just pass in the FragmentManager like new MyViewHolder(someView, getSupportFragmentManager()) and you must call this from the activity which extends FragmentActivity otherwise you cannot get the FragmentManager.

And then simply use myFragmentManager instead of calling the method getSupportFragmentManager() which causes the problem in this line:

final PagerAdapter adapter = new PagerAdapter
        (getSupportFragmentManager(), tabLayout.getTabCount());
Vucko
  • 7,371
  • 2
  • 27
  • 45
  • Could you please give example on how to achieve this? I've tried to find out on how to do this but still stuck. What should I add in the Activity and in the ViewHolder? – subcom Mar 24 '16 at 04:34