Customize PopupWindow to implement drop-down selection box and select data transfer

〇. Preface

PopupWindow is a commonly used and very vital control in Android, which can be seen in many places, and Android technology has been updated and iterated in recent years, and there is no substitute for PopupWindow. PopupWindow is similar to Dialog, but it is more flexible to use than Dialog. Today, I have time to make a record of my custom PopupWindow in the project. It is actually quite simple to implement, but there are still many details.

1. Customize 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<PopupHolder> {

        @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", "刘八"}
    };
}

illustrate:

  • First of all, in general, we select data for a TextView control, so passing in the TextView in the construction method has two advantages: one is to conveniently set the width of the PopupWindow to the width of the TextView, and the other is It is convenient to bind the selected data to the TextView, and there is no need to declare other variables redundantly, which is convenient for business processing;
  • Secondly, RecyclerView is used in PopupWindow, and the entry of RecyclerView is TextView. These controls are all new, and layout files and layout fillers are not used, so that the custom PopupWindow consumes less resources;
  • The last selected data is directly bound to the original TextView using the View.setTag() method, and the data transfer is extremely convenient.

Three, use

    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小弹窗
        }
    }

It is also very convenient to use.

Code: https://github.com/beita08/MyPopupDemo

Guess you like

Origin blog.csdn.net/beita08/article/details/116333729