Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能

这篇具有很好参考价值的文章主要介绍了Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、实现效果

Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能

二、引入依赖

appbuild.gradle在添加以下代码
1、TabLayoutimplementation 'com.google.android.material:material:1.1.0'
2、implementation 'com.github.li-xiaojun:StateLayout:1.3.4' //allprojects {…增加:maven { url ‘https://jitpack.io’ }…}
3、implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6',这个里面带的适配器,直接调用就即可
这依赖包还需要得到要添加,在Projectbuild.gradle在添加以下代码,不添加就不行

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }//加上
    }
}

三、源码实现

1、ViewPager实体类

PageInfo.java

package com.example.myapplication3.bean;

import com.example.myapplication3.fragment.BaseFragment;

public class PageInfo {

//    public String title;
    public BaseFragment fragment;

//    public PageInfo(String title, BaseFragment fragment) {
//        this.title = title;
//        this.fragment = fragment;
//    }

    public PageInfo(BaseFragment fragment) {
        this.fragment = fragment;
    }
}

ViewPager两个页面,TestFragment1.ktTestFragment2.tk的代码一样,布局也一样,自己写就即可
TestFragment1.kt

package com.example.myapplication3.fragment

import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.myapplication3.R
import com.example.myapplication3.adapter.RvAdapter
import kotlinx.android.synthetic.main.testfragment1.recyclerView

class TestFragment1 : BaseFragment(){

    private val mAdapter by lazy {
        RvAdapter().apply {
//            setOnItemLongClickListener(activity)
        }
    }

    override val layoutId: Int = R.layout.testfragment1
    override fun init(view: View?) {
        val itemList: MutableList<String> = ArrayList()
        for (i in 0..2) {
            itemList.add("position $i")
        }
        val layoutManager = LinearLayoutManager(activity)
        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
        recyclerView.layoutManager = layoutManager
        recyclerView.adapter = mAdapter
        mAdapter.setList(itemList)
    }
}

testfragment1.kt

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>
Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能

列表适配器RvAdapter.kt

package com.example.myapplication3.adapter

import android.widget.TextView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.example.myapplication3.R

class RvAdapter(layoutResId: Int = R.layout.rv_item) : BaseQuickAdapter<String, BaseViewHolder>(layoutResId) {

    override fun convert(holder: BaseViewHolder, item: String) {
        val itemTv = holder.getView<TextView>(R.id.item_tv)
        itemTv.text = item
    }
}

rv_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="112dp"
    android:layout_height="112dp"
    android:foreground="?android:attr/selectableItemBackground"
    card_view:cardBackgroundColor="@color/light_gray"
    card_view:cardCornerRadius="20dp"
    card_view:cardElevation="2dp"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/iv"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_gravity="center"
            android:src="@mipmap/ic_c" />

        <TextView
            android:id="@+id/item_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="测试"
            android:textSize="14dp"/>
    </LinearLayout>
</androidx.cardview.widget.CardView>
Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能

colors.xml中添加的颜色

	<color name="black">#000000</color><!--  黑色  -->
    <color name="white">#FFFFFFFF</color><!--  白色  -->
    <color name="gray">#959595</color><!--  灰色  -->
    <color name="light_gray">#E7E7E7</color><!--  浅灰  -->
    <color name="red">#FF0000</color><!--  红色  -->
    <color name="yellow">#FFC107</color><!--  黄色  -->
    <color name="purple">#FFBB86FC</color><!--  紫色  -->

这两个页面代码要继承父类BaseFragment()BaseFragment.kt

package com.example.myapplication3.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.lxj.statelayout.StateLayout

abstract class BaseFragment : Fragment() {
    var vieww: View? = null
    var isInit = false
    var stateLayout: StateLayout? = null
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (vieww == null) {
            vieww = inflater.inflate(layoutId, container, false)
            stateLayout = StateLayout(requireContext()).wrap(vieww).showLoading()
        }
        return stateLayout
    }

    override fun onResume() {
        super.onResume()
        safeInit()
    }

    private fun safeInit() {
        if (userVisibleHint && vieww != null) {
            if (!isInit) {
                isInit = true
                init(vieww)
                stateLayout!!.postDelayed({ stateLayout!!.showContent() }, 300)
            }
        }
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        safeInit()
    }

    protected abstract val layoutId: Int
    abstract fun init(view: View?)
    fun toast(msg: String?) {
//        Toast.makeText(XPopupApp.context, msg, Toast.LENGTH_SHORT).show();
    }
}

2、指示器样式(自定义类)

自定义ViewPagerIndicator.kt

package com.example.myapplication3.view

import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import androidx.annotation.Nullable
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import com.example.myapplication3.R

class ViewPagerIndicator @JvmOverloads constructor(
    context: Context,
    @Nullable attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    FrameLayout(context, attrs, defStyleAttr) {
//    private val rootView: View
    private val mRootView: View
    private val indView: View
    var indViewWidth = 0

    init {
        val root = inflate(context, R.layout.app_viewpager_indicator, this)
        mRootView = root.findViewById<View>(R.id.root)
        indView = root.findViewById<View>(R.id.ind_view)
    }

    override fun draw(canvas: Canvas) {
        super.draw(canvas)
    }

    fun setWithViewPager(viewPager: ViewPager) {
        //如果没有adapter,则隐藏不显示
        if (null == viewPager.adapter) {
            visibility = GONE
            Log.e(javaClass.simpleName, "no adapter")
            return
        }
        //获取viewPager中fragment的数量
        val count = viewPager.adapter!!.count
        if (count == 0) {
            return
        }

        //加载到window之后再进行view宽度的获取
        mRootView.post(Runnable { //获取当前滑块的宽度
            indViewWidth = width / count
            val layoutParams = indView.layoutParams as LayoutParams
            layoutParams.width = indViewWidth
            indView.layoutParams = layoutParams
        })
        viewPager.addOnPageChangeListener(object : OnPageChangeListener {
            /**
             *
             * @param position
             * @param positionOffset [0,1]中的值,指示在位置处与页面的偏移百分比。
             * @param positionOffsetPixels 以像素为单位的值,表示与位置的偏移量。
             */
            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
                //获取滑块距父布局左侧的距离
                val left = (position * indViewWidth + positionOffset * indViewWidth).toInt()

                //重新布局滑块view
                indView.layout(left, indView.top, left + indViewWidth, indView.bottom)
            }

            override fun onPageSelected(position: Int) {}
            override fun onPageScrollStateChanged(state: Int) {}
        })
    }
}

指示器布局app_viewpager_indicator.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/shape_indicator_radius_gray">

    <View
        android:id="@+id/ind_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_indicator_radius_yellow"/>
</FrameLayout>

指示器背景灰色shape_indicator_radius_gray.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/gray" />
    <corners android:radius="50dp" />
</shape>

指示器黄色shape_indicator_radius_yellow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/yellow" />
    <corners android:radius="50dp" />
</shape>

3、主视图实现

MainActivity.kt

package com.example.myapplication3

import android.graphics.Typeface
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.example.myapplication3.bean.PageInfo
import com.example.myapplication3.fragment.TestFragment1
import com.example.myapplication3.fragment.TestFragment2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import kotlinx.android.synthetic.main.activity_main.indicator
import kotlinx.android.synthetic.main.activity_main.tablayout
import kotlinx.android.synthetic.main.activity_main.viewPager

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        init()
    }

    private fun init() {

        //TabLayout添加自定义分割线并且可以修改分割线高度
        val linearLayout = tablayout.getChildAt(0) as LinearLayout
        linearLayout.showDividers = LinearLayout.SHOW_DIVIDER_MIDDLE
        linearLayout.dividerDrawable = ContextCompat.getDrawable(this, R.drawable.layout_divider_vertical)
//        linearLayout.dividerPadding = 50
        linearLayout.dividerPadding = 23

        viewPager.adapter = MainAdapter(supportFragmentManager)
        viewPager.currentItem = 0 //当前值设置为1才能仅显示一个默认视图
        tablayout.setupWithViewPager(viewPager)

        //****新代码**
        tablayout.getTabAt(0)?.setCustomView(R.layout.text)
        val toMyTextView1 = tablayout.getTabAt(0)?.customView?.findViewById<TextView>(R.id.textView)
        toMyTextView1?.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
        toMyTextView1?.textSize = 15F
        toMyTextView1?.setTextColor(resources.getColor(R.color.black))
        toMyTextView1?.text = "热销好货"

        tablayout.getTabAt(1)?.setCustomView(R.layout.text)
        val toMyTextView2 = tablayout.getTabAt(1)?.customView?.findViewById<TextView>(R.id.textView)
        toMyTextView2?.textSize = 12F
        toMyTextView2?.setTextColor(resources.getColor(R.color.gray))
        toMyTextView2?.text = "图文直播"
        //****

        indicator.setWithViewPager(viewPager)

        tablayout.addOnTabSelectedListener(object : OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                tab?.customView?.findViewById<TextView>(R.id.textView)?.isSelected  = true
                val tv = tab?.customView?.findViewById<TextView>(R.id.textView)
                tv?.typeface = Typeface.defaultFromStyle(Typeface.BOLD)//加粗
                tv?.textSize = 15F//直接用setTextSize(15F)也一样
                tv?.setTextColor(resources.getColor(R.color.black))
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
                tab?.customView?.findViewById<TextView>(R.id.textView)?.isSelected = false
                val tv = tab?.customView?.findViewById<TextView>(R.id.textView)
                tv?.textSize = 12F
                tv?.setTextColor(resources.getColor(R.color.gray))
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {
                Log.i("Tag","onTabReselected = ${tab?.position}")
            }
        })
    }

    class MainAdapter(fm: FragmentManager?) : FragmentPagerAdapter(fm!!) {

        private val pageInfos = arrayOf(
            PageInfo(TestFragment1()),
            PageInfo(TestFragment2()),
        )

        override fun getItem(i: Int): Fragment {
            return pageInfos[i].fragment
        }

        override fun getCount(): Int {
            return pageInfos.size
        }

//        override fun getPageTitle(position: Int): CharSequence? {
//            return pageInfos[position].title
//        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="10dp"
    android:background="@drawable/shape_indicator_radius_white"
    android:padding="10dp">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/bar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/white"
        app:elevation="0dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="50dp">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tablayout"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:layout_alignParentLeft="true"
                android:layout_centerInParent="true"
                android:overScrollMode="never"
                app:tabContentStart="10dp"
                app:tabIndicator="@drawable/tab_indicator"
                app:tabIndicatorColor="@color/yellow"
                app:tabMode="scrollable"
                app:tabRippleColor="@android:color/transparent"
                app:tabSelectedTextColor="@color/black"
                app:tabTextColor="@color/gray">

                <com.google.android.material.tabs.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="热销好货" />

                <com.google.android.material.tabs.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="图文直播" />

            </com.google.android.material.tabs.TabLayout>

            <!--  app:tabBackground="@color/yellow"
                  app:tabTextAppearance="@style/TabLayoutTextStyle"-->

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerInParent="true"
                android:text="更多 >" />
        </RelativeLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="112dp"
        android:layout_below="@id/bar" />

    <com.example.myapplication3.view.ViewPagerIndicator
        android:id="@+id/indicator"
        android:layout_width="40dp"
        android:layout_height="5dp"
        android:layout_below="@id/viewPager"
        android:layout_centerInParent="true" />
</RelativeLayout>

布局圆角shape_indicator_radius_white.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <corners android:radius="10dp" />
</shape>

TabLayout下的下划线样式tab_indicator.xml文章来源地址https://www.toymoban.com/news/detail-486533.html

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:width="20dp"
        android:height="2dp"
        android:gravity="center">
        <shape>
            <corners android:radius="1dp" />
        </shape>
    </item>
</layer-list>
Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能

到了这里,关于Android kotlin 实现仿蜜源ViewPager和指示器对应上面TabLayout功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第二十八回:如何给PageView添加指示器

    我们在前面章回中介绍了PageView这个Widget,本章回中将介绍 如何给PageView添加指示器 .闲话休提,让我们一起Talk Flutter吧。 我们在这里说的指示器表示 PageView 底部的小圆圈,它用来指示当前哪个页面被选中。常用的场景是滑动页面时小圆圈高亮显示当前被选中的页面,其它小圆

    2024年02月04日
    浏览(65)
  • Compose 实战之为下拉刷新添加自定义指示器

    在安卓开发中,下拉刷新是一个非常常用的功能,几乎只要是涉及到列表展示数据的界面都会用到它。 而 Compose 却直到 2022年10月份才在 compose.material:1.3.0 中添加了对下拉刷新的支持: Modifier.pullRefresh 。 在此之前,我们只能使用 accompanist-swiperefresh 来实现下拉刷新。 然而,更

    2024年02月07日
    浏览(31)
  • VL53L5CX驱动开发(4)----运动指示器

    VL53L5CX传感器内置了一个固件功能,可以检测场景中的运动。这个运动指示器是基于连续帧之间来计算的。使用插件vl53l5cx_plugin_motion_indicator可以使用这个选项。 运动指示器通过vl53l5cx_motion_indicator_init()函数进行初始化。如果用户想要更改传感器的分辨率,他必须使用专用函数

    2024年02月02日
    浏览(26)
  • iOS开发-下拉刷新动画依次渐隐渐显Indicator指示器效果

    iOS开发-下拉刷新动画依次渐隐渐显Indicator指示器效果 之前开发中实现下拉刷新动画三个球依次渐隐渐显指示器效果。 CABasicAnimation类的使用方式就是基本的关键帧动画。 所谓关键帧动画,就是将Layer的属性作为KeyPath来注册,指定动画的起始帧和结束帧,然后自动计算和实现

    2024年02月15日
    浏览(25)
  • Android UI--ViewPager扩展Tab标签指示

    android:layout_below=“@+id/ll_viewpager” android:scaleType=“matrix” android:src=“@drawable/cursor” / android.support.v4.view.ViewPager android:id=“@+id/viewpager” android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:layout_below=“@+id/cursor” android:flipInterval=“30” android:persistentDrawingCache=“

    2024年03月19日
    浏览(31)
  • Android——禁止ViewPager的左右滑动功能实现

    Android——禁止ViewPager的左右滑动功能实现 在Android开发中,ViewPager是一种常用的滑动控件,用于实现页面的左右切换效果。然而,在某些场景中,我们可能需要禁止ViewPager的左右滑动功能,只允许通过其他方式进行页面切换。本文将介绍如何在Android中实现禁止ViewPager左右滑动

    2024年02月06日
    浏览(34)
  • Android修行手册 - 使用ViewPager2实现画廊效果

    Unity3D特效百例 案例项目实战源码 Android-Unity实战问题汇总 游戏脚本-辅助自动化 Android控件全解手册 再战Android系列 Scratch编程案例 软考全系列 Unity3D学习专栏 蓝桥系列 ChatGPT和AIGC 专注于 Android/Unity 和各种游戏开发技巧,以及 各种资源分享 (网站、工具、素材、源码、游戏等

    2024年02月22日
    浏览(35)
  • 『Android基础入门』ViewPager+Fragment+BottomNavigationView实现底部导航

    👨‍🎓作者简介:一位喜欢写作,计科专业大三菜鸟 🏡个人主页:starry陆离 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 在ViewPager与Fragment结合实现多页面滑动的学习上再进一步,记录一下ViewPager+Fragment+BottomNavigationView实现底部导航 1.复习ViewPager的用法 2.复习F

    2023年04月08日
    浏览(32)
  • android 关于TabLayout联动ViewPager2 实现底部导航栏

    最近在心血来潮想写在app 不过我关于android可以说是0基础 在写底部导航栏的时候去问了大佬才知道TabLayout和ViewPager 花了两天才看懂... 这里只是简单介绍因为我不准备专门做安卓软件所以在学的途中很多地方没有认真记 本篇文章使用的代码是Java 这里官方是有将两个进行联动

    2024年01月25日
    浏览(34)
  • android : 底部导航栏的实现(使用ViewPager和BottomNavigationView)

      本案例中需要用的控件ViewPager和BottomNavigationView ViewPager:主要是页面的切换 Fragment:碎片(也就是每个页面的内容) BottomNavigationView:底部导航栏 非常简单,主要就是一个Viewpager和BottomNavigationView 先来说一下思路:BottomNavigationView底部导航栏   ViewPager+Fragment页面        

    2024年02月03日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包