【问题标题】:Creating Custom AlertDialog ? What is the root view?创建自定义警报对话框?什么是根视图?
【发布时间】:2020-08-06 01:52:40
【问题描述】:

我想做什么:

创建自定义警报对话框。按钮就像任何警报对话框一样,但上面是两个 TextEdit 输入框。我不想创建自定义对话框,而是自定义警报对话框

这是我正在尝试的#3: http://developer.android.com/guide/topics/ui/dialogs.html

上面写着:

AlertDialog.Builder builder;
AlertDialog alertDialog;

Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
                           (ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");


builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();

文档说:

View layout = inflater.inflate(R.layout.custom_dialog,
                           (ViewGroup) findViewById(R.id.layout_root));

其中第一个参数是布局资源ID,第二个参数是根View的ID。

问题是我不知道布局根是什么?这是我将在 Activity 中启动的对话框。如果活动,我应该使用布局ID吗? layout_root 是不是脱胎换骨了?

也试过了:

  View layout = inflater.inflate(R.layout.my_custom_layout,
                                   (ViewGroup)   findViewById(android.R.id.content).getRootView());

结果为空指针。

【问题讨论】:

    标签: android


    【解决方案1】:

    即使是一个较老的问题,这篇文章也可能对搜索此答案的其他人有用:

    Layout Inflation as Intended:

    如果您曾经使用以下代码编写过类似的代码 Android 应用程序中的 LayoutInflater:

    inflater.inflate(R.layout.my_layout, null);
    

    请继续阅读,因为您做错了,我想向您解释 你为什么。

    ...但是...

    每条规则都有例外

    当然,在某些情况下您可以真正证明 null 的合理性 通货膨胀期间的父母,但他们很少。发生了一个这样的例子 当您膨胀自定义布局以附加到 AlertDialog。考虑以下示例,我们要在其中使用我们的 相同的 XML 布局,但将其设置为对话框视图:

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    View content = LayoutInflater.from(context).inflate(R.layout.item_row, null);
    
    builder.setTitle("My Dialog");
    builder.setView(content);
    builder.setPositiveButton("OK", null);
    builder.show();
    

    这里的问题是 AlertDialog.Builder 支持自定义视图,但是 不提供采用布局的 setView() 实现 资源;所以你必须手动扩充 XML。然而,由于 结果将进入对话框,该对话框不会公开其根视图 (事实上​​,它还不存在),我们无法访问最终的 布局的父级,因此我们不能将其用于膨胀。事实证明, 这无关紧要,因为 AlertDialog 将删除任何 LayoutParams 无论如何布局并用 match_parent 替换它们。

    这篇文章解释了为什么你应该在大多数其他情况下提供父ViewGroup,而不是对话框构建。

    【讨论】:

    • 这个答案很完美!但是现在使用支持库,您可以使用developer.android.com/reference/android/support/v7/app/… 设置资源ID;然后,如果您想以编程方式向任何视图添加一些行为,您可以只使用 AlertDialog.findViewById(id)。为此,您应该调用 Builder.setView(res) => Builder.show() => find(id)... 问候!
    【解决方案2】:

    好的。文档中的根视图是指自定义布局中的元素。所以自定义布局将有一个称为根视图的最外层视图。你需要给它一个 Id,然后你可以将它传递进去,如图所示。所以第一个参数是自定义视图 id,第二个参数是自定义视图中根布局元素的 id。

     View layout = inflater.inflate(R.layout.custom_dialog,
                           (ViewGroup) findViewById(R.id.layout_root));
    

    因此,在上面文档中给出的这个示例中,R.id.layout_root 是指您提供的 id,例如 custom_dialog 布局中最外层的 LinearLayout。

    【讨论】:

      【解决方案3】:

      你试过了吗?

      View layout = inflater.inflate(R.layout.custom_dialog,null);
      

      【讨论】:

      • View v = inflater.inflate(R.layout.activity_main, null); 生成警告。使用View.inflate(..., null, false) 只是隐藏警告但不能解决问题。正确的方法是使用 builder.setView(R.layout.edit_account_dialog); dialog = builder.create();findViewById 只有在活动调用 dialog.show() 后才能使用;它引发了另一个问题:对话框的findViewByIdshow() 之前无法使用,并且在show() 之后也无法轻松调用。顺便说一句,在 dialog.show() 之后的活动中调用 findViewById 不是一个好习惯。
      【解决方案4】:
      builder.setView(layout);
      layout.getRootView();
      

      应该给LinearLayout

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        • 1970-01-01
        相关资源
        最近更新 更多