setContentView+LayoutInflater=完美切换页面(二者必定要同时使用,setContentView提升切换页面速度必看)setContentView的秘密----续上

http://blog.csdn.net/yanzi1225627/article/details/7802018这里的问题我已经找到了答案.html

setContentView的秘密:eclipse

      当activity 调用 setContentView() 时,Android 才会去绘制 layout 上的各个元素,并为其分配内存。只有分配了内存之后,才能继续执行findViewById(); 才能获得引用,否则获得空引用。空引用意味着,后面使用相应变量时就会发生访问的对象不存在的问题。当Activity从新setContentView()之后,那些以前绘制的控件,内存都被灭掉了。因此,如果经过setContentView 来达到画面切换目的的,要注意从新绘制之后从新取得引用。ide

      --------(参考:http://www.go2solo.net/2011/07/08/setcontentview%E7%9A%84%E7%A7%98%E5%AF%86.html函数

               http://blog.csdn.net/simplty/article/details/7036773布局

 

     什么是LayoutInflater?this

           LayoutInflater的做用就至关于findViewById,只不事后者是查找一些小的widget,如button、textview,而前者是查找layout文件下的.xml布局文件。也就是说:LayoutInflater 把布局xml文件引入成View对象,再经过setContentView(View view)方法来切换视图。由于全部对View的修改都保存在View对象里,因此,当切换回原来的view时,就能够直接显示原来修改后的样子。这样也 就解决了setContentView后还要findViewById的问题,由于这里是实例化的view对象,经过这个view去 setContentView,并且还能有效保存切换页面前的内容。spa

所以,我将程序修改为这个样子:.net

public class MainActivity extends Activity {
 View layoutMain = null;
 View layoutSecond = null;
 Button btn_mainActivity = null;
 Button btn_secondActivity;
 boolean firstFlag = true;
 long time = (long)0.0;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  LayoutInflater inflater = this.getLayoutInflater();
  layoutMain = inflater.inflate(R.layout.activity_main, null);
  layoutSecond = inflater.inflate(R.layout.activity_second, null);
  setContentView(layoutMain);xml

  btn_mainActivity  = (Button)findViewById(R.id.btn_mainAc_1);  
  btn_mainActivity.setOnClickListener(new ButtonListen());htm

 


 }

 class ButtonListen implements OnClickListener{

  public void onClick(View v) {
   // TODO Auto-generated method stub
   time = System.currentTimeMillis();
   switch(v.getId()){
   case R.id.btn_mainAc_1:
    Jump2Second();
    break;
   case R.id.btn_secondA_1:
    Jump2Main();
    break;
   default:
    break;
   }
  }

 }
 public void Jump2Second(){
  setContentView(layoutSecond);
  long currTime = System.currentTimeMillis();
  Toast.makeText(MainActivity.this,
    "切换耗时:" +String.valueOf(currTime-time)+"毫秒",
    Toast.LENGTH_SHORT).show();
  if(firstFlag){
   btn_secondActivity = (Button)findViewById(R.id.btn_secondA_1);
   btn_secondActivity.setOnClickListener(new ButtonListen());
   firstFlag = false;
  }   

 }
 public void Jump2Main(){
  setContentView(layoutMain);
  long currTime = System.currentTimeMillis();
  Toast.makeText(MainActivity.this,
    "切换耗时:" +String.valueOf(currTime-time)+"毫秒",
    Toast.LENGTH_SHORT).show();
 }
}

       这里要注意,firstFlag的使用,判断是否第一次跳转至second界面,若是是第一次的话则findViewById而后监听,只须要绑定一次就 能够了。并且这个绑定必须在跳转函数里,不能在onCreate方法里。为何呢?由于在onCreate方法里 setContentView(layoutMain),系统只为layoutMain里的元素分配了内存,并无为layoutSecond上的元素分 配内存,尽管这里用view将其实例化对象里。(这块表述可能不许确,欢迎大神们指点

       总之,没有setContentView(第二个界面)以前,第二个界面里的元素虽然可以find到,eclipse没有报错,但由于没有被分配内存,因此在onCreate这里为第二个界面绑定监听是错误的!你运行的时候程序会直接挂掉。

 

记住:setContentView以后才为布局里的元素分配内存,在未分配内存前对元素进行访问时没有意义的!!!

相关文章
相关标签/搜索