CardView 内的 TabLayout

Posted

技术标签:

【中文标题】CardView 内的 TabLayout【英文标题】:TabLayout Inside CardView 【发布时间】:2016-07-09 01:46:05 【问题描述】:

我正在尝试在 CardView 中创建一个 TabLayout,如下所示:

CardView 内的TabLayout

但卡在添加 ViewPager 适配器。

我按照从 this site. 制作 TabLayout 的示例进行操作

由于我使用的是RecyclerView,所以我把TabLayout和ViewPager放在了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) 

         
    );


但我在 getSupportFragmentManager 上收到“无法解析方法”。

这是 PagerAdapter 类。

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;


我使用 FirebaseRecyclerAdapter 连接到 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://***.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();


请帮我解决这个问题。谢谢。

【问题讨论】:

【参考方案1】:

这是因为您从 ViewHolder 调用它,它没有从支持库扩展 FragmentActivity,因此该方法不存在于超类中。

您可以使用 Activity 的 FragmentManager 或以其他方式将其传递给您的 ViewHolder(可能是在构造函数中设置的私有字段 private FragmentManager fm;)。

类似这样的:

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);

无论您在何处创建 ViewHolder,只需传入 FragmentManager(如 new MyViewHolder(someView, getSupportFragmentManager())),您必须从扩展 FragmentActivity 的活动中调用它,否则您无法获得 FragmentManager

然后简单地使用myFragmentManager 而不是调用方法getSupportFragmentManager() 导致这一行的问题:

final PagerAdapter adapter = new PagerAdapter
        (getSupportFragmentManager(), tabLayout.getTabCount());

【讨论】:

您能否举例说明如何实现这一目标?我试图找出如何做到这一点,但仍然卡住了。我应该在 Activity 和 ViewHolder 中添加什么?

以上是关于CardView 内的 TabLayout的主要内容,如果未能解决你的问题,请参考以下文章

CardView 内的布局重叠

Android:LinearLayout 内的 CardView 使应用程序崩溃

CardView 内的工具栏,用于创建弹出菜单(溢出图标)

为约束布局内的布局设置最小百分比高度

NestedScrollViewLayout 内的 SwipeRefreshLayout 内的 RecyclerView 无法滚动

选项卡片段内的卡片视图