在android中,findViewById(int)是获取当前上下文中的组件,即在这句话的完整句子是:layout.findViewById(int),前面省略的layout,是默认在oncreate方法中setContentView(int layoutid)中设置的layout。
这时候,如果我们需要访问的view并不在当前activity所在的layout中,我们就需要先加载该view所在的layout,然后通过layout来访问该view,如:
LayoutInflator layoutInflator=getLayoutInflator();
LinearLayout ll=(LinearLayout)layoutInflator.inflator(R.layout.XXX,null);
TextView tv=(TextView)ll.findViewById(R.id.XX);
而实际上,每次通过getLayoutInflator().inflator(R.layout.XXX)所得到的layout其实都相当于一个类的实例,也就是说,两次通过该方法得到的相同layout的实例,用它调用findViewById(int id)所得到的view是不同的。例如下面的实例:
LayoutInflator layoutInflator=getLayoutInflator();
View layout=layoutInflator.inflate(R.layout.settingsplashtime,null);
final EditText settime=(EditText)layout.findViewById(R.id.settime);
然后,再初始化一个对话窗口,它也是以R.layout.settingsplashtime对应layout为布局文件:
final TableLayout tl=(TableLayout)getLayoutInflator().inflate(R.layout.settingsplashtime,null);
Builder b=new AlertDialog.Builder(MainActivity.this)
.setTitle("修改启动时间")
.setView(tl)
.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(MainActivity.this, "aaa"+settime.getText().toString()+"aaa", Toast.LENGTH_SHORT).show();
}
})
R.layout.settingsplashtime所对应的布局xml文件代码如下:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/setsplashtime">
<TableRow >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请输入启动时间(单位:秒):"
/>
<EditText
android:id="@+id/settime"
android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</TableRow>
</TableLayout>
启动项目之后,Toast显示的值始终为空,无论如何修改EditText中的值都为空,但若在EditText中加上android:text=”xxx”,则每次都会显示xxx的值。
然后,如果将EditText的初始化以tl为上下文,即如下
final TableLayout tl=(TableLayout)getLayoutInflator().inflate(R.layout.settingsplashtime,null);
**final EditText settime=(EditText)tl.findViewById(R.id.settime);**
Builder b=new AlertDialog.Builder(MainActivity.this)
.setTitle("修改启动时间")
.setView(tl)
.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(MainActivity.this, "aaa"+settime.getText().toString()+"aaa", Toast.LENGTH_SHORT).show();
}
})
这样修改之后,则可以正常运行,Toast可正常显示EditText的输入值。
综上所述,即可说明:在修改前的流程为:
开始–>实例化settingsplashtime(记为实例1)–>(EditText) settime从实例1中取–>实例化settingsplashtime(记为实例2)作为对话窗口的布局
可以看出,settime所在layout实例与对话窗口所在实例并不是一个实例,settime.getText()取到的是实例1中EditText中的值,它没有被改变过,进行输入删除操作,改变内容的是实例2中的EditText,所以settime当然取不到值。
而修改之后,settime所对应的EditText即对话窗口中的EditText,当然可以正常取值。
不知道敏锐的你有没有在其中嗅到一丝丝面向对象的感觉呢?