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以後才爲佈局裏的元素分配內存,在未分配內存前對元素進行訪問時沒有意義的!!!

相關文章
相關標籤/搜索