一、实现效果
指示器样式,第二个gif是用模拟器的,gif有小问题,第三个截图没问题
二、引入依赖
在app
的build.gradle
在添加以下代码
1、implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6'
,这个里面带的适配器,直接调用就即可
这依赖包还需要得到要添加,在Project
的build.gradle
在添加以下代码,不添加就不行
allprojects {
repositories {
...
maven { url "https://jitpack.io" }//加上
}
}
三、源码实现
1、指示器样式(自定义类)
自定义RecyclerViewIndicator.kt
package com.example.myapplication3.view
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import androidx.annotation.Nullable
import androidx.recyclerview.widget.RecyclerView
import com.example.myapplication3.R
class RecyclerViewIndicator @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
var indViewHeight = 0
var rate = 0f
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)
}
/**
* 绑定recyclerView
* @param recyclerView
* @param orientation 排列方向
*
* 这里用到的recyclerView的三个方法
* computeHorizontalScrollExtent/computeVerticalScrollExtent 当前显示在屏幕上的总长度
* computeHorizontalScrollOffset/computeVerticalScrollOffset 当前滑动的总长度
* computeHorizontalScrollRange/computeVerticalScrollRange recylerView内部的总长度
*/
fun setWithRecyclerView(recyclerView: RecyclerView, orientation: Int) {
val isHorizontal = orientation == RecyclerView.HORIZONTAL
mRootView.post(Runnable {
val scrollRange =
(if (isHorizontal) recyclerView.computeHorizontalScrollRange() else recyclerView.computeVerticalScrollRange()).toFloat()
val scrollExtent =
(if (isHorizontal) recyclerView.computeHorizontalScrollExtent() else recyclerView.computeVerticalScrollExtent()).toFloat()
val layoutParams = indView.layoutParams as LayoutParams
if (isHorizontal) {
//算出比例
rate = width.toFloat() / scrollRange
//由显示在屏幕上的总长度算出滑块长度
indViewWidth = (scrollExtent * rate).toInt()
layoutParams.height = LayoutParams.MATCH_PARENT
layoutParams.width = indViewWidth
} else {
rate = height.toFloat() / scrollRange
layoutParams.width = LayoutParams.MATCH_PARENT
indViewHeight = (scrollExtent * rate).toInt()
layoutParams.height = indViewHeight
}
indView.layoutParams = layoutParams
})
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val scrollOffset =
if (isHorizontal) recyclerView.computeHorizontalScrollOffset() else recyclerView.computeVerticalScrollOffset()
//由recyclerView滑动距离算出滑块移动距咯
if (isHorizontal) {
val left = (scrollOffset * rate).toInt()
indView.layout(left, indView.top, left + indViewWidth, indView.bottom)
} else {
val top = (scrollOffset * rate).toInt()
indView.layout(indView.left, top, indView.right, top + indViewHeight)
}
}
})
}
}
指示器布局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>
colors.xml
中添加的颜色
<color name="gray">#959595</color><!-- 灰色 -->
<color name="orange">#F94E18</color><!-- 桔色 -->
<color name="translucent_red">#20EA5A5A</color> <!-- 半透明红 -->
指示器桔色shape_indicator_radius_orange.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/orange" />
<corners android:radius="50dp" />
</shape>
2、RecyclerView适配器
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"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/xx"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_c" />
<TextView
android:id="@+id/item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试"/>
</LinearLayout>
3、主视图实现
MainActivity.kt
package com.example.myapplication3
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.myapplication3.adapter.RvAdapter
import kotlinx.android.synthetic.main.activity_main.indicator
import kotlinx.android.synthetic.main.activity_main.recyclerView
class MainActivity : AppCompatActivity() {
private val mAdapter by lazy {
RvAdapter().apply {
// setOnItemLongClickListener(activity)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init()
}
private fun init() {
val itemList: MutableList<String> = ArrayList()
for (i in 0..12) {
itemList.add("测试$i")
}
val layoutManager = LinearLayoutManager(this@MainActivity)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
recyclerView.layoutManager = layoutManager
recyclerView.adapter = mAdapter
mAdapter.setList(itemList)
indicator.setWithRecyclerView(recyclerView,LinearLayoutManager.HORIZONTAL)
}
}
activity_main.xml文章来源:https://www.toymoban.com/news/detail-492869.html
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:orientation="vertical"
android:padding="10dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="15dp"
android:gravity="center">
<com.example.myapplication3.view.RecyclerViewIndicator
android:id="@+id/indicator"
android:layout_width="55dp"
android:layout_height="4dp" />
</LinearLayout>
</LinearLayout>
布局圆角样式shape_indicator_radius_white.xml
文章来源地址https://www.toymoban.com/news/detail-492869.html
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/translucent_red"/>
<corners android:radius="10dp" />
</shape>
到了这里,关于Android kotlin 实现仿淘宝RecyclerView和对应下的指示器功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!