note 23- 关于 LayoutInflater , Activity.findViewById() 和 View.findViewById()

经过一些实验,终于比较清楚地理解了 LayoutInflater 的真正作用.

 

这个实验要从一个问题说起: 为什么 Activity 里有 findViewById() 方法 , 而 View 里也有同样的 findViewById() ? 起初我以为这两个方法有什么地方是不一样的,但其实基本上是相同的, 同样的通过 id 获取自身的子组件 . 只是在Activity中它会间接返回Activity所使用的ViewContent的子组件.

 

看看我第一次实验的代码:(这是在 Mars Chen 老师的 Wifi 讲解那一课里顺便做的实验)

 

 

 

public void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        
        layout=new LinearLayout(this);
        
        LayoutInflater inflater=
                (LayoutInflater)layout.getContext().getSystemService(Service.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.main, layout, true);
        
        
        
        startWifiButt=(Button)layout.findViewById(R.id.startButton);
        stopWifiButt=(Button)layout.findViewById(R.id.stopButton);
        checkWifiButt=(Button)layout.findViewById(R.id.checkButton);
        
        startWifiButt.setOnClickListener(startClickListener);
        stopWifiButt.setOnClickListener(stopClickListener);
        checkWifiButt.setOnClickListener(checkClickListener);
        
        
    }

 上面这段代码编译的结果失败了, 屏幕上生成三个Button, 但点击后没有反应.

 值得留意的是 , 我的组件是通过 inflate 了 R.layout.main 产生一个main view的实例 layout ,通过这个layout 的 findViewById 方法去获取.

 

 

下面是成功了的代码:

 

 

public void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);
        
        
        
        layout=new LinearLayout(this);
        
        LayoutInflater inflater=
                (LayoutInflater)layout.getContext().getSystemService(Service.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.main, layout, true);
        
        setContentView(layout);
        
        startWifiButt=(Button)layout.findViewById(R.id.startButton);
        stopWifiButt=(Button)layout.findViewById(R.id.stopButton);
        checkWifiButt=(Button)layout.findViewById(R.id.checkButton);
        
        startWifiButt.setOnClickListener(startClickListener);
        stopWifiButt.setOnClickListener(stopClickListener);
        checkWifiButt.setOnClickListener(checkClickListener);
        
        
    }

 这一次,同样的 inflate 了一个 main view 的 layout 去获取组件. 但不同的是, 我把 activity 的 setContentView 中的ContentView set 成了 我自己 inflate 出来的那个 layout .

 

 

 

于是实验便证明了:

 

1. inflate 方法生成的是一个新的实例. inflate 多少次就会生成多少个 View 实例. 而不是返回某些已有的 View; 因此这       个新产生的 View 实例 与任何其他 View 实例都没有关联.

 

 

2. 在失败的例子中其实 findViewById() 并没有问题, 只是 activity 的 setContentView () 的 参数 R.layout.main 与     新生成的 layout 并没有关系 . 因此 显示的Button组件与 注册 OnClickListener 的组件并非同一批组件. 注册               Listener 的 Button 属于 layout 实例所有 , 而显示出来的是 R.layout.main

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值