一、实现效果
二、引入依赖
在app
的build.gradle
在添加以下代码
1、框架弹窗AnyLayer
(github
官网):implementation "com.github.goweii:AnyLayer:4.1.4-androidx"
2、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" }//加上
}
}
三、实现源码
1、实体类
单选/多选Dict.java
:
package com.example.myapplication3.data;
public class Dict {
private String dataName;
private String dataValue;
public Dict(String dataName, String dataValue) {
this.dataName = dataName;
this.dataValue = dataValue;
}
public String getDataName() {
return dataName;
}
public void setDataName(String dataName) {
this.dataName = dataName;
}
public String getDataValue() {
return dataValue;
}
public void setDataValue(String dataValue) {
this.dataValue = dataValue;
}
}
2、适配器单选/多选
单选RvRadioAdapter.kt
package com.example.myapplication3.adapter
import android.graphics.Color
import android.view.View
import android.widget.TextView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.example.myapplication3.R
import com.example.myapplication3.data.Dict
//单选
class RvRadioAdapter(var selValue: String, layoutResId: Int = R.layout.item_rad) :
BaseQuickAdapter<Dict, BaseViewHolder>(layoutResId) {
override fun convert(helper: BaseViewHolder, item: Dict) {
var tvName = helper.getView<TextView>(R.id.tvName)
var tvSelected = helper.getView<TextView>(R.id.tvSelected)
tvName.text = item.dataName
// 根据选中状态更新UI
tvName.setTextColor(context.resources.getColor(R.color.v666666))//<color name="v666666">#666666</color>
tvSelected.visibility = View.GONE
if(item.dataValue.equals(selValue)){
tvName.setTextColor(context.resources.getColor(R.color.red))
tvSelected.visibility = View.VISIBLE
}
}
fun getSelectIndex(): Int {
var index = 0
data.forEachIndexed { i, dict ->
if(dict.dataValue == selValue){
index = i
return@forEachIndexed
}
}
return index
}
}
多选RvMCAdapter.kt
package com.example.myapplication3.adapter
import android.view.View
import android.widget.TextView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.example.myapplication3.R
import com.example.myapplication3.data.Dict
//多选
class RvMCAdapter(var sels:MutableSet<Dict>, layoutResId: Int = R.layout.item_rad) :
BaseQuickAdapter<Dict, BaseViewHolder>(layoutResId) {
override fun convert(helper: BaseViewHolder, item: Dict) {
var tvName = helper.getView<TextView>(R.id.tvName)
var tvSelected = helper.getView<TextView>(R.id.tvSelected)
tvName.text = item.dataName
// 根据选中状态更新UI
tvName.setTextColor(context.resources.getColor(R.color.v666666))
tvSelected.visibility = View.GONE
if(sels.contains(item)){
tvName.setTextColor(context.resources.getColor(R.color.red))
tvSelected.visibility = View.VISIBLE
}
}
fun setCheckSelValue(sels: MutableSet<Dict>){
this.sels = sels
notifyDataSetChanged()
}
}
单选/多选item
布局item_rad.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="45dp"
android:gravity="center">
<!--<color name="v666666">#666666</color>-->
<TextView
android:id="@+id/tvName"
android:text="text"
android:textColor="@color/v666666"
android:textSize="15sp"
android:paddingStart="20dp"
android:paddingEnd="8dp"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:paddingLeft="20dp"
android:paddingRight="8dp" />
<TextView
android:id="@+id/tvSelected"
android:text="@string/checked"
android:layout_toEndOf="@+id/tvName"
android:textSize="15sp"
android:visibility="gone"
android:textColor="@color/red"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_toRightOf="@+id/tvName" />
<!--<color name="veeeeee">#eeeeee</color>-->
<View
android:background="@color/veeeeee"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="0.5dp"/>
</RelativeLayout>
3、框架弹窗AnyLayer单选/多选
DialogUtil.kt
package com.example.myapplication3.util
import android.view.Gravity
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.isGone
import androidx.recyclerview.widget.RecyclerView
import com.example.myapplication3.R
import com.example.myapplication3.adapter.RvMCAdapter
import com.example.myapplication3.adapter.RvRadioAdapter
import com.example.myapplication3.data.Dict
import per.goweii.anylayer.AnyLayer
import per.goweii.anylayer.widget.SwipeLayout
/**
* 底部弹出的列表对话框(单选)
*/
fun showRadioListDialog(
title: String?,
selValue: String?,
dictList: List<Dict>,
callback: OnResultCallback<String>
) {
val dialog = AnyLayer.dialog()
.contentView(R.layout.dialog_rad_list)
.backgroundDimDefault()
.gravity(Gravity.BOTTOM)
.swipeDismiss(SwipeLayout.Direction.BOTTOM)
.onClickToDismiss(R.id.flFork)
dialog.show()
val mAdapter = RvRadioAdapter(selValue ?: "").apply{
setOnItemClickListener { _, _, position ->
val dict = getItem(position)
if(dict.dataValue.equals(selValue)){
dict.dataValue = ""
}
callback.onResult(dict.dataName)
dialog.dismiss()
}
}
dialog.getView<TextView>(R.id.title)?.text = title?:""
dialog.getView<RecyclerView>(R.id.mRecyclerView)?.apply {
// setMaxHeight(getScreenPix().heightPixels * 1 / 2)
adapter = mAdapter
mAdapter.setList(dictList)
val pos = mAdapter.getSelectIndex()
scrollToPosition(pos)
}
}
/**
* 底部弹出的列表对话框(多选)
*/
fun showMCListDialog(
title: String?,
selname: String,
dictList: List<Dict>,
callback: OnResultCallback<String>
) {
val dialog = AnyLayer.dialog()
.contentView(R.layout.dialog_rad_list)
.backgroundDimDefault()
.gravity(Gravity.BOTTOM)
.swipeDismiss(SwipeLayout.Direction.BOTTOM)
.onClickToDismiss(R.id.flFork)
dialog.show()
val sels = mutableSetOf<Dict>()
val names = selname.split(",")
dictList.forEach {
if(names.contains(it.dataName)){
sels.add(it)
}
}
val mAdapter = RvMCAdapter(sels).apply{
setOnItemClickListener { parent, view, position ->
val dict = getItem(position)
if(sels.contains(dict)){
sels.remove(dict)
}else{
sels.add(dict)
}
setCheckSelValue(sels)
}
}
dialog.getView<TextView>(R.id.title)?.text = title?:""
dialog.getView<RecyclerView>(R.id.mRecyclerView)?.apply {
// setMaxHeight(getScreenPix().heightPixels * 1 / 2)
adapter = mAdapter
mAdapter.setList(dictList)
}
dialog.getView<LinearLayout>(R.id.ll_dialog_confirm)?.isGone = false
dialog.getView<TextView>(R.id.tv_dialog_confirm)?.setOnClickListener {
var valueBuilder = StringBuilder()
sels.forEach {
// valueBuilder.append("|$" + it.dataValue + "$");
valueBuilder.append(it.dataName);
}
// if(valueBuilder.isNotEmpty()){
// valueBuilder = valueBuilder.deleteCharAt(0)
// }
dialog.dismiss()
callback.onResult(valueBuilder.toString())
}
}
interface OnResultCallback<T> {
fun onResult(t: T)
}
Dialog
的item
布局dialog_rad_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:background="@color/white"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:paddingTop="@dimen/dp_10"
android:paddingBottom="@dimen/dp_10"
android:gravity="center_vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="33dp"
android:layout_centerInParent="true"
android:layout_toLeftOf="@id/flFork"
android:textColor="#333333"
android:gravity="center"
android:textStyle="bold"
android:textSize="15sp" />
<FrameLayout
android:id="@+id/flFork"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_10"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_alignParentRight="true">
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:src="@mipmap/icon_black_fork"
android:contentDescription="关闭"/>
<!--icon_black_fork,这是在android studio系统中添加资源图标-->
</FrameLayout>
</RelativeLayout>
<!--<color name="veeeeee">#eeeeee</color>-->
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/veeeeee" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
<LinearLayout
android:id="@+id/ll_dialog_confirm"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_margin="@dimen/dp_5"
android:visibility="gone"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/fl_dialog_close"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/tv_dialog_confirm"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C0C0C0"
android:gravity="center"
android:text="@string/confirm"
android:textSize="16sp"
android:textColor="#000000"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>
3、实现视图
从底部弹出列表对话框(单选/多选)功能,单选或多选确定后通知观察者MainActivity.kt
package com.example.myapplication3
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.myapplication3.data.Dict
import com.example.myapplication3.util.OnResultCallback
import com.example.myapplication3.util.showMCListDialog
import com.example.myapplication3.util.showRadioListDialog
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var list: MutableList<Dict> = ArrayList()
private var index: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()
initDatas()
initListener()
}
private fun initView() {
textView1.text = "测试1"//默认
textView2.text = "测试1"//默认
}
private fun initDatas() {
for (i in 1..10) {
val sc = Dict("测试$i", "$i")
list.add(sc)
}
}
private fun initListener() {
//从底部弹出列表对话框(单选)
textView1.setOnClickListener {
for (i in 0 until list.size) {
if (textView1.text == list[i].dataName) {
index = i;
break
}
}
showRadioListDialog(
textView1.text.toString(),
list[index].dataValue,
list as List<Dict>,
object : OnResultCallback<String> {
override fun onResult(dataName: String) {
textView1.text = dataName
}
})
}
//从底部弹出列表对话框(多选)
textView2.setOnClickListener {
for (i in 0 until list.size) {
if (textView1.text == list[i].dataName) {
index = i;
break
}
}
showMCListDialog(
textView1.text.toString(),
list[index].dataValue,
list as List<Dict>,
object : OnResultCallback<String> {
override fun onResult(s: String) {
textView2.text = s
}
})
}
}
}
activity_main.xml
<?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="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#DBDCDD"
android:textSize="30dp" />
<View
android:layout_width="match_parent"
android:layout_height="50dp"/>
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#DBDCDD"
android:textSize="30dp" />
</LinearLayout>