我创建了一个布局(比如my_layout.xml),其中包括两个其他XML布局文件,比如some_layout.xml和another_layout.xml.my_layout.xml是使用绘制的setContentView(R.layout.my_layout).
现在我有一个带ID的复选框some_checkbox,它在some_layout.xml中定义,我想给复选框一个OnCheckedChangeListenerusing setOnCheckedChangeListener(),就像这样:
CheckBox cb = (CheckBox) findViewById(R.id.some_checkbox);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
...
});
Run Code Online (Sandbox Code Playgroud)
但现在NullPointerException抛出了,因为cb是null.我猜那是因为包含的布局some_checkbox(some_layout)没有加载setContentView(R.layout.some_layout).
R.id.some_checkbox null?some_layout真的是可见的.some_layout变量,就像我在上面的代码片段中尝试过的那样?我终于解决了它,使用以下内容,由stealthjong建议:
一种解决方案可能是初始化
checkedChangeListener,向可扩展列表视图添加侦听器,以及打开可扩展列表视图的子项时,检查您Checkbox是否是其中一个膨胀的子项,并添加checkedchangeListenerif if.
我创建了一个名为的方法setCheckedChangeListenerToElement(int resourceId, OnCheckedChangeListener listener),它保存给定的resourceId(它是附加监听器的元素的ID)和给定的监听器.一旦inflater调用该方法getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent),就可以检索View.然后,在该View上,findViewById(int resourceId)可以调用,resourceId复选框的ID 在哪里.
ste*_*ong 21
这有两种方法.
第一个是通过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>
Run Code Online (Sandbox Code Playgroud)
而child_layout1和child_layout2只是两个其他布局,第二个有一个ButtonID为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());
}
}
Run Code Online (Sandbox Code Playgroud)
就像我怀疑的那样,这给了我一个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>
Run Code Online (Sandbox Code Playgroud)
还有一个稍大的应用程序入口点:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
哪个也给我一个false和一个android.widget.Button.
两种解决方案都应该正常工作.
UPDATE
你expandableListView的问题就在于,因为childLayout在实际打开/展开部分之前不会膨胀(请参阅下面的代码,了解一小段代码以检查当前的viewtree).
一种解决方案可能是初始化checkedChangeListener,向可扩展列表视图添加侦听器,以及打开可扩展列表视图的子项时,检查您Checkbox是否是其中一个膨胀的子项,并添加checkedchangeListenerif if.
一个可能更简单的方法是这个:
<CheckBox
...
android:onClick="checkclicked" />
Run Code Online (Sandbox Code Playgroud)
并在您的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;
}
Run Code Online (Sandbox Code Playgroud)
如果some_layout.xml包含在my_layout.xml中,则使用include标记,例如: -
<include layout="@layout/some_layout" android:id="@+id/someLayoutId" />
Run Code Online (Sandbox Code Playgroud)
然后你可以做到以下几点: -
View someLayoutView = findViewById(R.id.someLayoutId);
CheckBox cb = (CheckBox) someLayoutView.findViewById(R.id.some_checkbox);
Run Code Online (Sandbox Code Playgroud)
如果以编程方式夸大some_layout.xml,例如: -
View someLayoutView = LayoutInflater.from(mContext).inflate(
R.layout.some_layout, null);
Run Code Online (Sandbox Code Playgroud)
然后你仍然可以这样做: -
CheckBox cb = (CheckBox) someLayoutView.findViewById(R.id.some_checkbox);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42806 次 |
| 最近记录: |