TabLayout+ViewPager+Fragment(懒加载)实现导航栏

Android Material Design 系列之 TabLayout + ViewPager + Fragment 使用详解 前言 本文是 Material Design 系列第三篇:TabLayout + ViewPager + Fragment 基本使用,Material Design 所有控件属于高级 UI,所以 Material Design 控件是中高级工程师必备技能。现在市面上很多主流界面效果都是采用 Material Design 风格控件完成。希望博主 Material Design 系列文章对各位初学者有所帮助,也为自己学习做详细笔记。 一、TabLayout 方法介绍 1、addTab(TabLayout.T 阅读详情

之前,实现导航栏的效果有很多方法,使用第三方库,比如ViewPagerIndicator中的TabPagerIndicator,谷歌可能发现,导航栏使用的挺普遍的,so,也搞了一个属于自己的导航栏!就像侧滑菜单一样,也搞了一个属于自己的侧滑菜单DrawerLayout!

效果图是这样的:

这里写图片描述

跟ViewPagerIndicator实现的效果是一样的!

接下来看代码:

首先呢!需要compile一下:

compile 'com.android.support:design:25.3.1'

然后TabLayout就跟普通控件使用一样了!直接在xml里设置即可,代码如下:

<android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            app:tabIndicatorColor="#ff0000"
            app:tabSelectedTextColor="#ff0000"
            app:tabTextColor="#cccccc"
            app:tabMode="scrollable"/>

属性说明:

app:tabIndicatorColor:指示器那条下划线的颜色
app:tabTextColor:上面文本颜色
app:tabSelectedTextColor:文本被选中后的颜色
app:tabMode="scrollable" 适用于多文本的滑动

当然,还有一些别的属性,比如设置指示器下划线的粗细等等。

接下来就是HomeActivity的代码:

public class HomeActivity extends FragmentActivity implements View.OnClickListener{
    private ViewPager viewpager;
    private TabLayout layout;
    private DrawerLayout leftMenu;
    private ImageView touxiang;
    private List<String> titles = new ArrayList<>();
    private List<Fragment> fragments = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        initView();
        initData();
        viewpager.setAdapter(new PagerAdapter(getSupportFragmentManager(),titles,fragments));
        layout.setupWithViewPager(viewpager);//将导航栏和viewpager进行关联
        layout.addOnTabSelectedListener(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) {

            }
        });
    }

    private void initData() {
        titles.add("推荐");
        titles.add("热点");
        titles.add("美女");
        titles.add("军事");
        titles.add("数码");
        titles.add("体育");
        titles.add("汽车");
        fragments.add(new TuiJianFragment());
        fragments.add(new ReDianFragment());
        fragments.add(new BeautyFragment());
        fragments.add(new JunShiFragment());
        fragments.add(new ShuMaFragment());
        fragments.add(new SportFragment());
        fragments.add(new CarFragment());
    }

    private void initView() {
        viewpager = (ViewPager) findViewById(R.id.viewpager);
        touxiang = (ImageView) findViewById(R.id.touxiang);
        layout = (TabLayout) findViewById(R.id.title);
        leftMenu = (DrawerLayout) findViewById(R.id.left_menu);
        touxiang.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        leftMenu.openDrawer(GravityCompat.START);//打开侧滑菜单
    }
}

适配器:

public class PagerAdapter extends FragmentPagerAdapter {
    private List<String> titles;
    private List<Fragment> fragments;

    public PagerAdapter(FragmentManager fm, List<String> titles,List<Fragment> fragments) {
        super(fm);
        this.titles = titles;
        this.fragments = fragments;
    }

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

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

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

搞定!
————————————————————————————————————————————————————————————————
更多属性:

app:tabBackground="color"//整个TabLayout的颜色,这里不能直接写RGB,需要@color/xx

app:tabTextAppearance="@android:style/TextAppearance.Holo.Large"//设置文字的外貌大小

app:tabIndicatorHeight="2dp"//设置指示器下划线粗细,如果设置成0dp,则不显示指示器

app:tabMode="scrollable"//默认是fixed:固定的,标签很多时候会被挤压,不能滑动。

app:tabGravity="center"//居中,如果是fill,则是充满

默认选中某项这样设置:

tablayout.getTabAt(position).select();

————————————————————————————————————————————————————
PS:通常遇到这种组合,也需要实现Fragment懒加载,因为涉及到ViewPager的预加载特性,会预加载当前Fragment的前一个和后一个Fragment的数据。我们要实现的效果就是只有当点击该Fragment的时候,再去请求网络数据,禁用掉ViewPager的预加载特性,这样就节省很多开销。
可以让Fragment继承如下的BaseFragment:

public abstract class BaseFragment extends Fragment {
    protected boolean isInit;
    protected boolean isReallyLazy;//是否完全懒加载

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(setLayoutResourceID(), container, false);
        init();
        isInit = true;
        isCanLoadData();
        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isCanLoadData();
    }

    private void isCanLoadData() {
        //isReallyLazy为true实现完全懒加载,Fragment只会加载一次,再切回来的时候,不会加载,去掉该属性的话,再切回来的时候会重新加载
        if (getUserVisibleHint() && isInit && !isReallyLazy) {
            getData();
            isReallyLazy = true;
        }
    }

    protected abstract int setLayoutResourceID();

    protected abstract void init();

    protected abstract void getData();

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isInit = false;
    }
}

这样就可以将一进入该Fragment加载网络数据的方法,或者是切换回该Fragment需要刷新数据的方法都放在上面的方法里了。
————————————————————————————————————————————————————————————
下面再实现一种案例。项目中有时会用到,就是Tab选项添加图片,可以随意控制图片在Tab中的位置。效果图大概如下:
这里写图片描述
左右滑动,可以改变字体颜色和图片。
核心代码:适配器getPageTitle返回null即可,然后增加一个自定义样式的方法:

public View getTabView(int position) {
        View view = LayoutInflater.from(context).inflate(R.layout.tab_item, null);
        TextView tab_title = view.findViewById(R.id.tab_title);
        tab_title.setText(titles.get(position));
        ImageView img = view.findViewById(R.id.tab_icon);
        if (position == 0) {
            tab_title.setTextColor(Color.RED);
            img.setImageResource(R.drawable.icon_selected);
        }
        if (position == 1) {
            tab_title.setTextColor(Color.GRAY);
            img.setImageResource(R.drawable.flower_unselected);
        }
        if (position == 2) {
            tab_title.setTextColor(Color.GRAY);
            img.setImageResource(R.drawable.coin_unselected);
        }
        return view;
    }

其中的tab_item布局就是随便定义文字和图片的摆放位置。这里我是将图片放在文字的右侧:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:orientation="horizontal"
        android:gravity="center">
        <TextView
            android:id="@+id/tab_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <ImageView
            android:id="@+id/tab_icon"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:layout_marginLeft="4dp" />
    </LinearLayout>
</LinearLayout>

最后Activity中进行设置:
在tabLayout.setupWithViewPager(viewPager)之后添加动态Tab内容

for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(pagerAdapter.getTabView(i));
        }

然后TabLayout的滑动监听,动态改变文字颜色和图片即可:

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
                View view = tab.getCustomView();
                ((TextView)(view.findViewById(R.id.tab_title))).setTextColor(Color.RED);
                ImageView imageView = view.findViewById(R.id.tab_icon);
                switch (tab.getPosition()){
                    case 0:
                        imageView.setImageResource(R.drawable.icon_selected);
                        break;
                    case 1:
                        imageView.setImageResource(R.drawable.flower_selected);
                        break;
                    case 2:
                        imageView.setImageResource(R.drawable.coin_selected);
                        break;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                View view = tab.getCustomView();
                ((TextView)(view.findViewById(R.id.tab_title))).setTextColor(Color.GRAY);
                ImageView imageView = view.findViewById(R.id.tab_icon);
                switch (tab.getPosition()){
                    case 0:
                        imageView.setImageResource(R.drawable.icon_unselected);
                        break;
                    case 1:
                        imageView.setImageResource(R.drawable.flower_unselected);
                        break;
                    case 2:
                        imageView.setImageResource(R.drawable.coin_unselected);
                        break;
                }
            }

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

            }
        });
不止于滑动:用ViewPager+Fragment实现App引导页与主页Tab的实战踩坑记录 本文详细介绍了如何使用ViewPager和Fragment实现App引导页与主页Tab的实战经验,包括基础架构搭建、指示器与动画增强、与BottomNavigationView的深度集成、Fragment生命周期管理、状态保存与恢复以及性能优化方案。通过ViewPager2和FragmentStateAdapter的组合,开发者可以高效实现页面滑动和切换功能,提升用户体验和应用性能。 阅读详情

相关推荐

Android fragment使用时生命周期分析

最近在学习Fragment,顺便记录一下Fragment的生命周期,方便以后的使用 1、add和replace的区别 add:只在第一次加载的时候新建对象,后续都是复用之前的对象,只会回调onHiddenChanged方法,判断是否是当前展示的fragment replace:每次替换的时候都是将之前的fragment关闭,调用onStop、onDestroy方法,然后新展示的fragment开始初始化方法 2、TabLayout+ViewPager+fragment 使用TabLayout+ViewP

明天的增加的博客 633

TabLayout + ViewPager + Fragment 实现方式总结

应用内加个Tab实现左右滑动,已经是司空见惯,也有很多大佬进行了各种封装,(纯粹是做一下记录证明周末没有躺尸)。 首先是Android原生的TabLayout和ViewPager。 可参考APITabLayout 实现方式1 TabLayout + ViewPager + Fragment 1.两个Adapter的选用。 (一)FragmentPage...

Super 含 的博客 1768

Android导航栏设计实例:TabLayout+ViewPager+Fragment

本篇文章将介绍如何使用TabLayout、ViewPager和Fragment来实现一个漂亮且功能强大的导航栏效果。每个Fragment都有自己的生命周期和布局文件,可以在Activity中嵌入多个Fragment来构建复杂的界面。本文介绍了如何使用TabLayout、ViewPager和Fragment来实现Android应用程序中的导航栏效果。以上就是使用TabLayout、ViewPager和Fragment实现Android导航栏效果的详细步骤和相应的源代码。2.3 创建Fragment。

2301_79331328的博客 629

TabLayout+ViewPager+Fragment实现切页展示

写在前面 目前大多数的APP都采用的是几个Tab标签以及多个界面滑动的形式来提供多层次的交互体验,最为常用的做法就是采用TabLayout+ViewPager+Fragment的方式,最近在公司项目中遇到类似的界面,也看了各个论坛很多份博客,但是发现都没有完全把这种方法的坑填完,因此写下这篇博客,一方面是对知识的总结,另一方面也能让其他开发者们少走一些弯路,博客内容主要分为四个方面: T...

yourzeromax的博客 6万+

Android平台简易版QQ应用开发实战项目

想搞点炫酷的翻页效果?用分分钟实现:支持淡入淡出、3D旋转、景深等多种风格,随便挑。在Adapter末尾插入特殊类型的Footer:布局里放个ProgressBar加文字提示,用户一看就知道还在加载。这个“简易版QQ”项目看似简单,实则涵盖了Android开发中的绝大多数核心知识点:UI架构设计组件通信性能优化数据持久化异常处理更重要的是,它教会我们一个道理:优秀的用户体验,藏在每一个细节之中。

weixin_35811662的博客 724

手把手教你用gmid方法设计二级运放:从理论到仿真全流程(附避坑指南)

本文详细介绍了使用gmid方法设计二级运放的全流程,从理论到仿真实践,特别针对初学者常见问题提供避坑指南。通过系统化的晶体管尺寸确定技术,帮助工程师在性能、功耗和面积之间找到最佳平衡点,适用于模拟集成电路设计中的关键模块开发。

weixin_29213525的博客 272

Android 导航条效果实现(六) TabLayout+ViewPager+Fragment

TabLayout一、继承结构public class TabLayout extends HorizontalScrollView 二、TabLayout的使用 1、TabLayout简单使用 TabLayout来自design兼容包,使用需要添加依赖。android studio 添加依赖如下:

NoOneCode的博客 3万+

Android11,无障碍服务模拟多手势使用dispatchGesture时总是onCancelled

AccessibilityService的dispatchGesture去模拟多手势,总是onCancelled的一种解决办法

m0_49953943的博客 2102

TabLayout+ViewPager+Fragment实现懒加载

在开发中经常用到TabLayout+ViewPager+Fragment的组合。如下图所示:首先介绍一下使用方法:xml文件1 2 3 4 5 6 7 8 9 10 11 12 13 14 <android.support.design.widget.TabLayout android:id="@+id/tab_layout" andr

zhengyongbo的博客 631

MAC 青花瓷(Charles)爪机HTTPS 抓包

前段时间跟之前的产品小姐姐聊天,小姐姐说开发让她抓包帮忙看下数据,然而自己又不会,那就来写一篇简易版的教程 冲冲冲! 手上只有mac电脑跟iPhone手机,只做苹果手机的抓包,android7.0以上版本也没法通过正常的抓htts的包,让安卓开发装个后门吧,不是安卓开发并不知道是啥,连上USB之后访问chrome://inspect/#devices就能很简单的抓包 一、准备工具等 青花瓷...

Promise的博客 1615

BrepNet实战:5分钟搞定三维CAD模型的加工特征识别(附Python代码)

本文详细介绍了BrepNet在三维CAD模型加工特征识别中的实战应用,通过Python代码演示了从环境搭建到模型训练的全流程。BrepNet基于边界表示(BRep)的深度学习框架,能够高效识别加工特征,显著提升工业设计和智能制造领域的效率。文章还提供了性能优化和部署建议,帮助开发者快速实现AI驱动的几何特征识别。

weixin_29044713的博客 508

Android底部导航栏标签切换: ToolBar+TabLayout+ViewPager+Fragment

本文主要讲述实现以及Fragment切换之间如何优化,减少内存的开销,相信不少朋友吃过Fragment生命周期的亏。话不多说,切入正题。 1、结合ToolBarTabLayout+ViewPager+Fragment实现的底部导航功能 效果 与 分析 效果图如下,一般的手机应用首页就是这种样式,包括手机淘宝、QQ、微信。 我的主页 QQ 下面是新版QQ的界面,底部的导航栏实现的是切...

Xu_JL1997的博客 1560

Openclaw错误排查及解决方案之:Something went wrong while processing your request. Please try again.

Openclaw错误排查及解决方案之:Something went wrong while processing your request. Please try again.

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 3788

Android 基于TabLayout + ViewPager2 + Fragment + 角标 实现底部导航栏(升级版)

TabLayout + ViewPager2 + Fragment + 角标 实现底部导航栏

weixin_41782226的博客 2887

MIPI D-PHY的校准测试

MIPI的校准测试困扰了很久,今天终于得以解决!

一只豌豆象的博客 3919

【K8S系列】Kubernetes Pod节点CrashLoopBackOff 状态及解决方案详解【已解决】

在 Kubernetes 中,Pod 的状态为 **`CrashLoopBackOff`** 表示某个容器在启动后崩溃,Kubernetes > 尝试重启该容器,但由于持续崩溃,重启的间隔时间逐渐增加。下面将详细介绍 `CrashLoopBackOff > `状态的原因、解决方案及相关命令的输出解释。

颜淡慕潇 8381

[Android开发] Fragment的子Fragment+TabLayout+ViewPager 的使用

Android Fragment的子Fragment+TabLayout+ViewPager 的使用 文章目录Android Fragment的子Fragment+TabLayout+ViewPager 的使用1 思路分析2 具体实现2.1 Activity 中 Fragment+ViewPager 的使用2.2 Fragment 中子Fragment+TabLayout+ViewPager的使用...

龙王院的博客 1008

『Apisix进阶(九)』基于Upstream实现服务转发的最佳实践

本篇文章将以服务转发为核心,带你从原理到实战,深入了解 Upstream 的配置方法与常用场景。

老陈聊架构 1515

Tablayout + Fragment + ViewPager的懒加载实现

Android Tablayout + Fragment + ViewPager的懒加载实现 结合收藏 https://blog.youkuaiyun.com/qq2247064190/article/details/104518119 加 https://my.oschina.net/zhongsm/blog/3136312

u014105655的博客 355

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

FrameLayout+RadioGroup做导航栏(不适用Viewpager+Fragment+tablayout)

这里给大家说一下 我们在做导航栏的时候 我们用到的是add 和show 以及 hide 这些方法呢是在我们做导航栏的时候用到的比较多 这个方法每次切换页面的时候 页面不会重新加载适用于多次使用碎片场景 还有一种是将我们的add换成我们的replace replece这个方法呢每次切换我们的fragment页面的时候页面会被销毁掉,销毁掉之后呢会重新加载这个fragment页面,所以只适用于一次fragment碎片场景。解答:这个文件就是我们导航栏底部的选中和非选中状态的导航栏设置。

weixin_47139560的博客 932

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

TabLayout+ViewPager+Fragment实现底部导航

很多android的应用都有采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,今天我分享一种方法:TabLayout+ViewPager+Fragment实现底部导航 先上效果图:                        编码准备:在项目的build.gradle添加依赖:compile 'com.android.support:design:23.1.1

Yyongchao的博客 7598

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Android实现顶部导航栏(附带源码)

Android实现顶部导航栏(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 3170

Fragment嵌套Fragment,Viewpager和Fragment联动,懒加载

一、效果展示 二、主页布局 xml version="1.0" encoding="utf-8"?> xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_paren

Tangsan6666的博客 2630

Tablayout + viewpager + fragment 实现你的简易导航栏

实现该效果主要分一下几步:    1、build.gradle 中导入 compile 'com.android.support:design:26.0.0-alpha1' 依赖,具体版本视情况而定    2、上主布局文件 activity_main.xml,代码如下:        &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;LinearLa...

fengwuJ的博客 488

Android--- Drawer and Tab Navigation with ViewPager

Android--- Drawer and Tab NavigationTab Navigation --- View Pager+ Fragment + TabLayout关于ViewPagerTab NavigationDrawer Navigation Tab Navigation — View Pager+ Fragment + TabLayout 关于ViewPager ViewPager是一个可以实现横向滑动的组件, 如图片横向滑动和页面横向滑动 ViewPager2 ViewPag

HelloWorld 3193

android tab的实现方案

参考博客这里写链接内容 上述博客中提出了四种实现方式 1、ViewPager+Button实现Tab 这种,我以前只用来做轮播图,因为ViewPager的内容改起来真的很麻烦 2、Fragment切换+button实现Tab 这种方式还不错,但是我总考虑内存占用是不是过大,而且切换过于麻烦 3、FragmentPagerAdapter+ViewPager+Button实现Tab 由于...

1376
上一篇: DrawerLayout侧滑菜单
下一篇: ViewPager引导页实现跟随式小圆点
尘彦
博客等级 码龄11年 92粉丝 22原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘彦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值