欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

荐 最全AltertDialog 你只需要这一篇就够了

程序员文章站 2022-05-07 19:17:03
简单介绍一下自己,大三学生党一枚!主攻Android开发,对于Web和后端均有了解。个人语录:取乎其上,得乎其中,取乎其中,得乎其下,以*态度写好一篇的博客。AlterDialog详解一.AlertDialog的基础知识1.1 AlertDialog的构造函数1.2 辅助类函数介绍1.3 AlertDialog的一些问题1.3.1 dialog.show()和builder.show()的区别1.3.2 builder的一系列设置方法是怎么添加到dialog中的?1.3.3 AlertDialog的...

简单介绍一下自己,大三学生党一枚!主攻Android开发,对于Web和后端均有了解。
个人语录取乎其上,得乎其中,取乎其中,得乎其下,以*态度写好一篇的博客。


AlertDialog在实际开发过程中经常用到,并且根据场景不同,设计的提示也大相径庭,前几天我遇到一个需求:弹出提示的同时播放铃声,本来以为很简单,过程跌宕起伏让人抓狂!在这本该陪女盆友的一天,我却在写博客(说的我好像有女盆友一样!)

荐
                                                        最全AltertDialog 你只需要这一篇就够了

一.AlertDialog的基础知识

1.1 AlertDialog的构造函数

AlertDialog大体上来说有两个重载构造函数

//只需要传入上下文context即可,最后会调用具有默认布局的第二个构造函数。
 AlertDialog.Builder alertDialog1 = new AlertDialog.Builder(Context context);
//传入上下文,同时传入自定义的布局
 AlertDialog.Builder alertDialog2 = new AlertDialog.Builder(context, R.layout.xxx);

1.2 辅助类函数介绍

  builder.setMessage(CharSequence char);
  //设置提示信息,传入字符串即可
  builder.setIcon(Drawable drawable|int id);
  //设置提示的图标,可以传入资源id,也可以传入Drawable对象
  builder.setTitle(CharSequence char|int id);
  //设置提示的标题,传入字符串或者id
  builder.setView();
  //设置对话框内容为自定义view,仅设置内容区
  builder.setContentView();
  //设置对话框为自定义view,设置全部
  builder.setInverseBackgroundForced();
  //已经被弃用,用来更改默认的背景颜色
  builder.setCustomTitle();
  //自定义Title,可设置背景颜色
  builder.setCancelable(true);
  //如果设置为true则是可取消,点击屏幕其他区域,提示框自动消失,若设置false则不可
  builder.setAdapter()
  //设置对话框内容为自定义列表框
  builder.setItems(int id,Listener listener)
  //设置对话框为简单列表项,传入一个资源数组id和一个列表监听器
  builder.setMultiChoiceItems();
  //该方法也是简单列表,传入一个数组和一个boolean类型数组和一个监听器
   

函数真的好多,为了写博客一一验证,改了很多次描述,现在应该比较贴切了
荐
                                                        最全AltertDialog 你只需要这一篇就够了

1.3 AlertDialog的一些问题

AlertDialog.Builder(context).create()的返回值为AlertDialog,但是AlertDialog并不能直接实例化,需要借助AlertDialog.Builder来创建。我们简单的浏览几个重要的源码片段来学习他们的不同。

1.3.1 dialog.show()和builder.show()的区别

public AlertDialog show() {
//在内部创建dialog,最后调用dialog.show(),也就是说builder.show()是调用dialog.show()方法的
            final AlertDialog dialog = create();
            dialog.show();
            return dialog;
        }

1.3.2 builder的一系列设置方法是怎么添加到dialog中的?


    public static class Builder {
    //在builder内部有一个 成员变量P,看名字就知道是“关于显示(dialog)的一些列参数”
    //从builder.create()中可以得到验证
        @UnsupportedAppUsage
        private final AlertController.AlertParams P;
        }

 public AlertDialog create() {
           
            final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
            P.apply(dialog.mAlert);
            //设置dialog的一些列细节信息,如icon,message,都是在Builder中进行设置的,
            //最后调用builder.create()方法,把所有信息传递给dialog
            dialog.setCancelable(P.mCancelable);
            if (P.mCancelable) {
                dialog.setCanceledOnTouchOutside(true);
            }
            dialog.setOnCancelListener(P.mOnCancelListener);
            dialog.setOnDismissListener(P.mOnDismissListener);
            if (P.mOnKeyListener != null) {
                dialog.setOnKeyListener(P.mOnKeyListener);
            }
            return dialog;
        }

1.3.3 AlertDialog的默认布局是如何的?

先用一张图来展示

荐
                                                        最全AltertDialog 你只需要这一篇就够了


之前提到setView()方法可以设置内容区,内容区是在message下面,Buttton上面的一块区域。而setContentView()则可以设置整块区域。可以通过设置style修改默认的AlertDialog的背景。setCustomTitle()其实就是修改setTitle这块的内容,可以传入TextView,并设置TextView的颜色,这样就可以改变默认背景的颜色。

1.3.4 unable to add window的异常

荐
                                                        最全AltertDialog 你只需要这一篇就够了
解决方案:查看传入的Context是否正确。


荐
                                                        最全AltertDialog 你只需要这一篇就够了

二.AlertDialog的实战情景

2.1 消息提示型

简单描述:消息提示类没有复杂的操作,可能只有一个“我知道了”的按钮,是最简单的一种提示。但是默认的提示太丑了,先贴出默认提示,最后再自定义一个消息提示。

  AlertDialog.Builder builder =createMessageDialog(v.getContext());
                builder.setIcon(R.drawable.photo);
                builder.setMessage("明天上午10点,xxx约您在*见面");
                builder.setTitle("重要通知");
                builder.setPositiveButton("我知道了", new AlertDialog.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "您已接受邀请,请准时赴约", Toast.LENGTH_SHORT).show();
                        //这里可以做一些其他操作
                    }
                });
                builder.show();

效果图如下:
荐
                                                        最全AltertDialog 你只需要这一篇就够了


这个提示的代码很简单,下面贴一个自定义的消息提示,时间匆忙,没有做的很好看。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    android:background="#888888"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:gravity="center_horizontal"
        android:text="重要通知"
        android:textColor="#EEEEEE"
        android:layout_marginTop="8dp"
        android:textSize="22sp"
        android:layout_width="match_parent"
        android:layout_height="40dp">
    </TextView>
    <TextView
        android:layout_marginTop="10dp"
        android:gravity="center_horizontal"
        android:textSize="18sp"
        android:textColor="#CCCCCC"
        android:text="明天上午10点,xxx约您在见面"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </TextView>
    <Button
        android:gravity="center_horizontal"
        android:text="我知道了"
        android:textSize="16sp"
        android:layout_marginTop="30dp"
        android:background="@null"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </Button>
</LinearLayout>
 AlertDialog.Builder builder =createMessageDialog(v.getContext());
                  builder.setView(R.layout.layout_alert);
                  builder.show();
                  //三行代码加布局搞定一切

效果图展示:
荐
                                                        最全AltertDialog 你只需要这一篇就够了
如果需要添加Button的点击,可以通过android:onClick="xxx";并在代码中声明该方法即可。

2.2 逻辑操作型

逻辑操作类型,其实就是底部多了很多按钮,可以进行不同的操作,代码如下:

                AlertDialog.Builder builder =createMessageDialog(v.getContext());
                View view = getLayoutInflater().inflate(R.layout.layout_alert, null);
                builder.setView(view);
                TextView textView = new TextView(v.getContext());
                textView.setText("Android");
                builder.setCancelable(true);
                textView.setBackgroundColor(getResources().getColor(R.color.colorAccent));
                builder.setCustomTitle(textView);
                builder.setNegativeButton("取消", new AlertDialog.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "您点击了取消", Toast.LENGTH_SHORT).show();
                    }
                });
                builder.setPositiveButton("确定", new AlertDialog.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "您点击了确定", Toast.LENGTH_SHORT).show();
                    }
                });
                builder.setNeutralButton("中立的", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "您点击了中立", Toast.LENGTH_SHORT).show();
                    }
                });
                builder.setView(R.layout.layout_alert);
                builder.show();

效果图如下
荐
                                                        最全AltertDialog 你只需要这一篇就够了
这里同样也可以自定义,只需要和之前那样,声明按钮的点击方法即可,就不再演示。

2.3 列表选择型


                builder.setTitle("选择你最喜爱的城市");
                builder.setMultiChoiceItems(province, new boolean[]{true, true, true},
                        new OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                                switch (which) {
                                    case 0:
                                        Toast.makeText(getApplicationContext(), "您选择了A", Toast.LENGTH_SHORT).show();
                                        break;
                                    case 1:
                                        Toast.makeText(getApplicationContext(), "您选择了B", Toast.LENGTH_SHORT).show();
                                        break;
                                    case 2:
                                        Toast.makeText(getApplicationContext(), "您选择了c", Toast.LENGTH_SHORT).show();
                                        break;
                                }
                            }
                        });
                builder.show();



效果展示:


荐
                                                        最全AltertDialog 你只需要这一篇就够了


这里做一个仿网易云播放列表的案例

  builder2.setIcon(R.drawable.play);
                TextView textView1 = new TextView(getApplicationContext());
                textView1.setText("播放列表");
                textView1.setTextSize(22);
                builder2.setCustomTitle(textView1);
                //顶部已经设置好
                String[] songs = new String[]{"演员","聊表心意","花儿与少年","天后","狐狸","七里香","一路向北"};
                String[] singers = new String[]{"薛之谦","薛之谦","薛之谦","陈势安","薛之谦","周杰伦","周杰伦"};
                int[] photo = new int[]{R.drawable.xue,R.drawable.xue,R.drawable.xue,R.drawable.chen,R.drawable.xue,R.drawable.zhou,R.drawable.zhou};
                View view1 = getLayoutInflater().inflate(R.layout.layout_alert, null);
                RecyclerView recyclerView = view1.findViewById(R.id.recyclerview);
                SongAdapter adapter = new SongAdapter(photo, songs, singers, getApplicationContext());
                recyclerView.setAdapter(adapter);
                recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                builder2.setView(view1);
                builder2.show();

layout_alert

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

song_item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp">
    <ImageView
        android:layout_margin="6dp"
        android:id="@+id/singer_photo"
        android:src="@drawable/xue"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:scaleType="fitXY">
    </ImageView>
    <LinearLayout
        android:id="@+id/song"
        android:layout_toRightOf="@id/singer_photo"
        android:orientation="vertical"
        android:layout_marginLeft="16dp"
        android:layout_width="wrap_content"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/songs"
            android:textSize="20sp"
            android:text="认真的雪"
            android:textColor="#000000"
            android:layout_marginTop="5dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </TextView>
        <TextView
            android:id="@+id/singer"
            android:textSize="16sp"
            android:text="薛之谦"
            android:textColor="#555555"
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </TextView>
    </LinearLayout>


        <ImageView
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:scaleType="center"
            android:layout_marginRight="42dp"
            android:src="@drawable/start"></ImageView>

        <ImageView
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:scaleType="center"
            android:src="@drawable/more"></ImageView>
</RelativeLayout>

SongAdapter

 class SongAdapter extends RecyclerView.Adapter<ViewHolder>{
        private int[] photos;
        private String[] songs;
        private String[] singers;
        private Context context;

        public SongAdapter(int[] photos,String[] songs,String[] singers,Context context){
            this.photos=photos;
            this.songs=songs;
            this.singers=singers;
            this.context=context;
        }


        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(context).inflate(R.layout.song_item,null);
            ViewHolder viewHolder = new ViewHolder(view);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
             holder.imageView.setImageDrawable(getResources().getDrawable(photos[position]));
             holder.songs.setText(songs[position]);
             holder.singer.setText(singers[position]);
        }


        @Override
        public int getItemCount() {
            return photos.length;
        }

    }

    class ViewHolder extends RecyclerView.ViewHolder{
        ImageView imageView;
        TextView songs;
        TextView singer;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.singer_photo);
            songs = itemView.findViewById(R.id.songs);
            singer = itemView.findViewById(R.id.singer);
        }
    }

效果图,差的不是一点半点哈哈哈哈哈

荐
                                                        最全AltertDialog 你只需要这一篇就够了



荐
                                                        最全AltertDialog 你只需要这一篇就够了


2.4 自定义提示

自定义提示其实上面已经用到过了,比如自定义的消息提示,自定义的网易云播放列表等,最终要的是思想,我们可以把自定义的布局当成Activity的布局去设计他,大部分情况下,都是可用的。

提一个小案例:淘宝软件上,我们在点击查看已发货时,会弹出一个提示,类似于ViewPager+Fragment结合设计的功能更加复杂的AlertDialog
荐
                                                        最全AltertDialog 你只需要这一篇就够了


自定义提示的步骤如下:

第一步:根据需求,自定义Layout布局
第二步:根据逻辑,将Layout布局转换成view,初始化布局中需要改变的控件。

View view1 = getLayoutInflater().inflate(R.layout.layout_alert, null);
                RecyclerView recyclerView = view1.findViewById(R.id.recyclerview);

第三步:添加事件逻辑,如点击,选择,改变UI等。


2.5 封装提示类

提示在应用中比较常用,建议把AlertDialog封装起来,使用更方便。下面封装一个自定义类型的AlertDialog

public static AlertDialog.Builder 
    createMessageDialog(Context context,String title,String message, int photoId, int layoutId,boolean setview){
       AlertDialog.Builder builder = new AlertDialog.Builder(context);
       if(title!=null){
           builder.setTitle(title);
       }
       if(message!=null){
           builder.setMessage(message);
       }
       try{
            Drawable drawable = context.getResources().getDrawable(photoId);
            builder.setIcon(drawable);
       }catch (NullPointerException e){
            //do something
       }
        View view = LayoutInflater.from(context).inflate(layoutId, null);
       if(setview){
           //设置内容布局
           builder.setView(view);
       }else{
           //设置setContentView,要找builder.show()以后调用
       }
       return builder;
    }

三.AlertDialog高级进阶

3.1 设置AlertDialog入场出场动画

先上效果图:
荐
                                                        最全AltertDialog 你只需要这一篇就够了
这个效果非常简单,就是通过设置动画进行实现的,请看下列实现代码

//this关键字很重要,使用getApplicationContext会出错。
AlertDialog.Builder builder =new AlertDialog.Builder(this);
                builder.setIcon(R.drawable.photo);
                builder.setMessage("明天上午10点,XXX约您在见面");
                builder.setTitle("重要通知");
                builder.setPositiveButton("我知道了", new AlertDialog.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(getApplicationContext(), "您点击了确定", Toast.LENGTH_SHORT).show();
                    }
                });

                Dialog dialog = builder.create();
                //在这里指定动画
                dialog.getWindow().getAttributes().windowAnimations = R.style.dialogWindowAnim;
                dialog.show();

style.xml

 <style name="dialogWindowAnim" parent="android:Animation" mce_bogus="1">  
                <item name="android:windowEnterAnimation">@anim/dialog_enter_anim</item>  
                <item name="android:windowExitAnimation">@anim/dialog_exit_anim</item>  
    </style>

两个简单的动画

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="1000" >
</translate>

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="100"
     android:fromXDelta="0"
     android:fromYDelta="1000"
     android:toXDelta="0"
     android:toYDelta="0" >
</translate>

3.2 待补充

四 .小结

这篇博客耗时两天,总结了AlertDialog的大部分问题,时间有限,如有错误,请各位前辈指出,感谢各位看官。

先别走,我有一个资源学习群要推荐给你,它是白嫖党的乐园,小白的天堂!
荐
                                                        最全AltertDialog 你只需要这一篇就够了
别再犹豫,一起来学习!
荐
                                                        最全AltertDialog 你只需要这一篇就够了

本文地址:https://blog.csdn.net/weixin_43927892/article/details/106264157