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

猜你喜欢

转载自julianjulian8.iteye.com/blog/1734871