美文网首页
Dialog 笔记

Dialog 笔记

作者: chauI | 来源:发表于2017-03-03 16:42 被阅读480次
  • AlertDialog 实现
  • 从屏幕底部弹出对话框
  • 自定义效果
  • Activity 仿 Dialog 效果

部分参考 android 底部弹出提示框的实现方式

基础方法

构造方法
很好几个,要特别说的是这里的第二个,可以加载一个 style ,
是实现 dialog 宽度全屏的关键

Dialog(@NonNull Context context)
Dialog(@NonNull Context context, @StyleRes int themeResId) 

设置宽高
也可以直接使用数值

Window window = dialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);//设置 dialog 的宽高

设置动画
style 文件,下面会介绍
window.setWindowAnimations(R.style.dialog_anim);//设置动画效果

其他的方法

setTitle(@Nullable CharSequence title) //使用默认的标题
setCustomTitle(@Nullable View customTitleView) //传入一个布局,自定义样式
setIcon(@Nullable Drawable icon) //使用图标做标题
setMessage(@Nullable CharSequence message) // 在标题下按钮上的说明文字
setPositiveButton(CharSequence text, final OnClickListener listener) // 常用于"确定"按钮
setNegativeButton(CharSequence text, final OnClickListener listener) //常用于"取消"按钮
setCancelable(boolean cancelable) // 设置点击框外是否可以关闭,默认为可以
setItems(CharSequence[] items, final OnClickListener listener) //用这个实现简单的列表
setView(View view) //实现自定义的一个布局

监听事件


setOnCancelListener(OnCancelListener onCancelListener) 
setOnDismissListener(OnDismissListener onDismissListener)
setOnKeyListener(OnKeyListener onKeyListener)

AlertDialog 基础实现

一个不怎么标准的例子:
因为例子中是在 Fragment 中,通过 LayoutInflater 获取布局。
调用这个 openDialog() 方法即弹出对话框。

private void openDialog() {
    LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.change_password_dialog, null);
    final EditText originPasswordEt = (EditText) linearLayout.findViewById(R.id.origin_password);
    TextView forgetPassword = (TextView) linearLayout.findViewById(R.id.forget_password);
    final AlertDialog dialog = new AlertDialog.Builder(getContext())
        .setTitle("输入密码")
        .setView(linearLayout)
        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String originPassword = originPasswordEt.getText().toString().trim();
                //传到后台
            }
        })
        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        })
        .create();

    dialog.show();
    forgetPassword.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showToast("忘记密码");
            dialog.dismiss();
        }
    });
}

布局文件:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <LinearLayout android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_marginStart="24dp"
                  android:orientation="horizontal">

        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/origin_password"
                  android:textColor="@color/black_primary_dark"
                  android:textSize="16sp"/>

        <EditText android:id="@+id/origin_password"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_marginEnd="16dp"
                  android:layout_marginStart="32dp"
                  android:hint="@string/origin_password_hint"
                  android:inputType="textPassword"
                  android:lines="1"/>
    </LinearLayout>

    <TextView android:id="@+id/forget_password" android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginBottom="8dp"
              android:layout_marginStart="24dp"
              android:layout_marginTop="16dp"
              android:text="@string/forget_password"
              android:textColor="@color/small_text_color"
              android:textSize="16sp"/>

</LinearLayout>

出现的位置,与相应动画

弹出框出现在屏幕下方

Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);  //设置框的位置

弹出框会出现在屏幕下方,但屏幕的左右和下方都有一个小的空隙

图片源自[android 底部弹出提示框的实现方式](http://blog.csdn.net/wning1/article/details/51811513)

要使弹出框布不留有间隙,只改变布局的 layout_width 是不够的,这个是主题 style 导致的
新建一个 style:

<style name="Dialog_Full">
     <item name="android:windowFullscreen">true</item>
     <!-- 背景透明 -->
     <item name="android:windowBackground">@android:color/transparent</item>
     <!-- activity变暗 -->
     <item name="android:backgroundDimEnabled">true</item>
        
</style>

并让 dialog 引用这个 style

//在构造函数中引用 style
AlertDialog dialog = new AlertDialog.Builder(getContext(),R.style.Dialog_Full).create();
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);

//设置横向满屏,纵向自适应,没有这里弹出框会完全布满屏幕
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.WRAP_CONTENT);

弹出的动画和缩回的动画

//pop_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="100%p"
        android:toYDelta="0" />
    <alpha
        android:duration="@android:integer/config_shortAnimTime"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />
</set>

//pop_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromYDelta="0"
        android:toYDelta="100%p" />
</set>

还有一个 style:

<style name="dialog_anim" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/pop_in</item>
        <item name="android:windowExitAnimation">@anim/pop_out</item>
    </style>

设置引用这个 style:

Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setWindowAnimations(R.style.dialog_anim);//动画效果
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.WRAP_CONTENT);
dialog.show();//show 必须在 set 后面

效果图就不上了..

自定义效果

将这个控件封装好利于复用,并且可以自定义不同数目的 item 而不需要重写布局。
依然是参考 android 底部弹出提示框的实现方式,添加了一些改动

  • 支持放任意多个 Item,但只有文字内容
  • 选择是否左右无间隙
  • 选择是否有“取消”按钮
  • 选择是否可以点击外部关闭
  • 文字居中或者靠左

核心代码:



public static Dialog showItemSelectDialog() {
    final Dialog dialog;

    if (isFull){
        dialog = new Dialog(context,R.style.Dialog_Full);//传入布局改变主题
    }else {
        dialog = new Dialog(context);
    }

    View rootView = LayoutInflater.from(context).inflate(R.layout.layout_choice,null);
    LinearLayout contentsView = (LinearLayout) rootView.findViewById(R.id.dialog_content);
    //逐个添加 TextView
    for(int i = 0;i < contents.length;i++){
        View centerView = LayoutInflater.from(context).inflate(R.layout.dialog_center_item,null);
        TextView centerText = (TextView)  centerView.findViewById(R.id.dialog_center_item);
        final int finali = i;
        centerText.setText(contents[finali]);
        centerText.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                if (listener != null){
                    listener.getSelectedItem(contents[finali]);
                }
            }
        });
        if (isTextCenter){
            centerText.setGravity(Gravity.CENTER);//水平和垂直居中
        }else{
            centerText.setPadding(20,0,0,0);
            centerText.setGravity(Gravity.CENTER_VERTICAL);//垂直居中
        }
        contentsView.addView(centerView);
    }
    Button CancleBtn = (Button) rootView.findViewById(R.id.dialog_cancel);

    if (isBtnCancle){
        CancleBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    }else {
        CancleBtn.setVisibility(View.GONE);
    }

    dialog.setContentView(rootView);

    if (isCancelable){
        dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(true);
    }else {
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
    }

    Window window = dialog.getWindow();
    WindowManager.LayoutParams params = window.getAttributes();

    if (!(isCenter)){
        params.gravity = Gravity.BOTTOM;
    }
    params.width = WindowManager.LayoutParams.MATCH_PARENT;
    params.height = WindowManager.LayoutParams.WRAP_CONTENT;
    window.setAttributes(params);//设置 dialog 的宽高

    window.setWindowAnimations(R.style.dialog_anim);//设置动画效果

    dialog.show();

    return dialog;
}

只是很粗糙的实现,很多可以改进的地方。
但如果再继续折腾下去可能不还如直接用 popupwidow。

用 Activity 实现类似 Dialog 的效果

参考 Android中使用Dialog风格弹出框的Activity
在 style 新建:

<style name="dialogstyle">  
    <!--设置dialog的背景-->  
    <item name="android:windowBackground">@android:color/transparent</item>  
    <!--设置Dialog的windowFrame框为无-->  
    <item name="android:windowFrame">@null</item>  
    <!--设置无标题-->  
    <item name="android:windowNoTitle">true</item>  
    <!--是否浮现在activity之上-->  
    <item name="android:windowIsFloating">true</item>  
    <!--是否半透明-->  
    <item name="android:windowIsTranslucent">true</item>  
    <!--设置窗口内容不覆盖-->  
    <item name="android:windowContentOverlay">@null</item>  
    <!--设置动画,在这里使用让它继承系统的Animation.Dialog-->  
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>  
    <!--背景是否模糊显示-->  
    <item name="android:backgroundDimEnabled">true</item>  
</style>  

然后在 AndroidManifest.xml 中设置 DialogActivity 的 theme

来自 [Android 中使用 Dialog 风格弹出框的 Activity](http://blog.csdn.net/qq_20785431/article/details/50195977)

相关文章

  • Dialog源码学习笔记

    Dialog源码学习笔记 [TOC] (简书这个不支持吗?) Dialog源码学习笔记Dialog中值得学习之-...

  • Dialog 笔记

    AlertDialog 实现 从屏幕底部弹出对话框 自定义效果 Activity 仿 Dialog 效果 部分参考...

  • Dialog充满屏幕

    Dialog宽高设置 dialog style_dialog dialog_animation enter exi...

  • 全屏Dialog示例

    final Dialog dialog = new Dialog(context,R.style.weightin...

  • Dialog 出现消失动画和位置

    Dialog 的动画 拿到Dialog的实例,dialog.getWindow().getAttributes()...

  • Android圆角对话框Dialog

    需求:模仿iOS样式Dialog对话框。 自定义Dialog 核心代码: Dialog样式: Dialog布局文件...

  • 微信小程序,实现简易弹窗组件

    1、组件实现相关文件和代码: dialog.js dialog.json dialog.wxml dialog.w...

  • Dialog

    安卓dialog的使用+如何自定义dialog自定义Dialog自定义Dialog 自定义

  • Flutter Dialog 动画

    本文对 Dialog 做一次系统性学习记录,包括系统 Dialog,自定义 Dialog,Dialog 动画。 A...

  • dialog 不消失

    dialog弹出后会点击屏幕或物理返回键,dialog不消失 dialog弹出后会点击屏幕,dialog不消失;点...

网友评论

      本文标题:Dialog 笔记

      本文链接:https://www.haomeiwen.com/subject/swzqgttx.html