如何以编程方式加载在Android的布局XML文件? [英] How to load programmatically a layout XML file in Android?
问题描述
我已经做了布局(比如 my_layout.xml ),其中包括编程其他两个XML布局文件,说的 some_layout.xml 和 another_layout.xml 。 my_layout.xml 使用绘制的setContentView(R.layout.my_layout)
。
I have made a layout (say my_layout.xml) which includes programmatically two other XML layout files, say some_layout.xml and another_layout.xml. my_layout.xml is drawn using setContentView(R.layout.my_layout)
.
现在我有一个ID some_checkbox
,其内部定义的 some_layout.xml 一个复选框,我想给复选框的 OnCheckedChangeListener
使用 setOnCheckedChangeListener()
,就像这样:
Now I have a checkbox with ID some_checkbox
, which is defined inside some_layout.xml, and I want to give the checkbox an OnCheckedChangeListener
using setOnCheckedChangeListener()
, just like this:
CheckBox cb = (CheckBox) findViewById(R.id.some_checkbox);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
...
});
不过现在 NullPointerException异常
被抛出,因为 CB
是空
。我想这是因为布局包含 some_checkbox
(即 some_layout )未使用加载的setContentView(R.layout.some_layout )
。
But now a NullPointerException
is thrown, because cb
is null
. I guess that's because the layout containing some_checkbox
(which is some_layout) is not loaded using setContentView(R.layout.some_layout)
.
- 问题1:为什么呢?为什么返回找到
R.id.some_checkbox
空
? some_layout 真正的是的可见光。 - 问题2:我如何'负荷' some_layout 这样我就可以捕捉
some_layout
到一个变量,就像我尝试在$ C $上述C段?
- Question 1: Why? Why returns finding
R.id.some_checkbox
null
? some_layout really is visible. - Question 2: How do I 'load' some_layout so I can capture
some_layout
into a variable, like I tried in the code snippet above?
我终于解决了它,用下面所建议 stealthjong :
I've finally solved it, using the following, suggested by stealthjong:
一种解决方案可以初始化的 checkedChangeListener
,添加一个监听到你的扩展列表视图,以及可扩展列表视图的孩子打开时,检查如果你的复选框
是膨胀的一个孩子,并添加 checkedchangeListener
如果是的话。
One solution could be initialising the
checkedChangeListener
, adding a listener to your expandable listview, and when a child of the expandable listview is opened, checking if yourCheckbox
is one of the inflated children, and adding thecheckedchangeListener
if so.
我已经创建了一个名为 setCheckedChangeListenerToElement(INT RESOURCEID,OnCheckedChangeListener监听器)
的方法,既节约了给定的RESOURCEID(这是元素的ID其中,附加一个监听器向),并且给定的监听器。一旦充气调用方法 getChildView(INT groupPosition,诠释childPosition,布尔isLastChild,查看convertView,ViewGroup中父)
,该视图可以检索。然后,在该视图中, findViewById(INT RESOURCEID)
可以调用,其中 RESOURCEID
是复选框的ID。
I've created a method called setCheckedChangeListenerToElement(int resourceId, OnCheckedChangeListener listener)
, which saves the given resourceId (which is the ID of the element where to attach a listener to), and the given listener. Once the inflater calls the method getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
, the View can be retrieved. Then, on that View, findViewById(int resourceId)
can be called, where resourceId
is the ID of the checkbox.
推荐答案
有两种方法这一点。
首先是通过XML添加子布局:
The first being adding child layouts through 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>
和 child_layout1
和 child_layout2
只是两个布局,第二个有一个按钮
id为 mbutton
。
And child_layout1
and child_layout2
are just two other layouts, the second having a Button
with id mbutton
.
您的应用程序的入口应该是这样的:
Your application entry should look like this:
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());
}
}
此网我假
和 android.widget.Button
,完全按照我怀疑。
this nets me a false
and a android.widget.Button
, exactly as I suspected.
2。的程序化方法
另一种方法是的程序化的方法,因为你描述它是这样的,我怀疑这是你做了什么(或者至少尝试):
The other approach is the programmatical approach, and since you described it as such, I suspect this is what you did (or at least tried to):
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>
和一个稍大的应用程序入口点:
And a slightly larger application entrypoint:
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());
}
}
这也是网我假
和 android.widget.Button
。
这两种解决方案应该工作得很好。
Either solution should work just fine.
更新
您 expandableListView
是问题,因为childLayout不充气,直到你实际打开/展开部分(见$ C $下面的小块$ C $了C C到检查当前viewtree)。
Your expandableListView
is the problem, since the childLayout is not inflated until you actually open/expand the section (see code below for small piece of code to check current viewtree).
一种解决方案可以初始化的 checkedChangeListener
,添加一个监听到你的扩展列表视图,以及可扩展列表视图的孩子打开时,检查如果你的复选框
是膨胀的一个孩子,并添加 checkedchangeListener
如果是的话。
One solution could be initialising the checkedChangeListener
, adding a listener to your expandable listview, and when a child of the expandable listview is opened, checking if your Checkbox
is one of the inflated children, and adding the checkedchangeListener
if so.
有一个可能更直接的方法是这样:
A probably more straightforward approach would be this one:
<CheckBox
...
android:onClick="checkclicked" />
和您的活动
,添加方法公共无效checkclicked(查看视图){...}
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;
}
这篇关于如何以编程方式加载在Android的布局XML文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!