Android 推荐的自定义 Dialog 实现方式

原因

官方推荐的方式是使用AlertDialog,DialogFragment来实现。虽然说很多网上的例子直接使用了extends
Dialog来实现,但大部分时间我们应该使用上述的两种方式,因为有时候没有考虑到旋转或者Activity到后台后,Dialog附在的Activity消失,引起内存泄露的问题。

国内很多应用喜欢用Dialog的方式,基本上很大程度上要自定义Dialog中的button,这时候用DialogFragment其实可以实现,而且实现上也比较方便。

如同官方Dialog 类是对话框的基类,但您应该避免直接实例化
Dialog,而是使用下列子类之一:
说的这样,我们应该使用extends类。

实现方式

其实主要讲解是DialogFragment,主要是国内的应用还是在仿IOS,少有遵循Material
Design的设计,所以Button也是需要自定义的,那么AlertDialog就无法满足需要。这里引用官方的一段描述。

这些类定义您的对话框的样式和结构,但您应该将 DialogFragment
用作对话框的容器。DialogFragment 类提供您创建对话框和管理其外观所需的所有控件,而不是调用 Dialog 对象上的方法。

使用 DialogFragment
管理对话框可确保它能正确处理生命周期事件,如用户按“返回”按钮或旋转屏幕时。 此外,DialogFragment 类还允许您将对话框的 UI
作为嵌入式组件在较大 UI 中重复使用,就像传统 Fragment 一样(例如,当您想让对话框 UI
在大屏幕和小屏幕上具有不同外观时)。

重写onCreateView()

@Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View inflate = inflater.inflate(R.layout.fragment_edit_name, container, false);
        mEditText = (EditText) inflate.findViewById(R.id.txt_your_name);
        mButton1 = (Button) inflate.findViewById(R.id.btn1);
        mButton2 = (Button) inflate.findViewById(R.id.btn2);
        return inflate;
    } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这样基本就完成了,什么样式都在于你自己去实现。

设置有输入的Dialog调整,当键盘弹出

希望键盘可以说弹出,并且不挡住取消和确定这类的Button时,可以在onactivityCreated()中设置,其它地方也可以说。

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
  • 1
  • 2
  • 3
  • 4
  • 5

其中SOFT_INPUT_STATE_*中的各类型见名知意,这样了弹出直接拉起键盘,对用户也十分方便。更具体的使用请参考官方的DialogFragment

如下图所示为弹出和键盘自动弹出的情况,然后收缩键盘的情况。

如果说显示的内容特别多还是会把下面的给遮挡住的。下面这张图的情况就是过长的内容并不会把内容往上移动,因为移动已经超出屏幕了。 

关于宽度设置为match_parent时不占全的解决办法

在一些情况下有这种要求,处理很容易在onStart()中把背景色处理一下就可以了,也有说传null,但我认为下面方式更好些。

  @Override
    public void onStart() {
        super.onStart();
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
    }
  • 1
  • 2
  • 3
  • 4
  • 5

使用AlertDialog方式实现

这个时候不需要实现onCreateView(),这时应该实现public Dialog onCreateDialog(Bundle
savedInstanceState)
,如下代码所示。

@NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        View inflate = inflater.inflate(R.layout.dialog_test, null);
        mEditText = (EditText) inflate.findViewById(R.id.editText);
        mEditTest2 = (EditText) inflate.findViewById(R.id.editText2);




        builder.setView(inflate)
                // Add action buttons
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        // sign in the user ...
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        TestDialog.this.getDialog().cancel();
                    }
                });
        return builder.create();

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

如果之后需要request focus,应该在onActivityCreated()里面写。

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mEditText.requestFocus();
        getDialog().setTitle("haha");
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

关于Dialog位置和背景的设置

需要设置时需要 
得到顶层的window,可以参考下面的代码段1代码段2

Dialog dlg = <code to create custom dialog>;

Window window = dlg.getWindow();
WindowManager.LayoutParams wlp = window.getAttributes();

wlp.gravity = Gravity.BOTTOM;
wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
window.setAttributes(wlp);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
private CharSequence[] items = {"Set as Ringtone", "Set as Alarm"};
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setItems(items, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int item) {

            if(item == 0) {

            } else if(item == 1) {

            } else if(item == 2) {

            } 
        } 
    }); 

     AlertDialog dialog = builder.create();
     dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();

 wmlp.gravity = Gravity.TOP | Gravity.LEFT; 
 wmlp.x = 100;   //x position 
 wmlp.y = 100;   //y position 

 dialog.show(); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇