Android 几种弹框样式 自定义Dialog PopupWindow的使用

1.弹框的波浪线是动态的 和小度弹框样式相似 用到PopWindow 和自定义View

.

2.这个弹框是动态的 用于网络加载时候  用到自定义Dialog

3.这就是一简单通用的弹框样式

 
第一种弹框实现方式:

private void showPopupWindow() {
    View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.popuplayout, null);
    mPopWindow = new PopupWindow(contentView,
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
    mPopWindow.setFocusable(true);
    mPopWindow.setOutsideTouchable(true);
    mPopWindow.setContentView(contentView);
    TextView tv_more_skill = contentView.findViewById(R.id.tv_more_skill);
    View rootview = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_main, null);
    mPopWindow.showAtLocation(rootview, Gravity.BOTTOM, 0, 0);}

xml布局 popuplayout


    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#00000000">

            android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:background="@drawable/yuyin_pop_shape">

                    android:layout_width="match_parent"
            android:layout_height="wrap_content">

                            android:layout_width="match_parent"
                android:layout_height="wrap_content">

                                    android:layout_width="match_parent"
                    android:layout_height="120dp"
                    android:layout_alignParentBottom="true" />

                                    android:id="@+id/tv_more_skill"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="16dp"
                    android:layout_marginTop="15dp"
                    android:text="请说出要搜索小区的名字..."
                    android:textColor="@color/RGB_FFFFFF"
                    android:textSize="18sp" />

           
       

   

自定义View  VolumeWaveView

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import java.util.Random;
public class VolumeWaveView extends View {
    private static final String TAG = "VolumeWaveView";
    private static final int HEIGHT = 360;//整个控件的高度

    private static final int HEIGHT1 = 60;//第一层曲线的高度
    private static final int HEIGHT2 = 40;//第二层曲线的高度
    private static final int HEIGHT3 = 50;//第三层曲线的高度

    private int h1 = 0,h2 = 0, h3 = 0,h4 = 0,h5 = 0;

    private int range = 0;//波动的幅度,你可以动态改变这个值,比如麦克风录入的音量的高低

    private Path path;
    private Paint paint1,paint2,paint3,paint4;

    private LinearGradient linearGradient1,linearGradient2,linearGradient3,linearGradient4;//四种渐变色

    private ValueAnimator animator1,animator2,animator3,animator4,animator5;//五种动画


    public VolumeWaveView(Context context) {
        this(context,null);
    }

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

    public VolumeWaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs,defStyleAttr);
        initPaint();
        startAnimation();
    }

    /**
     * 初始化画笔
     */
    private void initPaint(){
        path = new Path();

        paint1 = new Paint();
        paint1.setStyle(Paint.Style.FILL);
        paint1.setAntiAlias(true);//抗锯齿
        //渐变色1
        linearGradient1 = new LinearGradient(0, 0, 0, HEIGHT1,
                Color.parseColor("#e652a6d2"), Color.parseColor("#e652d5a1"), Shader.TileMode.MIRROR);
        paint1.setShader(linearGradient1);

        paint2 = new Paint();
        paint2.setAntiAlias(true);//抗锯齿
        paint2.setStyle(Paint.Style.FILL);
        //渐变色2
        linearGradient2 = new LinearGradient(0, 0, 0, HEIGHT2,
                Color.parseColor("#e68952d5"), Color.parseColor("#e6525dd5"), Shader.TileMode.MIRROR);
        paint2.setShader(linearGradient2);


        paint3 = new Paint();
        paint3.setAntiAlias(true);//抗锯齿
        paint3.setStyle(Paint.Style.FILL);
        //渐变色3
        linearGradient3 = new LinearGradient(0, 0, 0, HEIGHT3,
                Color.parseColor("#e66852d5"), Color.parseColor("#e651b9d2"), Shader.TileMode.MIRROR);
        paint3.setShader(linearGradient3);


        paint4 = new Paint();
        paint4.setAntiAlias(true);//抗锯齿
        paint4.setStyle(Paint.Style.FILL);
        //渐变色4
        linearGradient4 = new LinearGradient(0, 0, 0, HEIGHT2,
                Color.parseColor("#e6d5527e"), Color.parseColor("#e6bf52d5"), Shader.TileMode.MIRROR);
        paint4.setShader(linearGradient4);

    }


    /**
     * draw方法中不要创建大量对象,尽量复用对象
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawLayer3(canvas);
        drawLayer2(canvas);
        drawLayer1(canvas);

    }

    /**
     * 绘制第一层
     * @param canvas
     */
    private void drawLayer1(Canvas canvas){
        drawCurve(path,canvas,paint1,getWidth()/5,getWidth()/3,h1);
        drawCurve(path,canvas,paint1,getWidth()/3+getWidth()/5,getWidth()/3,h2);
    }

    /**
     * 绘制第二层
     * @param canvas
     */
    private void drawLayer2(Canvas canvas){
        drawCurve(path,canvas,paint2,0,getWidth()/2,h3);
        drawCurve(path,canvas,paint4,getWidth()/2-10,getWidth()/2,h4);

    }

    /**
     * 绘制第三层
     * @param canvas
     */
    private void drawLayer3(Canvas canvas){
        drawCurve(path,canvas,paint3,getWidth()/4,getWidth()/2,h5);
    }


    /**
     * 画贝塞尔曲线
     * @param path
     * @param canvas
     * @param x 横向起点的位置(用于摆放曲线的左右的位置)
     * @param width 曲线的整个宽度
     * @param height 曲线的高度
     */
    private void drawCurve(Path path,Canvas canvas,Paint paint,int x,int width,int height){
        path.reset();
        /*因为这个弧形(类似一个山峰的形状)
         * 其实就是三个贝塞尔曲线组成;
         * 而每个贝塞尔曲线需要三个点,三个点连接起来也就是两部分构成;
         * 所以,这三个贝塞尔曲线就是由六部分组成了(A,B,C,D,E,F,G),
         * 所以这里就平均分一下,建议用笔在纸上画一下,就晓得了**/
        int subWidth = width/6;//每小部分的宽度
        path.moveTo(x,HEIGHT);//起点 A
        path.quadTo(x+subWidth,HEIGHT-height,x+subWidth*2,HEIGHT-height*2);//B - C

        path.lineTo(x+subWidth*2,HEIGHT-height*2);//C
        path.quadTo(x+subWidth*3,HEIGHT-height*3,x+subWidth*4,HEIGHT-height*2);//D - E

        path.lineTo(x+subWidth*4,HEIGHT-height*2);// E
        path.quadTo(x+subWidth*5,HEIGHT-height,x+subWidth*6,HEIGHT);//F - G

        canvas.drawPath(path,paint);
    }

    /**
     * 添加属性动画,每一个动画的变化范围和周期都不一样,这样错开的效果才好看点
     */
    public void startAnimation() {
        Random random = new Random();
        range = random.nextInt(100)%(100-10+1) + 10;//波动的幅度,模拟动态音量输入,你可以自己设置

        animator1 = ValueAnimator.ofInt(0,HEIGHT1,0);
        animator1.setDuration(1400);
        animator1.setInterpolator(new DecelerateInterpolator());
        //无限循环
        animator1.setRepeatCount(ValueAnimator.INFINITE);
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                h1 = (int) animation.getAnimatedValue();
                invalidate();

            }
        });
        animator1.start();

        animator2 = ValueAnimator.ofInt(0,HEIGHT1,0);
        animator2.setDuration(1700);
        animator2.setInterpolator(new DecelerateInterpolator());
        //无限循环
        animator2.setRepeatCount(ValueAnimator.INFINITE);
        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                h2 = (int) animation.getAnimatedValue();
                invalidate();

            }
        });
        animator2.start();

 

        animator3 = ValueAnimator.ofInt(0,HEIGHT2,0);
        animator3.setDuration(1600);
        animator3.setInterpolator(new DecelerateInterpolator());
        //无限循环
        animator3.setRepeatCount(ValueAnimator.INFINITE);
        animator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                h3 = (int) animation.getAnimatedValue();
                invalidate();

            }
        });
        animator3.start();


        animator4 = ValueAnimator.ofInt(0,HEIGHT2,0);
        animator4.setDuration(1300);
        animator4.setInterpolator(new DecelerateInterpolator());
        //无限循环
        animator4.setRepeatCount(ValueAnimator.INFINITE);
        animator4.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                h4 = (int) animation.getAnimatedValue();
                invalidate();

            }
        });
        animator4.start();


        animator5 = ValueAnimator.ofInt(0,HEIGHT3,0);
        animator5.setDuration(2000);
        animator5.setInterpolator(new DecelerateInterpolator());
        //无限循环
        animator5.setRepeatCount(ValueAnimator.INFINITE);
        animator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                h5 = (int) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator5.start();
    }

    /**
     * 关闭动画
     */
    public void removeAnimation(){
        if (animator1 != null){
            animator1.cancel();
            animator1 = null;
        }
        if (animator2 != null){
            animator2.cancel();
            animator2 = null;
        }
        if (animator3 != null){
            animator3.cancel();
            animator3 = null;
        }
        if (animator4 != null){
            animator4.cancel();
            animator4 = null;
        }
        if (animator5 != null){
            animator5.cancel();
            animator5 = null;
        }
    }

}

第二种弹框实现方式

/**
 * 自定义dialog
 */

public class LoadingDialog extends Dialog {

    private Context context;
    private static LoadingDialog dialog;
    private static ImageView ivProgress;
    private static TextView tvText;

    public LoadingDialog(Context context) {
        super(context);
        this.context = context;
    }

    public LoadingDialog(Context context, int themeResId) {
        super(context, themeResId);
        this.context = context;

    }

    //显示dialog的方法
    public static LoadingDialog showDialog(Context context, String msg) {
        dialog = new LoadingDialog(context, R.style.LoadDialog);//dialog样式
        dialog.setContentView(R.layout.dialog_layout);//dialog布局文件
        tvText = dialog.findViewById(R.id.tvText);
        if (ValidationUtils.isNotEmpty(msg)) {
            tvText.setText(msg);
        }
        ivProgress = dialog.findViewById(R.id.ivProgress);
        dialog.setCanceledOnTouchOutside(false);//点击外部不允许关闭dialog
        return dialog;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus && dialog != null) {
            startAnimation();
        } else {
            endAnimation();
        }
    }

    @Override
    public void setOnDismissListener(@Nullable OnDismissListener listener) {
        super.setOnDismissListener(listener);
        endAnimation();
    }

    private void startAnimation() {
        Animation animation = AnimationUtils.loadAnimation(context, R.anim.umcsdk_anim_loading);
        ivProgress.startAnimation(animation);
    }

    private void endAnimation() {
        Animation animation = AnimationUtils.loadAnimation(context, R.anim.umcsdk_anim_loading);
        animation.cancel();
    }
}

style LoadDialog样式


xml 布局dialog_layout


    android:layout_width="match_parent"
    android:layout_height="match_parent">

            android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:background="@drawable/sy_sdk_shap_bg"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="15dp">

                    android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center">

                            android:id="@+id/ivProgress"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerInParent="true"
                android:background="@mipmap/loading_progress" />
       

                    android:id="@+id/tvText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:text="网络加载中..."
            android:textSize="16dp" />
   

drawable 背景sy_sdk_shap_bg


   
   

   
            android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />

mipmap 图片 loading_progress

anim 动画umcsdk_anim_loading


            android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="-1"
        android:toDegrees="359" />

代码中使用:

private LoadingDialog mLoadingDialog;

//显示Dialog

public void Dialog() {
    if (mLoadingDialog == null) {
        mLoadingDialog = LoadingDialog.showDialog(this, "");
    }
    mLoadingDialog.show();
}
//显示Dialog传入msg
public void ssDialog(String msg) {
    if (mLoadingDialog == null) {
        mLoadingDialog = LoadingDialog.showDialog(this, msg);
    }
    mLoadingDialog.show();
}
//销毁Dialog
public void hDialog() {
    if (mLoadingDialog != null) {
        mLoadingDialog.dismiss();
    }
}

第三种弹框实现方式:

 

1.ShowDialog

public class ShowDialog {

    private FamilyDialog customDialog;

    public ShowDialog() {

    }
    public void show(final Context context, String message, final OnBottomClickListener onBottomClickListener) {
        customDialog = new FamilyDialog(context);
        customDialog.setMessage(message);
        customDialog.setYesOnClickListener("确定", new FamilyDialog.onYesOnClickListener() {
            @Override
            public void onYesClick() {
                if (onBottomClickListener != null) {
                    onBottomClickListener.positive();
                }
                customDialog.dismiss();
            }
        });

        customDialog.setNoOnClickListener("取消", new FamilyDialog.onNoClickListener() {
            @Override
            public void onNoClick() {
                if (onBottomClickListener != null) {
                    onBottomClickListener.negative();
                }
                customDialog.dismiss();
            }
        });
        customDialog.show();

    }
    public void show2(final Context context, String message,String confirm, final OnBottomClickListener onBottomClickListener) {
        customDialog = new FamilyDialog(context);
        customDialog.setMessage(message);
        customDialog.setYesOnClickListener(confirm, new FamilyDialog.onYesOnClickListener() {
            @Override
            public void onYesClick() {
                if (onBottomClickListener != null) {
                    onBottomClickListener.positive();
                }
                customDialog.dismiss();
            }
        });

        customDialog.setNoOnClickListener("取消", new FamilyDialog.onNoClickListener() {
            @Override
            public void onNoClick() {
                if (onBottomClickListener != null) {
                    onBottomClickListener.negative();
                }
                customDialog.dismiss();
            }
        });
        customDialog.show();

    }
    public interface OnBottomClickListener {
        void positive();

        void negative();

    }
}

2.FamilyDialog

  private Button yes; //确定按钮
    private Button no; //取消按钮
//    private TextView title; //消息标题文本
    private TextView message; //消息提示文本
    private String titleStr; //从外界设置的title文本
    private String messageStr; //从外界设置的消息文本
    private String yesStr, noStr; //确定文本和取消文本的显示内容
    private Window window = null;
    private onYesOnClickListener yesOnClickListener; //确定按钮被点击了的监听器
    private onNoClickListener noOnClickListener; //取消按钮被点击了的监听器


    public FamilyDialog(@NonNull Context context) {
        super(context, R.style.CustomDialog);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_dialog_family);
        //点击dialog以外的空白处是否隐藏
        setCanceledOnTouchOutside(false);
        //初始化界面控件
        initView();
        //初始化界面数据
        initData();
        //初始化界面控件的事件
        initEvent();
        //设置窗口显示
        windowDeploy();
    }

    /**
     * 初始化界面控件
     */
    private void initView() {
        yes = (Button) findViewById(R.id.yes);
        no = (Button) findViewById(R.id.no);
//        title = (TextView) findViewById(R.id.title);
        message = (TextView) findViewById(R.id.message);
    }

    /**
     * 初始化界面控件的显示数据
     */
    private void initData() {
//        if (TextUtils.isEmpty(titleStr)) {
//            title.setText(titleStr);
//        } else {
//            title.setText("应用提示");
//        }
        if (messageStr != null) {
            message.setText(messageStr);
        }
        if (yesStr != null) {
            yes.setText(yesStr);
        }
        if (noStr != null) {
            no.setText(noStr);
        }
    }

    /**
     * 初始化界面的确定和取消监听器
     */
    private void initEvent() {
        //设置确定按钮被点击后,向外界提供监听
        yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (yesOnClickListener != null) {
                    yesOnClickListener.onYesClick();
                }
            }
        });

        //设置取消按钮被点击后,向外界提供监听
        no.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (noOnClickListener != null) {
                    noOnClickListener.onNoClick();
                }
            }
        });
    }

    private void windowDeploy() {
        window = getWindow();
        window.setGravity(Gravity.CENTER); //设置窗口显示位置
//        window.setWindowAnimations(R.style.dialogWindowAnim); //设置窗口弹出动画
    }

    /**
     * 设置确定按钮的显示内容和监听
     *
     * @param str
     * @param onYesOnClickListener
     */
    public void setYesOnClickListener(String str, onYesOnClickListener onYesOnClickListener) {
        if (str != null) {
            yesStr = str;
        }
        this.yesOnClickListener = onYesOnClickListener;
    }

    /**
     * 设置取消按钮的显示内容和监听
     *
     * @param str
     * @param onNoClickListener
     */
    public void setNoOnClickListener(String str, onNoClickListener onNoClickListener) {
        if (str != null) {
            noStr = str;
        }
        this.noOnClickListener = onNoClickListener;
    }

    /**
     * 从外界Activity为Dialog设置标题
     *
     * @param title
     */
    public void setTitle(String title) {
        titleStr = title;
    }

    /**
     * 从外界Activity为Dialog设置dialog的message
     *
     * @param message
     */
    public void setMessage(String message) {
        messageStr = message;
    }

    /**
     * 设置确定按钮和取消被点击的接口
     */
    public interface onYesOnClickListener {
        void onYesClick();
    }

    public interface onNoClickListener {
        void onNoClick();
    }
}

3.xml 布局 layout_dialog_family


    android:layout_width="match_parent"
    android:layout_height="match_parent">

            android:layout_width="270dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/bg_dialog_white_color"
        android:orientation="vertical">


                    android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="36dp"
            android:layout_marginRight="20dp"
            android:layout_marginBottom="30dp"
            android:drawableLeft="@mipmap/icon_notice"
            android:drawablePadding="5dp"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            android:text="提示消息"
            android:textColor="@color/RGB_000000"
            android:textSize="16sp" />


                    android:layout_width="match_parent"
            android:layout_height="48dp"
            android:orientation="horizontal">

                            android:id="@+id/no"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@drawable/bg_dialog_btn_left"
                android:gravity="center"
                android:singleLine="true"
                android:text="取消"
                android:textColor="@color/RGB_000000"
                android:textSize="16sp" />

                            android:id="@+id/yes"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:layout_weight="1"
                android:background="@drawable/bg_dialog_btn_right"
                android:singleLine="true"
                android:text="确认"
                android:textColor="@color/RGB_000000"
                android:textSize="16sp" />

       

   

4. bg_dialog_white_color



   

   

5. bg_dialog_btn_left



   

   

6. bg_dialog_btn_right



   

   

7.style 样式 CustomDialog


8.代码中使用

new ShowDialog().show(context, "想要写的提示语", new ShowDialog.OnBottomClickListener() {
    @Override
    public void positive() {
        //确定操作
    }

    @Override
    public void negative() {
        //取消操作
    }
});
————————————————
版权声明:本文为CSDN博主「徐玮大人」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mr___xu/article/details/94601837

你可能感兴趣的:(Android,开发)