DialogFragment 动态弹窗位置及 外部点击事件监听

847 阅读1分钟
package com.bochk.mortgage.ui.homepage.fragment;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bochk.mortgage.R;
import com.bochk.mortgage.base.BaseAppCompatDialogFragment;
import com.bochk.mortgage.base.BaseApplication;
import com.bochk.mortgage.databinding.FragmentHomeTypeFilterBinding;
import com.bochk.mortgage.databinding.ItemHomeTypeBinding;
import com.bochk.mortgage.utils.ImageUtil;

import java.util.ArrayList;

public class HomeTypeFilterBottomDialog extends BaseAppCompatDialogFragment {

    private FragmentHomeTypeFilterBinding binding;
    private ArrayList<Data> data;
    private Confirm confirm;
    private Close close;
    private int WINDOWPARAMS_Y;

    public void setWINDOWPARAMS_Y(int WINDOWPARAMS_Y) {
        this.WINDOWPARAMS_Y = WINDOWPARAMS_Y;
    }


    public HomeTypeFilterBottomDialog(ArrayList<Data> dataList, Confirm confirm,Close close) {
        this.data = dataList;
        this.confirm = confirm;
        this.close = close;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = FragmentHomeTypeFilterBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        binding.rvContent.setAdapter(new HomeTypeFilterAdapter());
        binding.rvContent.setLayoutManager(new LinearLayoutManager(requireActivity()));
        for (Data op : data) {
            if (op.isCheck()) {
                GradientDrawable drawable = new GradientDrawable();
                try {
                    drawable.setStroke(requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_1), Color.parseColor(op.strokeColor));
                    drawable.setColor(Color.parseColor(op.color));
                    float[] radii = new float[]{
                            0F, 0F,
                            0F, 0F,
                            requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20), requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20),
                            requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20), requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20),
                    };
                    drawable.setCornerRadii(radii);
                    binding.rvContent.setBackgroundDrawable(drawable);
                } catch (Exception e) {
                    drawable.setStroke(requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_1), Color.parseColor("#920022"));
                    drawable.setColor(Color.parseColor("#FFFFFF"));
                    float[] radii = new float[]{
                            0F, 0F,
                            0F, 0F,
                            requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20), requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20),
                            requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20), requireActivity().getResources().getDimensionPixelSize(R.dimen.dp_20),
                    };
                    drawable.setCornerRadii(radii);
                    binding.rvContent.setBackgroundDrawable(drawable);
                }
            }
        }
        binding.getRoot().setOnClickListener(v -> {
            if (getDialog() != null) {
                dismiss();
            }
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        // Make us non-modal, so that others can receive touch events.
        getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        // ...but notify us that it happened.
        getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        //getDialog().getWindow().getDecorView().setSystemUiVisibility(View.INVISIBLE);
        Window window = getDialog().getWindow();
        window.setGravity(Gravity.TOP);
        window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentWhite)));
        // window.setWindowAnimations(R.style.animate_dialog);
        WindowManager.LayoutParams windowParams = window.getAttributes();
        windowParams.dimAmount = 0.0f;
        windowParams.y = WINDOWPARAMS_Y;
        window.setAttributes(windowParams);
        Dialog dialog = getDialog();
        window.getDecorView().setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                int p = 0;
                for (int i = 0; i < data.size(); i++) {
                    if(data.get(i).isCheck()){
                        p=i;
                    }
                }
                close.close(data, p);
                dismiss();
            }
            return true;
        });
        if (dialog != null) {
            DisplayMetrics dm = new DisplayMetrics();
            requireActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
            dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
            dialog.getWindow().setAttributes(lp);
        }
    }




    @Override
    public void show(FragmentManager manager, String tag) {
        try {
            manager.beginTransaction().remove(this).commit();
            super.show(manager, tag);
        } catch (Exception e) {
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }


    public static class Data {
        private String title = "";
        private boolean check = false;
        private String url = "";
        private String color = "";
        private String strokeColor = "";

        public String getCheckedBg() {
            return checkedBg;
        }

        public void setCheckedBg(String checkedBg) {
            this.checkedBg = checkedBg;
        }

        private String checkedBg = "";

        public String getColor() {
            return color;
        }

        public void setColor(String color) {
            this.color = color;
        }

        public String getStrokeColor() {
            return strokeColor;
        }

        public void setStrokeColor(String strokeColor) {
            this.strokeColor = strokeColor;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }


        public Data() {
        }

        public Data(String title, String url) {
            this.title = title;
            this.url = url;
        }

        public Data(String title, boolean check, String url) {
            this.title = title;
            this.check = check;
            this.url = url;
        }

        public Data(String title, String url, String color, String strokeColor, String checkedBg) {
            this.title = title;
            this.url = url;
            this.color = color;
            this.strokeColor = strokeColor;
            this.checkedBg = checkedBg;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public boolean isCheck() {
            return check;
        }

        public void setCheck(boolean check) {
            this.check = check;
        }
    }

    private class HomeTypeFilterAdapter extends RecyclerView.Adapter<HomeTypeFilterAdapter.ViewHolder> {

        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(requireActivity()).inflate(R.layout.item_home_type, parent, false);
            return new ViewHolder(view);
        }

        @SuppressLint("RecyclerView")
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            Data obj = data.get(position);
            holder.binding.tvName.setText(obj.title);
            if (obj.isCheck()) {
                holder.binding.curtain.setVisibility(View.GONE);
                holder.binding.llSearch.setVisibility(View.GONE);
                holder.binding.viewDivider.setVisibility(View.GONE);
            } else {
                ImageUtil.setNormalGlide(requireActivity(), obj.url, R.mipmap.ic_default_icon, holder.binding.icon);
                holder.binding.curtain.setVisibility(View.GONE);
                holder.binding.llSearch.setVisibility(View.VISIBLE);
                holder.binding.viewDivider.setVisibility(View.VISIBLE);
                holder.binding.tvName.setTextColor(requireActivity().getResources().getColor(R.color.text_normal));
            }
            holder.binding.llSearch.setOnClickListener(v -> {
                for (Data op : data) {
                    op.setCheck(false);
                }
                holder.binding.getRoot().post(new Runnable() {
                    @Override
                    public void run() {
                        holder.binding.curtain.setVisibility(View.VISIBLE);
                        try {
                            holder.binding.curtain.setBackgroundColor(Color.parseColor(data.get(position).checkedBg));
                        } catch (Exception e) {
                        }
                        new Thread() {
                            @Override
                            public void run() {
                                super.run();
                                try {
                                    sleep(200);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                requireActivity().runOnUiThread(() -> {
                                    BaseApplication.app.getRedisBean().setHOME_TYPE_FILTER_POSITION(position);
                                    data.get(position).setCheck(true);
                                    notifyDataSetChanged();
                                    confirm.confirm(data, position);
                                    dismiss();
                                });
                            }
                        }.start();
                    }
                });
            });
        }

        @Override
        public int getItemCount() {
            return data.size();
        }

        class ViewHolder extends RecyclerView.ViewHolder {
            ItemHomeTypeBinding binding;

            public ViewHolder(@NonNull View itemView) {
                super(itemView);
                binding = ItemHomeTypeBinding.bind(itemView);
            }
        }
    }

    public interface Confirm {
        void confirm(ArrayList<Data> data, int position);
    }
    public interface Close {
        void close(ArrayList<Data> data, int position);
    }

}

动态计算高度 getLocationOnScreen(location) 当前控件距离屏幕坐标系的绝对坐标 0为x 1为y,控件坐标系默认左上角 , DialogFragment 默认是状态栏高度的。

int[] location = new int[2];
binding.clType.getLocationOnScreen(location);
homeTypeFilterBottomFragment.setWINDOWPARAMS_Y(location[1] + binding.clType.getHeight() - StatusBarTool.getStatusBarHeight(requireActivity()));
homeTypeFilterBottomFragment.show(getChildFragmentManager(), HomeTypeFilterBottomDialog.class.getName());