CoordinatorLayout+ViewPager+RecyclerView+自定义TabLayout布局

本文详细介绍了一种基于CoordinatorLayout、ViewPager、RecyclerView和自定义TabLayout的安卓布局方案,通过实例解析了各组件的配置与交互,包括整体布局设计、ViewPager与Fragment结合使用、自定义TabLayout的实现等关键步骤。
摘要由CSDN通过智能技术生成

首先看看效果确定是不是你想要的:

如果效果是你想要的,那就接着往下看吧,我会一一介绍

(1)整体布局:

布局采用CoordinatorLayout+ViewPager+RecyclerView+自定义TabLayout实现,其中CoordinatorLayout为可上下滚动部分,ViewPager作为左右切换部分,tablayout作为标签部分

先给出整体布局的xml代码:

<android.support.design.widget.CoordinatorLayout
    android:layout_below="@+id/rel_home"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <LinearLayout
            android:id="@+id/ll_banner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dp12"
            android:layout_marginTop="@dimen/dp12"
            android:layout_marginRight="@dimen/dp12"
            app:layout_scrollFlags="scroll">

            <com.bigkoo.convenientbanner.ConvenientBanner
                android:id="@+id/convenient_banner"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp104"
                app:canLoop="true" />
        </LinearLayout>

        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout"
            android:layout_width="match_parent"
            app:tabMaxWidth="@dimen/dp84"
            android:layout_height="@dimen/dp34"
            style="@style/aliwx_column_third_grade_with_click_style"
            app:tabPaddingEnd="0dp"
            app:tabPaddingStart="@dimen/dp0"
            android:layout_marginBottom="@dimen/dp12"
            android:layout_marginLeft="@dimen/dp12"
            android:layout_marginRight="@dimen/dp12"
            app:tabIndicatorHeight="0dp"
            android:layout_marginTop="@dimen/dp12"
            android:background="@drawable/iv_homefragment_label" />
        <!--</LinearLayout>-->
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_marginLeft="@dimen/dp12"
        android:layout_marginRight="@dimen/dp12"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

布局可见,CoordinatorLayout为滚动部分的整体布局,甚至可看做行为可控制的ScrollView。

AppBarLayout作为悬浮窗口,什么地方要悬浮就在此ViewGroup里面写布局,而需要注意的是标红部分app:layout_scrollFlags="scroll" 其中值有五种,具体差异可在这篇博客中看到:https://www.jianshu.com/p/7caa5f4f49bd

此处的意思是其ChildView跟随滚动事件移除屏幕外或移进。

app:layout_behavior="@string/appbar_scrolling_view_behavior"指定了ViewPager的滚动行为

当总体布局写成这样就能基本实现框架了,接下来将各部分关联起来

(2)ViewPager部分

viewpager这里设计的是使用viewpager+fragment+recyclerview的方式是实现。

首先viewpager与tablayout绑定就很简单的一句话:mTablayout.setupWithViewPager(mViewpager);

这样的话。viewpager与tablayout的行为就实现了绑定,具体内容填充后面会介绍到

接着viewpager的部分,首先是viewpager的适配器,此处使用FragmentPagerAdapter:

public class HomeViewPagerAdapter extends FragmentPagerAdapter {
    private List<HomeLabelsEntity.LabelsListBean> mLabelsListBeanList;
    private Context mContext;
    private List<ViewPagerFragment> mViewPagerFragments;
    FragmentManager fM;
    public HomeViewPagerAdapter(Context context,FragmentManager fm, List<HomeLabelsEntity.LabelsListBean> labelsListBeanList) {
        super(fm);
        fM = fm;
        mContext=context;
        mLabelsListBeanList=labelsListBeanList;
        mViewPagerFragments=new ArrayList<>();
    }

    @Override
    public Fragment getItem(int position) {
        ViewPagerFragment fragment = new ViewPagerFragment();
        Bundle bundle=new Bundle();
        bundle.putParcelable("data",mLabelsListBeanList.get(position));
        fragment.setArguments(bundle);
        return fragment;
    }
    public void notifData( List<HomeLabelsEntity.LabelsListBean> labelsListBeanList){
        mLabelsListBeanList=labelsListBeanList;
        notifyDataSetChanged();
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ViewPagerFragment fragment = (ViewPagerFragment)super.instantiateItem(container,
                position);
        FragmentTransaction ft =fM.beginTransaction();
        String fragmentTag = fragment.getTag();
        ft.remove(fragment);
        fragment = new ViewPagerFragment();
        Bundle bundle=new Bundle();
        bundle.putParcelable("data",mLabelsListBeanList.get(position));
        fragment.setArguments(bundle);
        ft.add(container.getId(), fragment, fragmentTag);
        ft.attach(fragment);
        ft.commitAllowingStateLoss();
        return fragment;
    }



    @Override
    public int getCount() {
        return mLabelsListBeanList==null?0:mLabelsListBeanList.size();
    }

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

此处需要注意的就是两个标红方法的重载,getItem当Viewpager创建新界面的时候启用,instantiateItem是当前界面渲染的时候使用,因为我写的效果里面需要切换城市,要刷新Viewpager的状态与数据,所以需要使用到instantiateItem,没有这个需求的,getItem就能够实现。此处使用的是传参方式将数据传递到new出来的fragment。至于fragment部分就拿到数据,展示到recyclerview里面,这里就不做说明了。

(3)自定义tablayout

首先说明如果是纯文字的tablayout只需要在viewpager的adapter中加上

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

tagStringList即为标签文字集合

而如果采用自定义tablayout的话就需要在绑定之后进行布局的渲染:

  //此处设置tablayout的内容
    for (int i = 0; i < mLabelsListBeanLists.size(); i++) {
        TabLayout.Tab tabAt = mHomePageChangeFragmentView.getTabLayout().getTabAt(i);
        View view= LayoutInflater.from(mContext).inflate(R.layout.item_recycler_home,null);
        if (i==mLabelsListBeanLists.size()-1){
            //最后一个不显示箭头
            view.findViewById(R.id.iv_cutline).setVisibility(View.GONE);
        }else{
            view.findViewById(R.id.iv_cutline).setVisibility(View.VISIBLE);
        }
        ((TextView)view.findViewById(R.id.tv_selected)).setText(mLabelsListBeanLists.get(i).getName());
        ((TextView)view.findViewById(R.id.tv_unselect)).setText(mLabelsListBeanLists.get(i).getName());
        if (i==0){
            //第一个默认设置被选中
            view.findViewById(R.id.llyout_selected).setVisibility(View.VISIBLE);
            view.findViewById(R.id.tv_unselect).setVisibility(View.INVISIBLE);
        }else{
            //其他设置为不选中状态
            view.findViewById(R.id.llyout_selected).setVisibility(View.INVISIBLE);
            view.findViewById(R.id.tv_unselect).setVisibility(View.VISIBLE);
        }
        tabAt.setCustomView(view);
    }
    mHomePageChangeFragmentView.getTabLayout().addOnTabSelectedListener(this);
}

如代码所示,在tablayout绑定viewpager后,填充tablayout的布局,并处理事件,处理事件采用监听

@Override
public void onTabSelected(TabLayout.Tab tab) {
    if (tab!=null&&tab.getCustomView()!=null){
        tab.getCustomView().findViewById(R.id.llyout_selected).setVisibility(View.VISIBLE);
        tab.getCustomView().findViewById(R.id.tv_unselect).setVisibility(View.INVISIBLE);
    }
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
    if (tab!=null&&tab.getCustomView()!=null){
        tab.getCustomView().findViewById(R.id.llyout_selected).setVisibility(View.INVISIBLE);
        tab.getCustomView().findViewById(R.id.tv_unselect).setVisibility(View.VISIBLE);
    }
}

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

}

而此处说一说自己踩的坑,首先tablayout的子布局tabitem宽度,并不是根据你设置的宽度进行渲染的,它会在计算的时候进行重新计算,类似于LinearLayout子布局中加android:layout_weight=""的效果,平分tablayout的宽度,想要自行设置宽度的话,在tablyout中设置属性app:tabMaxWidth="@dimen/dp84"即可,然后tabitem自带padding,所以发现自己布局不对的话,设置其属性

app:tabPaddingEnd="0dp"
app:tabPaddingStart="@dimen/dp0"

而想要设置没有下划线则设置,app:tabIndicatorHeight="0dp",此处不再多做赘述,因为属性有点多,具体的根据想要实现的效果填充即可

 

本篇博客到此结束,感谢观看。

如有不对,请指正。

因为此效果是在项目中, 所以不太好传源码,见谅!

好的,下面是一个使用TabLayout+ViewPager+Fragmet+RecyclerView结合的小demo的示例代码。 1. 首先,在xml文件中添加TabLayout和ViewPager组件。 ```xml <android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 创建Fragment类,用于展示RecyclerView数据。 ```java public class SimpleFragment extends Fragment { private RecyclerView recyclerView; private SimpleAdapter adapter; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_simple, container, false); recyclerView = view.findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); adapter = new SimpleAdapter(); recyclerView.setAdapter(adapter); return view; } } ``` 3. 创建FragmentPagerAdapter类,用于管理Fragment。 ```java public class SimplePagerAdapter extends FragmentPagerAdapter { private String[] titles; public SimplePagerAdapter(FragmentManager fm, String[] titles) { super(fm); this.titles = titles; } @Override public Fragment getItem(int position) { return new SimpleFragment(); } @Override public int getCount() { return titles.length; } @Nullable @Override public CharSequence getPageTitle(int position) { return titles[position]; } } ``` 4. 创建RecyclerView Adapter类,用于展示数据。 ```java public class SimpleAdapter extends RecyclerView.Adapter<SimpleViewHolder> { private List<String> data; public SimpleAdapter() { data = new ArrayList<>(); for (int i = 0; i < 20; i++) { data.add("Item " + i); } } @NonNull @Override public SimpleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_simple, parent, false); return new SimpleViewHolder(view); } @Override public void onBindViewHolder(@NonNull SimpleViewHolder holder, int position) { holder.textView.setText(data.get(position)); } @Override public int getItemCount() { return data.size(); } } ``` 5. 创建RecyclerView ViewHolder类,用于展示每个item。 ```java public class SimpleViewHolder extends RecyclerView.ViewHolder { public TextView textView; public SimpleViewHolder(View itemView) { super(itemView); textView = itemView.findViewById(R.id.text_view); } } ``` 6. 最后,在Activity中进行初始化和设置。 ```java public class MainActivity extends AppCompatActivity { private TabLayout tabLayout; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tabLayout = findViewById(R.id.tab_layout); viewPager = findViewById(R.id.view_pager); String[] titles = {"Tab 1", "Tab 2", "Tab 3"}; SimplePagerAdapter adapter = new SimplePagerAdapter(getSupportFragmentManager(), titles); viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); } } ``` 这样就完成了TabLayout+ViewPager+Fragmet+RecyclerView结合的小demo。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值