自定义PopupWindow实现下拉选择框并进行选择数据传递

〇、前言

PopupWindow在Android中是一个常用且极具生命力的控件,在好多地方都能看见,而且这几年Android技术一直更新迭代也没有PopupWindow的替代品出现。PopupWindow类似于Dialog,但是使用起来比Dialog则更加灵活,今天有空将自己在项目中的自定义PopupWindow做一个记录,实现起来其实挺简单的,但是细节还是不少。

自定义PopupWindow实现下拉选择框并进行选择数据传递_第1张图片

一、自定义PopupWindow

package com.mliuxb.popupdemo;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * Description: MyPopupWindow
 * Copyright  : Copyright (c) 2021
 * Author     : mliuxb
 * Date       : 2021-05-01 21:17:06
 */
public final class MyPopupWindow extends PopupWindow {
    private static final String TAG = "MyPopupWindow";
    private final TextView mTextView;//用于PopupWindow定位的TextView

    public MyPopupWindow(@NonNull Context context, @NonNull TextView textView) {
        super(context);
        this.mTextView = textView;
        setContentView(context);
        setWidth(textView.getWidth());
        setHeight(dip2px(context, 200));
        setFocusable(true);
        setBackgroundDrawable(new ColorDrawable());
    }


    public void setContentView(@NonNull Context context) {
        final RecyclerView recyclerView = new RecyclerView(context);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        final DividerItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
        itemDecoration.setDrawable(context.getResources().getDrawable(R.drawable.shape_recycler_list_divider_orange));
        recyclerView.addItemDecoration(itemDecoration);
        recyclerView.setAdapter(new PopupAdapter());
        recyclerView.setBackgroundResource(R.drawable.shape_orange_rectangle_stroke_base);
        setContentView(recyclerView);
    }

    private class PopupAdapter extends RecyclerView.Adapter {

        @NonNull
        @Override
        public PopupHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            final Context context = parent.getContext();//context是当前Activity的对象
            final int dip10 = dip2px(context, 10);
            //final int dip15 = dip2px(context, 15);
            final TextView textView = new TextView(context);
            textView.setWidth(mTextView.getWidth());
            textView.setTextSize(18);
            //textView.setTextColor(context.getResources().getColor(R.color.blue_base));
            textView.setTextColor(context.getResources().getColorStateList(R.color.selector_text_blue_orange));
            textView.setPadding(dip10, dip10, dip10, dip10);
            //textView.setBackgroundResource(R.drawable.selector_recycler_item_gray_sky);
            return new PopupHolder(textView);
        }

        @Override
        public void onBindViewHolder(@NonNull final PopupHolder holder, int position) {
            final String[] selectItem = selectArr[position];
            holder.textView.setTag(R.id.UID, selectItem[0]);
            holder.textView.setTag(R.id.UTYPE, selectItem[1]);
            holder.textView.setText(selectItem[2]);

            holder.textView.setOnClickListener(v -> {
                mTextView.setTag(R.id.UID, holder.textView.getTag(R.id.UID));
                mTextView.setTag(R.id.UTYPE, holder.textView.getTag(R.id.UTYPE));
                mTextView.setText(holder.textView.getText());
                if (isShowing()) {
                    dismiss();
                }
            });
        }

        @Override
        public int getItemCount() {
            return selectArr.length;
        }
    }

    private static class PopupHolder extends RecyclerView.ViewHolder {

        private final TextView textView;

        private PopupHolder(@NonNull TextView textView) {
            super(textView);
            this.textView = textView;
        }
    }

    // 将dip或dp值转换为px值
    private int dip2px(Context context, double dipValue) {
        final double scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    //数组静态初始化:给出初始化值,由系统决定长度
    private final String[][] selectArr = {
            {"3", "LEADER", "张三"},
            {"4", "WORKER", "李四"},
            {"5", "WORKER", "王五"},
            {"6", "WORKER", "周六"},
            {"7", "WORKER", "赵七"},
            {"8", "WORKER", "刘八"}
    };
}

说明:

  • 首先一般情况下我们都是针对一个TextView控件选择数据,所以在构造方法中将这个TextView传递进来,这样做有两个好处:其一是方便将PopupWindow的宽度设置为该TextView的宽度,其二是方便将选择的数据之间绑定到该TextView上,不用多余再声明其他变量,方便业务处理;
  • 其次PopupWindow中使用了RecyclerView,RecyclerView的条目是TextView,这些控件都是new出来的,并没有使用布局文件以及布局填充器,这样自定义的PopupWindow消耗资源更少;
  • 最后选择的数据是直接使用View.setTag()方法绑定在原TextView上的,数据传递极其方便。

三、使用

    private PopupWindow mPopupWindow;
    
    public void onClick(View view) {
        final int viewId = view.getId();
        if (viewId == R.id.tv_select_user) {
            if (mPopupWindow == null) { //用户可能多次点击,不必重复创建对象
                mPopupWindow = new MyPopupWindow(MainActivity.this, (TextView) view);
            }
            mPopupWindow.showAsDropDown(view);//显示PopupWindow小弹窗
        }
    }

使用也是非常的方便。

代码:https://github.com/beita08/MyPopupDemo

你可能感兴趣的:(PopupWindow,Android,PopupWindow,自定义)