实现一个通用的支持输入原因并且可以滑动消失的Dialog

package com.zdj.zdj_library.widget;

import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.PopupWindow;

import androidx.annotation.NonNull;

import com.zdj.zdj_library.R;
import com.zdj.zdj_library.util.UiUtils;
import com.zdj.zdj_library.view.TitleBar;

/**
 * <pre>
 *     author : zhangdj
 *     time   : 2021/07/12
 *     desc   : 原因弹框
 *              注:该弹框支持跟随手指向下滑动
 *              实现思路:自定义Dialog,重写onTouchEvent。在down的时候记录y,滑动的时候计算出滑动距离。scrollBy控制view(decorView,通过getWindow().getDecorView()得到dialog的decorView)的滑动。
 *              确保view不能往上滑动溢出,所以控制view.getScrollY大于0的时候重置。手指抬起的时候判断滑动方向如果是向下并且超过四分之一,隐藏dialog,然后重置view的内容的位置。
 *              通过改变mScrollY来变化view的位置,实际上view本身并没有发生移动,移动的是view的内容。view的内容和view本身的横向纵向距离就是mScrollX和mScrollY的值。
 * </pre>
 */
public class ReasonDialog extends Dialog {
    Context context;
    View view;

    public ReasonDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
        setContentView(R.layout.dialog_reason);
        Window window = getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.width = layoutParams.MATCH_PARENT;
        layoutParams.height = (int) (UiUtils.getHeight(context) * 0.6);
        window.setAttributes(layoutParams);
        window.setGravity(Gravity.BOTTOM);
        this.context = context;
        view = window.getDecorView();
    }

    public void init(final String title, final Callback callback) {
        TitleBar titleBar = findViewById(R.id.titleBar);
        titleBar.setViewVisible(false, false, false, true, true)
                .setTitleTvText(title)
                .setLeftTvText(this.context.getString(R.string.cancel))
                .setRightTvText(this.context.getString(R.string.confirm))
                .setLeftTvTextColor(this.context.getResources().getColor(R.color.light_gray_6))
                .setRightTvTextColor(this.context.getResources().getColor(R.color.blue));
        final EditText et_reason = findViewById(R.id.et_reason);
        UiUtils.setEditTextHintTextSize("200个字以内", 14, et_reason);
        titleBar.setClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (v.getId() == R.id.tv_left) {
                    dismiss();
                } else if (v.getId() == R.id.tv_right) {
                    dismiss();
                    if (callback != null) {
                        String reason = et_reason.getText().toString();
                        if (reason == null) {
                            reason = "";
                        }
                        callback.confirm(reason);
                    }
                }
            }
        });
    }

    float startY;
    float moveY;

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                moveY = event.getY() - startY;
                //传正值往上滑动,传负值往下滑动。这个在view的scrollBy、scrollTo方法源码解析里面已经分析过。
                view.scrollBy(0, -(int)moveY);
                startY = event.getY();
                if (view.getScrollY() > 0) {
                    view.scrollTo(0, 0);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (view.getScrollY() < -this.getWindow().getAttributes().height / 4) {
                    this.dismiss();
                }
                view.scrollTo(0,0);
                break;
        }
        return super.onTouchEvent(event);
    }



    public Callback callback;
    public interface Callback {
        void confirm(String reason);
    }
}

空闲之余,记录一下。代码里面很清晰,并且有注释。直接看代码即可。

猜你喜欢

转载自blog.csdn.net/zdj_Develop/article/details/119647091