这里使用了BottomSheetDialog,需要在app的.gradle中依赖implementation'com.google.android.material:material:1.0.0'
我们创建一个bean对象,里面的数据必须实现 Cloneable, Parcelable ,并添加成员变量 public CharSequence s; 这个s要在数据生成好后初始化好,并赋值在adapter中显示的内容,作为筛选之用。
public class SelectedBeanimplements Cloneable, Parcelable {
public Stringname;
public Stringcode;
public CharSequences;
public SelectedBean(String name, String code) {
this.name = name;
this.code = code;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest,int flags) {
dest.writeString(this.name);
dest.writeString(this.code);
}
public SelectedBean() {
}
protected SelectedBean(Parcel in) {
this.name = in.readString();
this.code = in.readString();
}
public static final Parcelable.CreatorCREATOR =new Parcelable.Creator() {
@Override
public SelectedBean createFromParcel(Parcel source) {
return new SelectedBean(source);
}
@Override
public SelectedBean[] newArray(int size) {
return new SelectedBean[size];
}
};
@Override
public SelectedBean clone()throws CloneNotSupportedException {
return (SelectedBean)super.clone();
}
}
//初始化bean数据:
list.add(new SelectedBean("北京",0+""));
list.add(new SelectedBean("上海",1+""));
list.add(new SelectedBean("广州",2+""));
list.add(new SelectedBean("深证",3+""));
list.add(new SelectedBean("杭州",4+""));
list.add(new SelectedBean("南京",5+""));
list.add(new SelectedBean("合肥",6+""));
list.add(new SelectedBean("苏州",7+""));
list.add(new SelectedBean("武汉",8+""));
list.add(new SelectedBean("无锡",9+""));
list.add(new SelectedBean("芜湖",10+""));
for (int i=0;i
//给s赋值
SelectedBean selectedBean =list.get(i);
selectedBean.s = selectedBean.name;//将名字同时赋值给s
}
然后是底部弹出的dialog
public class SelectedDialogextends BottomSheetDialogimplements View.OnClickListener, DialogInterface.OnDismissListener {
private ListmList;
private OnListenermListener;
private SelectedAdapterselectedAdapter;
private EditTextetSearch;
private TextViewtvFinish;
private RecyclerViewrecyclerView;
public SelectedDialog(@NonNull Context context, List list,OnListener mListener) {
super(context);
mList = list;
this.mListener = mListener;
View view = LayoutInflater.from(context).inflate(R.layout.dialog_bottom_sheet,null);
initView(view);
setContentView(view);
View parent = (View) view.getParent();
parent.setBackgroundColor(getContext().getResources().getColor(android.R.color.transparent));
BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
//这里最好采用灵活高低,不要写死
behavior.setPeekHeight(640);
setOnDismissListener(this);
SoftKeyboardStateHelper softKeyboardStateHelper =new SoftKeyboardStateHelper(view);
softKeyboardStateHelper.addSoftKeyboardStateListener(new SoftKeyboardStateHelper.SoftKeyboardStateListener() {
@Override
public void onSoftKeyboardOpened(int keyboardHeightInPx) {
//键盘打开
tvFinish.setVisibility(View.VISIBLE);
}
@Override
public void onSoftKeyboardClosed() {
tvFinish.setVisibility(View.VISIBLE);
}
});
}
private void initView(View view) {
etSearch = view.findViewById(R.id.search_et);
tvFinish = view.findViewById(R.id.finish_tv);
recyclerView = view.findViewById(R.id.recyclerView);
tvFinish.setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
selectedAdapter =new SelectedAdapter(mListener);
selectedAdapter.setData(mList);
recyclerView.setAdapter(selectedAdapter);
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s,int start,int count,int after) {
}
@Override
public void onTextChanged(CharSequence s,int start,int before,int count) {
selectedAdapter.getFilter().filter(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cancel:
dismiss();
break;
case R.id.finish_tv:
InputMethodManager imm = (InputMethodManager) UIUtil.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm !=null) {
imm.hideSoftInputFromWindow(etSearch.getWindowToken(),0);
}
//并将显示的数据还原,这里数据顺序不能反了
selectedAdapter.setData(mList);
etSearch.setText("");
break;
}
}
@Override
public void onDismiss(DialogInterface dialogInterface) {
//关闭dialog的回调
selectedAdapter.setData(mList);
etSearch.setText("");
}
public SelectedDialog(@NonNull Context context,int theme) {
super(context, theme);
}
protected SelectedDialog(@NonNull Context context,boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
public interface OnListener {
void onPicked(SelectedBean selectedBean);
}
然后是adapter ,这个adapter要实现implements Filterable,这个是筛选的关键,并在public Filter getFilter() {}这个方法中写筛选的逻辑,
public class SelectedAdapterextends RecyclerView.Adapterimplements Filterable {
private ListmList ;
private ListmFilterData =new ArrayList<>() ;
private SelectedDialog.OnListenermListener;
private SelectedBeanmSelectedBean;
public SelectedAdapter(SelectedDialog.OnListener listener) {
this.mListener= listener;
}
public void setData(List data) {
mList = data;
mFilterData = data;
notifyDataSetChanged();
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_selected,parent,false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder,int position) {
SelectedBean bean =mFilterData.get(position);
holder.tvName.setText(bean.s);
holder.tvName.setSelected(mSelectedBean !=null && TextUtils.equals(bean.code,mSelectedBean.code));
if (mSelectedBean !=null && TextUtils.equals(bean.code,mSelectedBean.code)) {
//选中的右边加一个选中符号,
holder.tvName.setCompoundDrawablesWithIntrinsicBounds(0,0, R.drawable.icon_selected,0);
}else {
holder.tvName.setCompoundDrawablesWithIntrinsicBounds(0,0,0,0);
}
}
@Override
public int getItemCount() {
return mFilterData ==null ?0 :mFilterData.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
if (TextUtils.isEmpty(charSequence)){
//没有过滤内容,使用原数据
}else {
//创建新集合
List filteredList =new ArrayList<>();
for (SelectedBean bean:mList){
//判断我们的名字之中是否包含charSequence(输入的字段)
if (bean.s.toString().contains(charSequence)){
SpannableString ss =new SpannableString(bean.s);
//检测到相同的文字,就显示红色
ForegroundColorSpan foregroundColorSpan =new ForegroundColorSpan(Color.parseColor("#ff0000"));
//输入的字符长度范围
int start =bean.s.toString().indexOf(charSequence.toString());
int end = start+charSequence.length();
ss.setSpan(foregroundColorSpan,start,end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try {
bean = bean.clone();
bean.s = ss;
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
filteredList.add(bean);//将包含的数据添加到过滤的集合中
}
}
mFilterData = filteredList;
}
FilterResults filterResults =new FilterResults();
filterResults.values =mFilterData;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilterData = (List) filterResults.values;//将最新的过滤的集合,显示在页面上
notifyDataSetChanged();
}
};
}
class MyViewHolderextends RecyclerView.ViewHolderimplements View.OnClickListener{
TextViewtvName;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_name);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int position = getAdapterPosition();
SelectedBean bean =mFilterData.get(position);
if (mListener !=null) {
if (mSelectedBean == bean) {
mSelectedBean =null;
}else {
mSelectedBean = bean;
}
mListener.onPicked(mSelectedBean);
}
notifyDataSetChanged();
}
}
}
//创建并回调:在activity或者fragment中
tvStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (selectedDialog ==null){
selectedDialog =new SelectedDialog(MainActivity.this,list,new SelectedDialog.OnListener() {
@Override
public void onPicked(SelectedBean selectedBean) {
if (selectedBean !=null) {
tvResult.setText(selectedBean.name);
}else {
tvResult.setText("选择城市");
}
selectedDialog.dismiss();
}
});
}
selectedDialog.show();
}
});