【Android】TabLayout设置使用自定义的样式的图片显示问题

序言

TabLayout我们经常使用,用来和ViewPager2进行组合使用,做多Fragment切换页面效果。
TabLayout我们经常看到的的显示效果是上面文字,下面一个线段,在各大浏览器/新闻类APP可以看到,这个效果也是对TabLayout配置参数可以实现的,但是我们想要实现这种效果
在这里插入图片描述
我们有两个Tab,左边和右边的,选中左边的之后,左边的就是橙色,然后箭头指向右边,选中右边的,右边变成橙色,然后箭头指向左边。

这个需要对TabLayout进行配置。

实现

首先Tablayout在xml里面的配置

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="fill"
        android:background="@color/white"
        android:paddingStart="0dp"
        android:paddingEnd="0dp"
        app:tabGravity="fill"
        app:tabIndicatorColor="@color/white"
        app:tabIndicatorHeight="0dp"
        app:tabMaxWidth="0dp"
        app:tabMode="fixed"
        app:tabPaddingEnd="-1dp"
        app:tabPaddingStart="-1dp"
        app:tabRippleColor="@null" />

其中这个

      app:tabPaddingEnd="-1dp"
      app:tabPaddingStart="-1dp"

是因为Tab本身自己是有默认的Padding的,这样是为了能让我们图片充满TabLayout的空间。

在这里插入图片描述
在这里插入图片描述

然后我们需要准备好这种图片放在项目里面
接下来就是很正常的操作了,创建Adapter继承FragmentStateAdapter,然后往里面加内容

class TabAdapter(
    val fragment: FragmentActivity,
    val mContext: Context,
    val index: Int
) : FragmentStateAdapter(fragment) {

    private class ViewPagerData(var imageBgId: Int, var imageIcon: Int, var textId: Int)

    private val viewPagerDataList: MutableList<ViewPagerData> = mutableListOf()

    init {
        viewPagerDataList.add(
            ViewPagerData(
                R.drawable.ic_un_selected,
                R.mipmap.ic_un_change,
                R.string.lable_type
            )
        )
        viewPagerDataList.add(
            ViewPagerData(
                R.drawable.ic_un_selected,
                R.mipmap.ic_un_change,
                R.string.installation
            )
        )
    }

    override fun getItemCount(): Int = viewPagerDataList.size

    override fun createFragment(position: Int): Fragment {
        return when (position) {
            0 -> OneFragment()
            1 -> TwoFragment()
            else -> OneFragment()
        }
    }

    @SuppressLint("MissingInflatedId")
    fun getTabView(position: Int): View? {
        val view =
            LayoutInflater.from(mContext).inflate(R.layout.view_layout, null)
        val tabBg = view.findViewById<LinearLayout>(R.id.ll_bg)
        val tabTextView = view.findViewById<TextView>(R.id.tv_name)
        val tabImageView = view.findViewById<ImageView>(R.id.iv_icon)
        // 在这里设置初始颜色和图标
        tabTextView.setText(viewPagerDataList[position].textId)
        tabTextView.setTextColor(mContext.resources.getColor(R.color.color_first_level_word))
        tabImageView.setImageResource(viewPagerDataList[position].imageIcon)
        tabBg.setBackgroundResource(viewPagerDataList[position].imageBgId)
        return view
    }
}

里面的view_layout文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_bg"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/iv_tab_icon"
        android:layout_width="@dimen/agree_user_width_22"
        android:layout_height="@dimen/agree_user_width_22"
        android:layout_gravity="center_vertical" />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/Standard_height48"
        android:layout_marginStart="@dimen/margin_8"
        android:gravity="center_vertical"
        android:textColor="@color/color_first_level_word"
        android:textSize="@dimen/textSize_18sp" />
</LinearLayout>

注意:在设置这个Tab的高度的时候,有时候可能因为系统的问题,导致我们设置的Tab图片无法充满这个TabLayout的空间,解决办法上面有提到,其中左右无法充满就是使用这个方法解决,在TabLayout里面加

      app:tabPaddingEnd="-1dp"
      app:tabPaddingStart="-1dp"

这个上面提到了,但是上下不充满的话就无法使用这个设置了,
需要我们在设置TabLayout的时候
1.设置TabLayout的上下高度

   android:layout_height="wrap_content"

2.在设置我们每个Tab的xml文件时,就是上面的view_layout文件里面设置高度,但是不要在父View里面设置高度,就像上面的view_layout里面,父View是LinearLayout,不能将LinearLayout的高度设置成我们需要的,要将其设置成

  android:layout_height="wrap_content"

然后在里面的子View里面,将某个高度设置成我们需要的高度,撑起这个布局,比如我们将TextView的高度设置成48dp,这也是我们需要的TabLayout的高度,这样的话可以解决我们的Tab图片在上下方向上不能充满TabLayout的空间的问题。

然后我们就可以在Activity里面使用了

val adapter = TabAdapter(this, this, 0)
binding.viewPager.adapter = adapter
binding.viewPager.setIsFocusableInTouchModeKtx(false)
binding.viewPager.isUserInputEnabled = false
TabLayoutMediator(binding.tab, binding.viewPager) { tab: TabLayout.Tab, position: Int ->
     tab.customView = adapter.getTabView(position)
}.attach()
binding.tab.isTabIndicatorFullWidth = false
binding.viewPager.setCurrentItem(0, false)
//初始修改选中的item文字图片颜色
binding.tab.getTabAt(0)?.customView?.findViewById<LinearLayout>(R.id.ll_bg)?.setBackgroundResource(R.mipmap.ic_select)
binding.tab.getTabAt(0)?.customView?.findViewById<ImageView>(R.id.iv_icon)?.setImageResource(R.mipmap.ic_change)
binding.tab.getTabAt(0)?.customView?.findViewById<TextView>(R.id.tv_name)?.setTextColor(getColor(R.color.color_brand))

这样我们就已经将TabLayout和ViewPager2绑定成功了,但是我们在选择Tab的时候,还是要根据选择的Tab更换相应的背景和图片的。
我们要对这个TabLayout监听

binding.tab.addOnTabSelectedListener(object :
   TabLayout.OnTabSelectedListener {
   //选中的item处理
   override fun onTabSelected(tab: TabLayout.Tab) {
       val view = tab.customView
       if (view != null) {
           val tabBg = view.findViewById<LinearLayout>(R.id.ll_bg)
           val tabImageView =
               view.findViewById<ImageView>(R.id.iv_icon)
           val tabTextView =
               view.findViewById<TextView>(R.id.tv_name)
           val position = tab.position
           if (position == 0) {
           //因为我们只有两个Item的Tab,所以这个0代表的是第一个,也就是左边的Tab被选中了,
           //此时我们要更换图片和其他需要更换的东西,同理当我们选中其他的Tab也是要这么做的
               tabBg.setBackgroundResource(R.mipmap.ic_select)
               tabImageView.setImageResource(R.mipmap.ic_change)
               abTextView.setTextColor(getColor(R.color.color_brand)) // 替换成选中颜色
           } else {
               tabBg.setBackgroundResource(R.mipmap.ic_right_select)
               tabImageView.setImageResource(R.mipmap.ic_change)
               tabTextView.setTextColor(getColor(R.color.color_brand)) // 替换成选中颜色
           }
       }
   }

   //未选中的item处理
   override fun onTabUnselected(tab: TabLayout.Tab) {
       val view = tab.customView
       if (view != null) {
           val tabBg = view.findViewById<LinearLayout>(R.id.ll_bg)
           val tabImageView =
               view.findViewById<ImageView>(R.id.iv_icon)
           val tabTextView =
               view.findViewById<TextView>(R.id.tv_name)
           val position = tab.position
           if (position == 0) {
           //0代表第一个没有被选中
           //跟上面的处理逻辑一样
           } else {
           //跟上面的处理逻辑一样        
                     
           }
       }
   }

   override fun onTabReselected(tab: TabLayout.Tab) {
   // 不需要处理
   }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/128233.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# .NET Core API 注入Swagger

C# .NET Core API 注入Swagger 环境 Windows 10Visual Studio 2019(2017就有可以集中发布到publish目录的功能了吧)C#.NET Core 可跨平台发布代码,超级奈斯NuGet 套件管理dll将方法封装(据说可以提高效率,就像是我们用的dll那种感觉)Swagger 让接口可视化编写时间2020-12-09 …

灵活运用Vue指令:探究v-if和v-for的使用技巧和注意事项

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、作…

【虹科干货】Lambda数据架构和Kappa数据架构——构建现代数据架构

如何更好地构建我们的数据处理架构&#xff0c;如何对IT系统中的遗留问题进行现代化改造并将其转变为现代数据架构&#xff1f;该怎么为你的需求匹配最适合的架构设计呢&#xff0c;本文将分析两种最流行的基于速度的数据架构&#xff0c;为你提供一些思路。 文章速览&#xf…

电商大促演变:拼多多百亿补贴的消费升级体验

出品| 大力财经 文 | 魏力 拼多多已经够便宜了&#xff0c;双十一还能怎么玩&#xff1f;作为一个曾经被认为是深耕五环外消费者的电商平台&#xff0c;这几年拼多多从五环外杀到市中心&#xff0c;现在的国人&#xff0c;不管是中产&#xff0c;还是职场小白&#xff0c;人人…

四川思维跳动商务信息咨询有限公司是真的吗?

随着数字时代的到来&#xff0c;短视频平台抖音已经成为亿万用户每日必刷的社交媒体。不少有远见的公司也意识到了这个平台的巨大潜力&#xff0c;纷纷投身其中&#xff0c;寻求新的商业机会。四川思维跳动商务信息咨询有限公司就是这样一家企业&#xff0c;他们提供的抖音电商…

C++结构体定义 创建 赋值 结构体数组

结构体是什么&#xff1f; struct是自定义数据类型&#xff0c;是一些类型集合组成的一个类型。结构体的定义方式 #include<iostream> using namespace std;struct Student {string name;int age;int score; };创建结构体变量并赋值 方式一&#xff0c;先创建结构体变…

完整版付费进群带定位源码

看到别人发那些不是挂羊头卖狗肉&#xff0c;要么就是发的缺少文件引流的。恶心的一P 这源码是我付费花钱买的分享给大家&#xff0c;功能完整。 搭建教程 nginx1.2 php5.6--7.2均可 最好是7.2 第一步上传文件程序到网站根目录解压 第二步导入数据库&#xff08;shujuk…

偶数科技亮相2023中国程序员节——数据库技术高峰论坛

2023年10月24日&#xff0c;由中国软件行业协会主办的“中国程序员节”在北京、深圳、宁波多地同时召开&#xff0c;其中数据库技术高峰论坛在北京举办&#xff0c;偶数科技亮相本次论坛并分享了题为《大模型、实时需求推动湖仓平台走向开放》的主题演讲。 国际局势复杂、科技竞…

C语言中指针的用法以及相应的作用

目录 什么是指针&#xff1f; 指针的基本操作 &#xff08;1&#xff09;变量地址引用&#xff1a; &#xff08;2&#xff09;动态内存分配&#xff1a; &#xff08;3&#xff09;数组和字符串操作&#xff1a; &#xff08;4&#xff09;函数参数传递&#xff1a; &a…

Android Mvp案例解析

目录 后端数据接口数据格式 App客户端布局逻辑主界面布局 M&#xff08;Model&#xff09;V&#xff08;View&#xff09;P&#xff08;Presenter&#xff09;OkhttpRetrofitRxJava网络http请求 Mvp架构-初学者MVP架构的契约者 后端数据接口 接口地址&#xff1a;https://apis.…

STM32——NVIC中断优先级管理分析

文章目录 前言一、中断如何响应&#xff1f;NVIC如何分配优先级&#xff1f;二、NVIC中断优先级管理详解三、问题汇总 前言 个人认为本篇文章是我作总结的最好的一篇&#xff0c;用自己的话总结出来清晰易懂&#xff0c;给小白看也能一眼明了&#xff0c;这就是写博客的意义吧…

平安人寿基于 Apache Doris 统一 OLAP 技术栈实践

导读&#xff1a;平安人寿作为保险行业领军企业&#xff0c;坚持技术创新&#xff0c;以数据业务双轮驱动的理念和更加开放的思路来应对不断增长的数据分析和应用需求&#xff1b;以深挖数据价值、保障业务用数效率为目标持续升级大数据产品体系。自 2022 年起平安人寿开始引入…

芯驰科技出席2023云栖大会,探讨新汽车舱驾融合

10月31日-11月2日&#xff0c;2023云栖大会在杭州成功举办&#xff0c;全场景智能车芯引领者芯驰科技受邀参加斑马智行专场。 芯驰科技资深产品市场总监金辉在「新汽车舱驾融合趋势」研讨会上发表了主题演讲。在随后举办的圆桌论坛上&#xff0c;他和来自智能汽车域控制器、操…

Halcon WPF 开发学习笔记(1):Hello World小程序

文章目录 文章专栏视频链接Hello World训练图片训练目的 开始训练图像预处理导入图像三通道处理调用算子通道选取 滤波什么是好的滤波 增加对比度 区域选取阈值处理算子参数选择运行结果(红色为选择区域) 区域分割运行结果 特征筛选参数代码第二次&#xff0c;面积筛选 画选中十…

【数据在内存中的存储】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 1. 整数在内存中的存储 2. 大小端字节序和字节序判断 2.1 什么是大小端&#xff1f; 2.2 为什么有大小端? 2.3 练习 2.3.1 练习1 2.3.2 练习2 2.3.3 练习3 2.3.4 …

2023长三角G60科创走廊高质量发展要素对接大会举行

11月8日&#xff0c;第六届中国国际进口博览会2023长三角G60科创走廊高质量发展要素对接大会在国家会展中心隆重举行。会上&#xff0c;G60“一廊九城”同向同行、共赴未来&#xff0c;立足“三先走廊”战略定位&#xff0c;围绕“服务‘一带一路’建设&#xff0c;赋能一体化高…

makefile的基础使用

1、建一个目录: mkdir Makefile/makefile(两个任意一个就可以) 2、用vim打开 3、在makefile里面的写法&#xff1a; 目标文件 : 依赖文件 >小例子: test:test.c [tab]依赖关系 gcc -o test test.c 4、…

【计网 传输层概述】 中科大郑烇老师笔记 (十)

目录 0 引言1 概述1.1 传输服务和协议1.2 传输层 vs 网络层1.3 Internet传输层协议 TCP和UDP 2 多路复用、解复用2.1 UDP的多路复用2.2 TCP的多路复用 3 UDP3.1 概述3.2 UDP报文段3.3 拓展&#xff1a;TCP报文段 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏…

【中间件篇-Redis缓存数据库03】Redis高级特性和应用(发布 订阅、Stream)

Redis高级特性和应用(发布 订阅、Stream) 发布和订阅 Redis提供了基于“发布/订阅”模式的消息机制&#xff0c;此种模式下&#xff0c;消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道( channel)发布消息&#xff0c;订阅该频道的每个客户端都可以收到该消息。 …

innovus/ICC2:实际绕线层次有低于routing rule min layer的情况如何解决?

ICC2 这是因为routing rule的min layer是soft rule&#xff0c;如果希望min layer严格按照设置的来&#xff0c;还需要手动添加如下命令: set_routing_rule -min_layer_mode hard -rule xx [get_nets xx] innovus 设置route type是加入min_stack_layer选项。 create_route_…