如何在 Android 中以编程方式加载布局 XML 文件?

2024-01-22

我已经做了一个布局(比如说my_layout.xml)其中以编程方式包括另外两个 XML 布局文件,例如一些_layout.xml and another_layout.xml. my_layout.xml是使用绘制的setContentView(R.layout.my_layout).

现在我有一个带有 ID 的复选框some_checkbox,其定义在里面一些_layout.xml,我想给复选框一个OnCheckedChangeListener using setOnCheckedChangeListener(), 像这样:

CheckBox cb = (CheckBox) findViewById(R.id.some_checkbox);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    ...
});

但现在一个NullPointerException被抛出,因为cb is null。我想那是因为布局包含some_checkbox(这是一些布局) 未使用加载setContentView(R.layout.some_layout).

  • 问题1:为什么?为什么返回发现R.id.some_checkbox null? 一些布局 really is可见的。
  • 问题 2:如何“加载”一些布局这样我就可以捕捉到some_layout到一个变量中,就像我在上面的代码片段中尝试的那样?

UPDATE

我终于解决了这个问题,使用以下建议潜行 https://stackoverflow.com/users/1627730/stealthjong:

一种解决方案可能是初始化checkedChangeListener,向可扩展列表视图添加一个侦听器,然后当打开可扩展列表视图的子视图时,检查您的Checkbox是膨胀的孩子之一,并添加checkedchangeListener if so.

我创建了一个名为的方法setCheckedChangeListenerToElement(int resourceId, OnCheckedChangeListener listener),它保存给定的resourceId(这是要附加侦听器的元素的ID)和给定的侦听器。一旦充气器调用该方法getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent),可以检索视图。然后,在该视图上,findViewById(int resourceId)可以调用,其中resourceId是复选框的 ID。


有两种方法可以实现这一点。

第一个是通过 XML 添加子布局:

1.XML方法

my_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <include
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/child_layout1" >
    </include>

    <include
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/child_layout2" />

</LinearLayout>

And child_layout1 and child_layout2只是另外两个布局,第二个有一个Button带身份证mbutton.

您的应用程序条目应如下所示:

public class MainActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_layout);
        View v = findViewById(R.id.mbutton);
        System.out.println(v == null);
        System.out.println(v.getClass().getName());
    }   
}

这让我false and a android.widget.Button,正如我所怀疑的那样。

2. 程序化方法

另一种方法是编程方法,既然你这样描述它,我怀疑这就是你所做的(或至少尝试过的):

noinclude_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/inclusionlayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </RelativeLayout>

</LinearLayout>

还有一个稍大的应用程序入口点:

public class MainActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.noinclude_layout);
        ViewGroup inclusionViewGroup = (ViewGroup)findViewById(R.id.inclusionlayout);

        View child1 = LayoutInflater.from(this).inflate(
                R.layout.child_layout1, null); 
        View child2 = LayoutInflater.from(this).inflate(
                R.layout.child_layout2, null);
        inclusionViewGroup.addView(child1);
        inclusionViewGroup.addView(child2);

        View v = findViewById(R.id.mbutton);
        System.out.println(v == null);
        System.out.println(v.getClass().getName());
    }   
}

这也让我false and a android.widget.Button.

任何一种解决方案都应该可以正常工作。

UPDATE

Your expandableListView是问题所在,因为在您实际打开/展开该部分之前,childLayout 不会膨胀(请参阅下面的代码,了解检查当前视图树的一小段代码)。

一种解决方案可能是初始化checkedChangeListener,向可扩展列表视图添加一个侦听器,然后当打开可扩展列表视图的子视图时,检查您的Checkbox是膨胀的孩子之一,并添加checkedchangeListener if so.

一种可能更直接的方法是:

<CheckBox
    ...
    android:onClick="checkclicked" />

并在你的Activity,添加方法public void checkclicked(View view){ ... }

ViewTree打印机

private void printFullTree() {
    printTree(this.getWindow().getDecorView(),0);
}

private void printTree(View view, int indent) {
    System.out.print(indent(indent) + view.getClass().getName() + "; " + view.getId());
    if (view instanceof ViewGroup) {
        ViewGroup vg = (ViewGroup)view;
        System.out.print("; children = " + vg.getChildCount() + "\n");
        for (int i = 0; i< vg.getChildCount(); i++) {
            printTree(vg.getChildAt(i), indent++);
        }
    }
    else
        System.out.print("\n");
}

private String indent(int indent) {
    String result = "";
    for (int i = 0; i < indent; i++) {
        result += "  ";
    }
    return result;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Android 中以编程方式加载布局 XML 文件? 的相关文章

随机推荐

  • 如何添加 XML 文件并将键值对读取到字典中? [复制]

    这个问题在这里已经有答案了 我对编程相当陌生 我正在尝试添加一个 XML 文件来存储一些映射 我想在字典中准备好这些键值对 以下是我正在考虑的 XML 格式
  • QUOTENAME 函数的相反函数是什么?

    在 SQL Server 中 有一个内置函数可以为您引用一个标识符 称为 是否有一个函数可以执行相反的操作并再次删除引号 换句话说 在下面的代码示例中 我该如何替换 SOMEFUNCTION 才能使其对于我可以将 name 初始化为的任何值
  • Python:列表理解背后的机制

    当使用列表理解或infor 循环上下文中的关键字 即 for o in X do something with o or l o for o in X 背后的机制如何in works 其中包含哪些函数 方法X它打电话吗 If X可以遵循多种
  • 使用具有相同参数的不同模板模板参数重载函数时出错

    我有一个类 它获取两个模板模板参数 并使用一个参数重载一个函数 该参数是一个或另一个模板模板参数 但两次都使用相同的模板参数 template
  • 使用boost::iostreamsmapped_file_source和filtering_streambuf解压缩文件

    我计划处理大型压缩文件 并且希望对文件进行内存映射以加快读取速度 我采用了带有常规文件输入的现有示例 但无法编译或工作 我正在使用 C Boost 1 49 欢迎任何建议 include
  • 在 C# 中创建/打开从路径到新 Outlook.MailItem 的现有消息

    您好 我想从磁盘上的现有 Outlook MailItem 创建一个 Outlook MailItem 我相信 我将路径存储在字符串中 并且希望访问以保存其中的正文和附件 我似乎不知道如何在 C 中打开它并访问它 目前我有类似的东西 其中
  • 从字符串中删除数字

    我想知道如何从字符串中删除数字 我尝试使用 StringReplace 但不知道如何告诉函数我要替换数字 这是我尝试过的 StringReplace mString 0 9 rfReplaceAll rfIgnoreCase 简单但有效 可
  • fatal:您当前的分支似乎已损坏

    我使用时出现此错误 git log fatal 您当前的分支似乎已损坏 我的分支文件被破坏了 我在记事本中打开 git refs heads mybranch 但我只看到一些 在文件中 我知道我必须找到分支哈希并将其复制到 git refs
  • 在滚动上重新定位 CdkConnectedOverlay

    我正在尝试使用CdkConnectedOverlay单击按钮时显示叠加层 它大部分工作正常 但覆盖层没有在滚动时重新定位 我确信我遗漏了一些小东西 但我一生都无法弄清楚 我在用着Angular 7 2 8 and Angular CDK 7
  • 无法从 iOS OAuth1.0、OAConsumer 客户端在 tumblr 上发帖

    我正在尝试将 tumblr 集成到我的应用程序中 我能够成功获取访问令牌 但是 当我尝试发帖时 出现以下错误 meta status 401 msg Not Authorized response 我正在使用OAuthConsumeriOS
  • 关联的遍历方向

    我正在读这本书领域驱动设计 of 埃里克 埃文斯 第5章 关于协会 他降低模型复杂性的建议之一是为关联施加遍历方向 I quote 尽可能地限制关系很重要 A 双向关联意味着两个对象都可以被理解 只有在一起 当应用需求不需要遍历时 在两个方
  • 静音按钮不会使 AVAudioPlayer 静音

    我需要在我的 iPhone 应用程序中循环播放 caf 文件 AVAudioPlayer 看起来很有前途 但有一个问题 即使我按下 iPhone 上的静音按钮 它也不会停止或静音 据我了解 在 iOS 5 中 无法以编程方式查明静音按钮是否
  • WooCommerce 付款完整挂钩

    经过长时间的搜索 我找到了这篇文章 WooCommerce 挂钩用于 付款完成后 操作 https stackoverflow com questions 28218580 woocommerce hook for after paymen
  • Mongo,通过id列表查找

    我有一个返回字符串 MongoDB id 列表的进程 512d5793abb900bf3e20d012 512d5793abb900bf3e20d011 我想向 Mongo 发起一个查询 并按照与列表相同的顺序获取匹配的文档 执行此操作的
  • React Native AsyncStorage getItem 返回承诺而不是值

    我有一个登录表单 我可以发布表单值 成功的 POST 请求后 我会收到从 API 返回的身份验证令牌 我需要将此令牌保存在本地存储中以供将来参考 为了保存此身份验证令牌 我使用 AsyncStorage 我用了AsyncStorage se
  • Python 发送的 MIME 电子邮件附件未显示在 mail.live 中

    我有一个 Python 3 脚本 它使用 MIMEMultipart 发送带有生成的附件的 xlsx 文件的电子邮件 我曾经在 Py2 上使用相同的脚本来发送相同的生成文件 唯一的区别是 Py2 脚本从 MySQL 收集信息来创建 xlsx
  • 三次曲线 JavaFX

    我在 JavaFX 中的 CubicCurve 上遇到了困难 例如 如何绘制 y x 3 绘制曲线的机制看起来非常笨拙 是否可以将曲线的端点之一连接到另一个节点 以便当该节点的位置发生变化时曲线会适应它 Thanks 我认为 JavaFX
  • 更换默认手机APP

    我正在尝试替换默认的 Android 电话应用程序 更具体地说 我想在每次执行呼叫操作时启动自定义电话呼叫屏幕 我知道自 Android 的 API 24 版本 7 0 Nougat 以来这是可能的 但我没有找到有关如何实现此目的的参考资料
  • 在 ionic 中加载 url 显示空白屏幕

    我在网上搜索过 但没有得到关于这个问题的具体信息 我正在使用 ionic v1 其中我正在加载我的 adfs url 来要求用户通过 adfs 网页登录 但仅在某些手机上我看到登录页面 而在其他手机上我看到空白屏幕 我尝试调试它 但到目前为
  • 如何在 Android 中以编程方式加载布局 XML 文件?

    我已经做了一个布局 比如说my layout xml 其中以编程方式包括另外两个 XML 布局文件 例如一些 layout xml and another layout xml my layout xml是使用绘制的setContentVi