在app
的build.gradle
在添加以下代码
1、implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6'
,这个里面带的适配器,直接调用就即可
BaseRecyclerViewAdapterHelper
简称BRVAH
Android SDK |
是否支持BaseRecyclerViewAdapterHelper:3.0.6 |
---|---|
android compileSdkVersion 29 |
是 |
android compileSdkVersion 30 |
是 |
android compileSdkVersion 31 |
是 |
android compileSdkVersion 32 |
是 |
android compileSdkVersion 33 |
是 |
这依赖包还需要得到要添加,在Project
的build.gradle
在添加以下代码,不添加就不行
allprojects {
repositories {
...
maven { url "https://jitpack.io" }//加上
}
}
2、侧滑菜单:implementation 'com.github.ljphawk:SwipeMenuLayout:1.01'
列表item
的num
值和top
文本,SlidingItembean.xml
package com.example.myapplication3;
public class SlidingItembean {
private String num;
private String name;
private String path;
private String setTop;
public SlidingItembean() {
super();
}
public SlidingItembean(String num, String name, String path, String setTop) {
super();
this.num = num;
this.name = name;
this.path = path;
this.setTop = setTop;
}
public String getSetTop() {
return setTop;
}
public void setSetTop(String setTop) {
this.setTop = setTop;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
RvAdapter.kt
package com.example.myapplication3.adapter
import cn.ljp.swipemenu.SwipeMenuLayout
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.example.myapplication3.R
import com.example.myapplication3.SlidingItembean
import kotlinx.android.synthetic.main.item.view.*
class RvAdapter(layoutResId: Int = R.layout.item) :
BaseQuickAdapter<SlidingItembean, BaseViewHolder>(layoutResId) {
//侧滑右顶置
private var mFirstOnItemClickListener: FirstOnItemClickListener? = null
private var mOnItemClickListener: OnItemClickListener? = null
override fun convert(holder: BaseViewHolder, item: SlidingItembean) {
val mSwipe: SwipeMenuLayout = holder.getView(R.id.swipe_menu_layout)
//侧滑右删
mSwipe.setEnableRightSwipe(false)
//侧滑左删
// mSwipe.setEnableRightSwipe(true)
holder.itemView.run {
tv_content.text = item.num
if (item.setTop.equals("取消置顶")){
swipe_menu_layout.setBackgroundColor(resources.getColor(R.color.colorRipple))
}else if (item.setTop.equals("置顶")){
swipe_menu_layout.setBackgroundColor(resources.getColor(R.color.white))
}
tv_toFirst.text = item.setTop
//侧滑右置顶
tv_toFirst.setOnClickListener {
mFirstOnItemClickListener!!.firstOnItemClickListener(holder)
}
//侧滑右删除
tv_menu2.setOnClickListener {
mOnItemClickListener!!.onItemClickListener(holder)
}
}
}
fun setFirstOnItemClickListener(firstOnItemClickListener: FirstOnItemClickListener) {
this.mFirstOnItemClickListener = firstOnItemClickListener
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
this.mOnItemClickListener = onItemClickListener
}
interface FirstOnItemClickListener {
fun firstOnItemClickListener(holder: BaseViewHolder)
}
interface OnItemClickListener {
fun onItemClickListener(holder: BaseViewHolder)
}
}
item
布局item.xml
<cn.ljp.swipemenu.SwipeMenuLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipe_menu_layout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/white"
app:isClickMenuAndClose="false"
app:isEnableLeftMenu="false"
app:isEnableSwipe="true"
app:isOpenChoke="true"
tools:ignore="MissingDefaultResource">
<RelativeLayout
android:id="@+id/ll_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
RelativeLayout>
<TextView
android:id="@+id/tv_toFirst"
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#2196F3"
android:gravity="center"
android:text="顶置"/>
<TextView
android:id="@+id/tv_menu2"
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#f00"
android:gravity="center"
android:text="删除"
android:textColor="#fff"/>
cn.ljp.swipemenu.SwipeMenuLayout>
<color name="white">#FFFFFFFFcolor>
<color name="colorRipple">#E2E2E2color>
<color name="white">#FFFFFFFFcolor>
“取消置顶”item
的num
值是从大到小,“置顶”item
的值是从小到大,仿QQ的“取消置顶”时间也是从大到小
num
的String
可以转换成Int
var num = mAdapter.data[position].num.toInt()
1、如果列表某一个item
的num
值是0
,top
文本是“置顶”,就直接把该item
插入它的上面,没有什么其他的
if (mAdapter.data[position].num.toInt() == 0 && mAdapter.data[position].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(position + 1, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
2、如果全部列表item
的top
文本都是“置顶”,就直接把该item
插入首位,没有什么其他的
var j = 0
for (i in 0..mAdapter.data.size) {
if (j == mAdapter.data.size) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(0, mAdapter.data[position])
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
return
}
if (i == mAdapter.data.size) break
if (mAdapter.data[i].setTop.equals("置顶")) {
j++
}
}
如果点击item
的num
值是3
3、如果某一个item
的num
值大于首位一个item
的num
值,并且某一个item
的top
文本为“置顶”和首位一个item
的top
文本是“取消置顶”,就直接把该item
插入首位,没有什么其他的
if (mAdapter.data[position].num.toInt() > mAdapter.data[0].num.toInt() && mAdapter.data[0].setTop.equals("取消置顶")) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(0, mAdapter.data[position])
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
return
}
如果点击item
的num
值是4
4、如果某一个item
的num
值小于最后到首位的哪一个item
的num
值,并且哪一个item
的top
文本为“取消置顶”,就把该item
插入哪一个item
的top
文本“取消置顶”下面,注意:需要在上面第3个下可以解决
var num = mAdapter.data[position].num.toInt()
// for (i in 0 until mAdapter.data.size)
for (i in mAdapter.data.size - 1 downTo 0) {
// if (num < mAdapter.data[i].num.toInt() && num > mAdapter.data[i+1].num.toInt() && mAdapter.data[i].setTop.equals("取消置顶") && mAdapter.data[i+1].num.equals("取消置顶")) {
if (num < mAdapter.data[i].num.toInt() && mAdapter.data[i].setTop.equals("取消置顶")) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(i + 1, mAdapter.data[position])
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
break
}
}
如果点击item
的num
值是2
1、如果列表某一个item
的num
值是0
,top
文本是“取消置顶”,就直接把该item
插入“置顶”首位,没有什么其他的
if (mAdapter.data[position].num.toInt() == 0) {
for (i in mAdapter.data.indices) {
if (mAdapter.data[i].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(i, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
}
}
2、如果全部列表item
的top
文本都是“取消置顶”,就直接把该item
插入底部设置为“置顶”,没有什么其他的
var j = 0
for (i in 0..mAdapter.data.size) {
if (j == mAdapter.data.size) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(mAdapter.data.size, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
if (i == mAdapter.data.size) break
if (mAdapter.data[i].setTop.equals("取消置顶")) {
j++
}
}
如果列表数是4
,某一个item
的num
值是2
3、如果某一个item
的num
值大于最后一个item
的num
值,并且最后一个item
的top
文本是“置顶”,就直接把该item
插入底部,没有什么其他的
if (mAdapter.data[position].num.toInt() > mAdapter.data[mAdapter.data.size - 1].num.toInt() && mAdapter.data[mAdapter.data.size - 1].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(mAdapter.data.size, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
如果列表数是4
,某一个item
的num
值是2
4、如果某一个item
的num
值小于首位到最后的哪一个item
的num
值,并且哪一个item
的top
文本为“置顶”,就把该item
插入哪一个item
的top
文本“置顶”上面,注意:需要在上面第3
个下可以解决
var num = mAdapter.data[position].num.toInt()
for (i in 0 until mAdapter.data.size) {
if (num < mAdapter.data[i].num.toInt() && mAdapter.data[i].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(i, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
break
}
}
如果列表数是4
,某一个item
的num
值是2
完整MainActivity.kt
代码
package com.example.myapplication3
import android.app.Activity
import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.example.myapplication3.adapter.RvAdapter
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : Activity(), RvAdapter.FirstOnItemClickListener, RvAdapter.OnItemClickListener {
private val mAdapter by lazy {
RvAdapter()
}
private val list: MutableList<SlidingItembean> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()
initData()
initEvent()
}
private fun initEvent() {
recyclerView.adapter = mAdapter
mAdapter.setList(list)
mAdapter.setFirstOnItemClickListener(this)
mAdapter.setOnItemClickListener(this)
}
private fun initData() {
for (i in 0..3) {
var slidingItembean: SlidingItembean? = null
slidingItembean = SlidingItembean("$i", "", "", "置顶")
list.add(slidingItembean)
}
}
/**
* 初始化界面
*/
private fun initView() {
val layoutManager = LinearLayoutManager(this@MainActivity)
layoutManager.orientation = LinearLayoutManager.VERTICAL
recyclerView.layoutManager = layoutManager
}
/**
* 取消置顶
* @param position
*/
private fun unSetTop(position: Int) {
var isAdd = false
/** 差值 */
var min = 9999999
/** 当前position的数值 */
// val num: Int
// var num: Int
// 差值最小处的行数
var j = 0
var num2 = 0
var jumpNum = 0
mAdapter.data[position].setTop = "置顶"
var num = mAdapter.data[position].num.toInt()
// list长度为2特殊处理
if (mAdapter.data.size == 2) {
// 第一行确定为取消置顶
if (mAdapter.data[1].setTop.equals("取消置顶")) {
if (position == 0) {
if (num == 0) {
mAdapter.data.add(2, mAdapter.data[position])
}
if (num == 1) {
mAdapter.data.add(2, mAdapter.data[position])
}
// list.removeAt(position)
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
} else {
mAdapter.data.add(2, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
}
} else {
if (num == 0) {
mAdapter.data.add(1, mAdapter.data[position])
}
if (num == 1) {
mAdapter.data.add(2, mAdapter.data[position])
}
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
}
} else {
//for (i in mAdapter.data.indices)
for (i in 0 until mAdapter.data.size) {
if (num < mAdapter.data[i].num.toInt() && mAdapter.data[i].setTop.equals("置顶")) {
mAdapter.data.add(i, mAdapter.data[position])
isAdd = true
break
}
if (i + 1 != mAdapter.data.size) {
if (num > mAdapter.data[i].num.toInt() && num < mAdapter.data[i + 1].num.toInt()) {
mAdapter.data.add(i + 1, mAdapter.data[position])
isAdd = true
break
}
} else {
mAdapter.data.add(i + 1, mAdapter.data[position])
isAdd = true
break
}
}
// 如果没有比自己小的值 例如0 则isAdd=false
// 遍历list 寻找差值最小的地方插入list
if (!isAdd) {
// for (i in mAdapter.data.indices)
for (i in 0 until mAdapter.data.size) {
if (i == position || mAdapter.data[i].setTop.equals("取消置顶")) {
// 排除与自身相比较
// 排除置顶item比较
Log.i("TAG", "调过$i")
jumpNum++
if (jumpNum == mAdapter.data.size) {
j = mAdapter.data.size
}
continue
}
num2 = mAdapter.data[i].num.toInt()
if (num2 - num < min) {
min = num2 - num
// 记录行号
j = i
Log.i("TAG", "插入行数J=$j")
}
}
// 遍历完成后拿到差值min
val number = min + num
mAdapter.data.add(j, mAdapter.data[position])
Log.i("TAG", "*********插入行数J=$j")
}
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
}
}
//取消置顶
private fun unSetTop2(position: Int) {
//1、如果列表某一个item的num值是0,top文本是“取消置顶”,就直接把该item插入“置顶”首位,没有什么其他的
if (mAdapter.data[position].num.toInt() == 0) {
for (i in mAdapter.data.indices) {
if (mAdapter.data[i].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(i, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
}
}
//2、如果列表item的top文本都是“取消置顶”,不用数一下就直接把该item插入底部
var j = 0
for (i in 0..mAdapter.data.size) {
if (j == mAdapter.data.size) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(mAdapter.data.size, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
if (i == mAdapter.data.size) break
if (mAdapter.data[i].setTop.equals("取消置顶")) {
j++
}
}
//3、如果某一个item的num值大于最后一个item的num值,并且最后一个item的top文本是“置顶”,不用数一下就直接把该item插入底部
if (mAdapter.data[position].num.toInt() > mAdapter.data[mAdapter.data.size - 1].num.toInt() && mAdapter.data[mAdapter.data.size - 1].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(mAdapter.data.size, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
//4、如果某一个item的num值小于首位到最后的哪一个item的num值,并且哪一个item的top文本为“置顶”,就把该item插入哪一个item的top文本“置顶”上面,注意:需要在上面第3个下可以解决
var num = mAdapter.data[position].num.toInt()
for (i in 0 until mAdapter.data.size) {
if (num < mAdapter.data[i].num.toInt() && mAdapter.data[i].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "置顶"
mAdapter.data.add(i, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
break
}
}
}
/**
* 置顶
* @param position
*/
private fun setTop(position: Int) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(0, mAdapter.data[position])
// 置顶后list.size增加一 所以要position+1
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
}
//置顶
private fun setTop2(position: Int) {
//1、如果列表某一个item的num值是0,top文本是“置顶”,就直接把该item插入它的上面,没有什么其他的
if (mAdapter.data[position].num.toInt() == 0 && mAdapter.data[position].setTop.equals("置顶")) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(position + 1, mAdapter.data[position])
mAdapter.data.removeAt(position)
mAdapter.notifyDataSetChanged()
return
}
//2、如果列表item的top文本都是“置顶”,不用数一下就直接把该item插入首位
var j = 0
for (i in 0..mAdapter.data.size) {
if (j == mAdapter.data.size) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(0, mAdapter.data[position])
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
return
}
if (i == mAdapter.data.size) break
if (mAdapter.data[i].setTop.equals("置顶")) {
j++
}
}
//3、如果某一个item的num值大于首位一个item的num值,并且某一个item的top文本为“置顶”和首位一个item的top文本是“取消置顶”,不用数一下就直接把该item插入首位
if (mAdapter.data[position].num.toInt() > mAdapter.data[0].num.toInt() && mAdapter.data[0].setTop.equals("取消置顶")) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(0, mAdapter.data[position])
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
return
}
//4、如果某一个item的num值小于首位到最后的哪一个item的num值,并且哪一个item的top文本为“取消置顶”,就把该item插入哪一个item的top文本“取消置顶”下面,注意:需要在上面第3个下可以解决
var num = mAdapter.data[position].num.toInt()
// for (i in 0 until mAdapter.data.size)
for (i in mAdapter.data.size - 1 downTo 0) {
// if (num < mAdapter.data[i].num.toInt() && num > mAdapter.data[i+1].num.toInt() && mAdapter.data[i].setTop.equals("取消置顶") && mAdapter.data[i+1].num.equals("取消置顶")) {
if (num < mAdapter.data[i].num.toInt() && mAdapter.data[i].setTop.equals("取消置顶")) {
mAdapter.data[position].setTop = "取消置顶"
mAdapter.data.add(i + 1, mAdapter.data[position])
mAdapter.data.removeAt(position + 1)
mAdapter.notifyDataSetChanged()
break
}
}
}
//侧滑右置顶
override fun firstOnItemClickListener(holder: BaseViewHolder) {
if (mAdapter.data[holder.adapterPosition].setTop.equals("置顶")) {
setTop2(holder.adapterPosition)
// setTop(holder.adapterPosition)
} else if (mAdapter.data[holder.adapterPosition].setTop.equals("取消置顶")) {
unSetTop2(holder.adapterPosition)
}
}
//侧滑右删除
override fun onItemClickListener(holder: BaseViewHolder) {
mAdapter.data.removeAt(holder.adapterPosition)
mAdapter.notifyDataSetChanged()
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dyk="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff4f7f9"
android:cacheColorHint="#00000000"
android:divider="#dddbdb"
android:dividerHeight="1dp"
dyk:right_width="120dp" />
RelativeLayout>