关于findViewById你所不知道的

在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,当然可以正常取值。
不知道敏锐的你有没有在其中嗅到一丝丝面向对象的感觉呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值