我制作了一个布局(例如 my_layout.xml ),其中包含两个其他XML布局文件,例如 some_layout.xml 和另一个_layout.xml 。 my_layout.xml 是使用setContentView(R.layout.my_layout)
绘制的。
现在我有一个标识为some_checkbox
的复选框,该复选框在 some_layout.xml 中定义,我想使用OnCheckedChangeListener
为复选框setOnCheckedChangeListener()
,就像这样:
CheckBox cb = (CheckBox) findViewById(R.id.some_checkbox);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
...
});
但现在抛出了NullPointerException
,因为cb
是null
。我想这是因为包含some_checkbox
的布局( some_layout )未使用setContentView(R.layout.some_layout)
加载。
R.id.some_checkbox
null
? some_layout 真的 可见。some_layout
捕获到变量中,就像我在上面的代码段中尝试过一样?我终于使用stealthjong建议的以下内容解决了它:
一个解决方案可能是初始化
checkedChangeListener
,为您的可扩展列表视图添加一个监听器,并且当可扩展列表视图的子项打开时,检查您的Checkbox
是否是一个膨胀的孩子,并且如果是,请添加checkedchangeListener
。
我创建了一个名为setCheckedChangeListenerToElement(int resourceId, OnCheckedChangeListener listener)
的方法,它保存了给定的resourceId(它是附加侦听器的元素的ID)和给定的侦听器。一旦inflater调用方法getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
,就可以检索View。然后,在该视图上,可以调用findViewById(int resourceId)
,其中resourceId
是复选框的ID。
答案 0 :(得分:20)
这有两种方法。
第一个是通过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
只是另外两种布局,第二种布局为Button
,ID为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
和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
和android.widget.Button
。
任何一种解决方案都应该可以正常工作。
<强>更新强>
您的expandableListView
是问题,因为在您实际打开/展开该部分之前,childLayout不会被充气(请参阅下面的代码以查看当前viewtree的小段代码)。
一个解决方案可能是初始化checkedChangeListener
,为您的可扩展列表视图添加一个监听器,并且当可扩展列表视图的子项打开时,检查您的Checkbox
是否是一个膨胀的孩子,并且如果是,请添加checkedchangeListener
。
这个可能更直接的方法是:
<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;
}
答案 1 :(得分:7)
如果some_layout.xml包含在my_layout.xml中,则使用include标记,例如: -
<include layout="@layout/some_layout" android:id="@+id/someLayoutId" />
然后您可以执行以下操作: -
View someLayoutView = findViewById(R.id.someLayoutId);
CheckBox cb = (CheckBox) someLayoutView.findViewById(R.id.some_checkbox);
如果以编程方式夸大some_layout.xml,例如: -
View someLayoutView = LayoutInflater.from(mContext).inflate(
R.layout.some_layout, null);
然后你仍然可以这样做: -
CheckBox cb = (CheckBox) someLayoutView.findViewById(R.id.some_checkbox);