栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android下拉选择弹窗

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android下拉选择弹窗

起因呢又是有个需求,也是自己觉得好看,很多app都有下拉选择框,就想着实现下(主要是时间空闲,如果时间少,项目急,就找现成的),先看图片:

直接上代码:
xml:

    

attrs:这个属性的作用是在内容较长的情况下保持底部距离

    
        
    

view:

package com.yinp.proapp.module.work.view;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.frameLayout;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.yinp.proapp.R;
import com.yinp.proapp.utils.AppUtils;


public class DownSelectDialogView extends frameLayout {
    private int contentWidth;
    private int contentHeight;
    
    private boolean isFirstLoad = false;
    
    private boolean isCanEnd = false;
    
    private boolean isStarting = false;
    
    private long duration = 400;
    
    private Rect rectContent;


    public DownSelectDialogView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DownSelectDialogView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public DownSelectDialogView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initFirstView(attrs);
    }

    private frameLayout dialogContentView;
    private RelativeLayout dialogBgView;
    private int bottomMargin = 100;

    private void initFirstView(AttributeSet attrs) {
        setVisibility(GONE);
        isFirstLoad = true;

        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DownSelectDialogView);
        bottomMargin = ta.getInteger(R.styleable.DownSelectDialogView_dsdvBottomMargin, bottomMargin);
        ta.recycle();

        dialogBgView = new RelativeLayout(getContext());
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        dialogBgView.setLayoutParams(layoutParams);
        dialogBgView.setBackgroundColor(Color.BLACK);
        addView(dialogBgView, 0);

        dialogContentView = new frameLayout(getContext());
        LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams2.bottomMargin = AppUtils.dpToPx(getContext(), bottomMargin);
        dialogContentView.setLayoutParams(layoutParams2);
        addView(dialogContentView, 1);
    }

    public void mAddView(View child) {
        if (dialogContentView != null) {
            dialogContentView.addView(child);
        }
    }

    private String mFlag = "";

    public void mAddView(View child, String flag) {
        if (child != null && dialogContentView != null) {
            boolean isDiff = mFlag.equals(flag);
            if (!isDiff) {
                mRemoveView();
                dialogContentView.addView(child);
            }
            startAnimations(isDiff);
            mFlag = flag;
        }
    }

    public void mRemoveView() {
        if (dialogContentView != null && dialogContentView.getChildCount() > 0) {
            dialogContentView.removeAllViews();
        }
    }

    
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (getChildCount() != 2) {
            return;
        }
        if (isFirstLoad) {
            isFirstLoad = false;
            rectContent = new Rect();
        } else {
            contentWidth = dialogContentView.getWidth();
            contentHeight = dialogContentView.getHeight();

            rectContent.left = dialogContentView.getLeft();
            rectContent.top = dialogContentView.getTop();
            rectContent.right = dialogContentView.getRight();
            rectContent.bottom = dialogContentView.getBottom();

            dialogContentView.layout(0, 0, contentWidth, contentHeight);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!rectContent.contains((int) event.getX(), (int) event.getY())) {
                    endAnimation();
                }
                break;
        }
        //必须对点击事件进行拦截
        return true;
    }

    
    public void startAnimations(boolean isDiff) {
        if (isStarting || !isEnd) {
            return;
        }
        setVisibility(VISIBLE);
        if (!isDiff) {
            dialogContentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    contentHeight = dialogContentView.getHeight();
                    start();
                    getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            });
        } else {
            start();
        }
    }

    private void start() {
        //清理动画
        dialogContentView.clearAnimation();
        dialogBgView.clearAnimation();
        isCanEnd = false;
        isStarting = true;

        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(dialogBgView, "alpha", 0, 0.4f);
        ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(dialogContentView, "translationY", -contentHeight * 1.0f, 0f);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(alphaAnimator, translationAnimator);
        animatorSet.setDuration(duration);
        animatorSet.start();
        if (animatorSet.isStarted()) {
            isCanEnd = true;
        }
    }

    private boolean isEnd = true;

    
    public void endAnimation() {
        //目的时判断当前是否有开启动画,有才允许关闭动画
        if (!isCanEnd) {
            return;
        }
        //清理动画
        dialogContentView.clearAnimation();
        dialogBgView.clearAnimation();
        isCanEnd = false;
        isEnd = false;
        isStarting = false;

        ObjectAnimator alphaOb = ObjectAnimator.ofFloat(dialogBgView, "alpha", 0.4f, 0f);
        ObjectAnimator translationYOb = ObjectAnimator.ofFloat(dialogContentView, "translationY", 0f, 1.0f * (-contentHeight));
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(alphaOb, translationYOb);
        animatorSet.setDuration(duration);
        animatorSet.start();
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                setVisibility(GONE);
                isEnd = true;
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }

    
    private OnDialogOpenListener onDialogOpenListener;

    public interface OnDialogOpenListener {
        void onDialogOpen(boolean isOpen);
    }

    public void setOnDialogOpenListener(OnDialogOpenListener onDialogOpenListener) {
        this.onDialogOpenListener = onDialogOpenListener;
    }

    
    public void setDuration(long duration) {
        this.duration = duration;
    }

    public boolean isStarting() {
        return isStarting;
    }
}


activity:

public class DownSelectDialogActivity extends AppbaseFragmentActivity {
    View viewOne;
    View viewTwo;

    //onCreate调用的方法
    @Override
    protected void initViews() {
        setStatusBarHeight(StatusBarUtil.getStatusBarHeight(mContext));
        bd.btnOne.setOnClickListener(v -> {
            bd.dsdDialog.mAddView((viewOne == null ? initViewOne() : viewOne), "viewOne");
        });
        bd.btnTwo.setOnClickListener(v -> {
            bd.dsdDialog.mAddView((viewTwo == null ? initViewTwo() : viewTwo), "viewTwo");
        });
//        dsvView.endAnimation();可以通过调用主动结束
    }

    private View initViewOne() {
        viewOne = LayoutInflater.from(this).inflate(R.layout.layout_one_one, null);
        //可处理逻辑
        return viewOne;
    }

    private View initViewTwo() {
        viewTwo = LayoutInflater.from(this).inflate(R.layout.layout_one_two, null);
        //可处理逻辑
        return viewTwo;
    }
}

直接拿来就可以用,没有做所有情况的适配,自己用可以修改。因为是模拟的弹窗效果,实际上是布局,所以需要在layout中添加它的布局。还有另外一种方案使用poupwindow
,但是popupWindow.setAnimationStyle(R.style.popwin_anim_style);只能这样使用这种动画设置,就是透明度变化,而不能做到根据位置来实现平移动画,所以放弃了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/643282.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号