目录
前言
之前用的下拉弹窗,都是设定固定的实体类,每次从后台获取集合后都要转换为弹窗上设定的指定类型,非常麻烦,于是我便开始了优化升级,传入任意集合类型都可以显示数据,并可以获取选中的实体类型。
一、引入插件
下面是弹窗中使用到的插件。
// 强烈推荐
//基础工具库
implementation 'com.github.tamsiree.RxTool:RxKit:2.6.3'
//UI库
implementation 'com.github.tamsiree.RxTool:RxUI:2.6.3'
implementation 'org.apache.commons:commons-lang3:3.6'
二、实现步骤
不多说,直接上代码
首先创建dialog ,相关解释看代码注释
package com.home.lh.ui.dialog.custom;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.home.lh.R;
import com.home.lh.utils.system.MySystemUtil;
import com.tamsiree.rxkit.view.RxToast;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 漠水情自定义弹窗
*/
public class MsqListDialog<T> extends Dialog {
private Context context;
TextView qx;
TextView wc;
TextView titleView;
private String title;
RecyclerView recyclerView;
SearchView searchView;
private List<T> list;
String fieldName;
MsqListDialogListener<T> msqListDialogListener;
MsqListAdapter<T> hd;
T t;
int flag = View.GONE;
boolean isBottom = true;
LinearLayout listZt;
/**
*
* @param context 全局
* @param list 数据
* @param fieldName 展示的字段名称
*/
public MsqListDialog(@NonNull Context context,List<T> list,String fieldName) {
super(context);
this.context = context;
this.list = list;
this.fieldName = StringUtils.capitalize(fieldName);
}
/**
*
* @param context 全局
* @param themeResId 资源样式
* @param list 数据
* @param fieldName 展示的字段名称
*/
public MsqListDialog(@NonNull Context context, int themeResId,List<T> list,String fieldName) {
super(context, themeResId);
this.context = context;
this.list = list;
this.fieldName = StringUtils.capitalize(fieldName);
}
protected MsqListDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
this.context = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_msq_list);
setCanceledOnTouchOutside(true);
qx = findViewById(R.id.list_qx);
wc = findViewById(R.id.list_wc);
titleView = findViewById(R.id.list_title);
recyclerView = findViewById(R.id.recyclerView);
searchView = findViewById(R.id.search_view);
listZt = findViewById(R.id.list_ll_zt);
searchView.setVisibility(flag);
titleView.setText(title);
initClick();
initData();
}
@Override
public void show() {
super.show();
WindowManager wm = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);
Point point=new Point();
wm.getDefaultDisplay().getSize(point);
int width = point.x;
int height = point.y;
WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.width = width;
//
if(isBottom){
layoutParams.gravity = Gravity.BOTTOM;
getWindow().setWindowAnimations(R.style.dialogCtChange);
}else{
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) listZt.getLayoutParams();
lp.height = (int)(height * 0.7);
listZt.setLayoutParams(lp);
layoutParams.gravity = Gravity.CENTER;
getWindow().setWindowAnimations(R.style.custom_dialog);
}
// layoutParams.x = 100;
// layoutParams.y = 100;
getWindow().getDecorView().setPadding(0, 0, 0, 0);
getWindow().setAttributes(layoutParams);
}
/**
* 初始化数据
*/
private void initData(){
LinearLayoutManager manager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
// 设置布局管理器
recyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
recyclerView.setLayoutManager(manager);
setInfoData(list);
}
/**
* 初始化数据
* @param list
*/
private void setInfoData(List<T> list){
hd= new MsqListAdapter<T>(list,fieldName,context);
hd.setMsqListRecyclerviewListener(new MsqListAdapter.MsqListRecyclerviewListener<T>() {
@Override
public void onItemLongClickListenerData(View view, T o) {
}
@Override
public void onItemClickListenerData(View view, T o) {
t = o;
int all= Objects.requireNonNull(recyclerView.getAdapter()).getItemCount();
int num = recyclerView.getChildCount();
for (int i = 0;i<num;i++){
LinearLayout tv = (LinearLayout) recyclerView.getChildAt(i);
TextView tx= (TextView) tv.getChildAt(0);
tx.setBackgroundColor(context.getResources().getColor(R.color.white));
tx.setTextColor(context.getResources().getColor(R.color.black));
}
view.setBackgroundColor(context.getResources().getColor(R.color.danluese));
TextView textView= (TextView) view;
textView.setTextColor(context.getResources().getColor(R.color.white));
}
});
recyclerView.setAdapter(hd);
}
/**
* 初始化点击事件
*/
private void initClick(){
// 关闭弹窗
qx.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
//确定选择
wc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
if(t == null){
RxToast.warning("请选择条目!");
}else {
msqListDialogListener.onYesClick(t);
dismiss();
}
}
});
searchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchView.setIconified(false);
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
List<T> seachList = new ArrayList<>();
list.stream().forEach(t->{
String val= MySystemUtil.getValue(t,fieldName);
if(Objects.requireNonNull(val).contains(query)){
seachList.add(t);
}
});
setInfoData(seachList);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
List<T> seachList = new ArrayList<>();
list.stream().forEach(t->{
String val= MySystemUtil.getValue(t,fieldName);
if(Objects.requireNonNull(val).contains(newText)){
seachList.add(t);
}
});
setInfoData(seachList);
return false;
}
});
}
/**
* 设置中间的标题
* @param t
*/
public void setTitle(String t){
this.title = t;
}
/**
* 设置监听
* @param msqListDialogListener
*/
public void setMsqListDialogListener(MsqListDialogListener<T> msqListDialogListener){
this.msqListDialogListener = msqListDialogListener;
}
/**
* 是否显示查询
* @param flag
*/
public void isShowSeach(Boolean flag){
if(flag){
this.flag = View.VISIBLE;
}else{
this.flag = View.GONE;
}
}
/**
* 设置是否底部,默认居于底部
* @param flag
*/
public void isBottom(Boolean flag){
this.isBottom = flag;
}
/**
* 内部实现接口
*/
public interface MsqListDialogListener<T>{
/**
* 确定
* @param s
*/
public void onYesClick(T s);
}
}
上述代码中使用到的xml如下:
dialog_msq_list.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="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/dls_color"
android:orientation="horizontal">
<TextView
android:id="@+id/list_qx"
android:layout_width="0dp"
android:layout_height="match_parent"
android:textSize="@dimen/sp_16"
android:text="取消"
android:textColor="@color/white"
android:gravity="center"
android:layout_weight="1"/>
<TextView
android:textSize="@dimen/sp_16"
android:id="@+id/list_title"
android:text="分配整改区域"
android:textColor="@color/white"
android:layout_width="180dp"
android:gravity="center"
android:layout_height="match_parent"
/>
<TextView
android:textSize="@dimen/sp_16"
android:id="@+id/list_wc"
android:layout_width="0dp"
android:text="完成"
android:textColor="@color/white"
android:gravity="center"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.SearchView
app:queryHint="请输入要查询的内容"
android:iconifiedByDefault="false"
android:queryHint="搜索"
android:id="@+id/search_view"
android:background="@color/qian_hui"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_35">
</androidx.appcompat.widget.SearchView>
</LinearLayout>
<LinearLayout
android:id="@+id/list_ll_zt"
android:layout_width="match_parent"
android:layout_height="280dp"
android:background="@color/white"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
style.xml 弹出动画
<!--弹窗居中动画-->
<style name="Dialog_Msg" parent="android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item> <!--边框-->
<item name="android:windowIsFloating">true</item> <!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">true</item> <!--半透明-->
<item name="android:windowNoTitle">true</item> <!--无标题-->
<item name="android:background">@android:color/transparent</item> <!--背景透明-->
<item name="android:windowBackground">@android:color/transparent</item> <!--背景透明-->
<item name="android:backgroundDimEnabled">true</item> <!--模糊-->
<item name="android:backgroundDimAmount">0.6</item> <!--背景透明度-->
</style>
<!--上弹 dialog的动画-->
<style name="dialogCtChange" mce_bogus="1" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/changtc_dialog_in</item>
<item name="android:windowExitAnimation">@anim/changtc_dialog_out</item>
</style>
changtc_dialog_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="100%"
android:toYDelta="0" />
</set>
changtc_dialog_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="0"
android:toYDelta="100%" />
</set>
创建adapter
package com.home.lh.ui.dialog.custom;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.home.lh.R;
import com.home.lh.utils.system.MySystemUtil;
import java.util.ArrayList;
import java.util.List;
public class MsqListAdapter<T> extends RecyclerView.Adapter<MsqListAdapter.VH> {
private List<T> list;
private String fieldName;
private MsqListRecyclerviewListener<T> msqListRecyclerviewListener;
private Context context;
private List<Boolean> isClicks;//控件是否被点击,默认为false,如果被点击,改变值,控件根据值改变自身颜色
public MsqListAdapter(List<T> list,String fieldName, Context context) {
this.list = list;
this.fieldName = fieldName;
this.context = context;
isClicks = new ArrayList<>();
for(int i = 0;i<list.size();i++){
isClicks.add(false);
}
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.dialog_msq_list_item, viewGroup, false);
return new MsqListAdapter.VH(v);
}
@Override
public void onBindViewHolder(@NonNull VH vh, @SuppressLint("RecyclerView") final int i) {
final T s = list.get(i);
String val= MySystemUtil.getValue(s,fieldName);
vh.item.setText(val);
if(isClicks.get(i)){
vh.item.setBackgroundColor(context.getResources().getColor(R.color.danluese));
}else{
vh.item.setBackgroundColor(context.getResources().getColor(R.color.white));
}
vh.item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for(int i = 0; i <isClicks.size();i++){
isClicks.set(i,false);
}
isClicks.set(i,true);
// notifyDataSetChanged();
msqListRecyclerviewListener.onItemClickListenerData(v,s);
}
});
}
@Override
public int getItemCount() {
return list.size();
}
public static class VH extends RecyclerView.ViewHolder {
private TextView item;
public VH(@NonNull View v) {
super(v);
item = v.findViewById(R.id.item_info);
}
}
public void setMsqListRecyclerviewListener(MsqListRecyclerviewListener<T> msqListRecyclerviewListener) {
this.msqListRecyclerviewListener = msqListRecyclerviewListener;
}
public interface MsqListRecyclerviewListener<T> {
void onItemLongClickListenerData(View view, T o);
void onItemClickListenerData(View view, T o);
}
}
用到 的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="40dp"
android:background="@color/white"
android:orientation="horizontal">
<TextView
android:id="@+id/item_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="@color/black"
android:text="啊哈哈哈哈哈"/>
</LinearLayout>
使用到颜色color.xml:
<color name="danluese">#00FFFF</color>
<color name="white">#FFFFFFFF</color>
<color name="black">#FF000000</color>
<color name="qian_hui">#F8F8FF</color>
<color name="dls_color">#3366ff</color>
调用示例:
List<SpannerInfo> spannerInfos = new ArrayList<>();
SpannerInfo s1 =new SpannerInfo();
s1.setId("1");
s1.setText("111111");
spannerInfos.add(s1);
SpannerInfo s2 =new SpannerInfo();
s2.setId("2");
s2.setText("22222");
spannerInfos.add(s2);
SpannerInfo s3 =new SpannerInfo();
s3.setId("3");
s3.setText("333333");
spannerInfos.add(s3);
SpannerInfo s4 =new SpannerInfo();
s4.setId("4");
s4.setText("4444444");
spannerInfos.add(s4);
SpannerInfo s5 =new SpannerInfo();
s5.setId("5");
s5.setText("555555");
spannerInfos.add(s5);
SpannerInfo s6 =new SpannerInfo();
s6.setId("6");
s6.setText("666666");
spannerInfos.add(s6);
SpannerInfo s7 =new SpannerInfo();
s7.setId("7");
s7.setText("77777777");
spannerInfos.add(s7);
MsqListDialog<SpannerInfo> myDialog = new MsqListDialog<>(requireActivity(), R.style.Dialog_Msg,spannerInfos,"text");
myDialog.setTitle("问题选择");
myDialog.isBottom(true);
myDialog.isShowSeach(false);
myDialog.setCanceledOnTouchOutside(false);
myDialog.setMsqListDialogListener(new MsqListDialog.MsqListDialogListener<SpannerInfo>() {
@Override
public void onYesClick(SpannerInfo s) {
RxToast.info(s.getText());
}
});
myDialog.show();
截图:
总结
工作和学习中有好的想法或思路就要付诸行动去实现它,只有这样才能更快的成长!