2012-10-13 50 views
0

嘗試在ViewFlipper中切換視圖時,會出現大量工件和錯誤行爲。我想添加和刪除視圖根據需要,所以,而不是使用XML,我必須調用ViewGroup.addView()。在某些時候,我想通過除去最後的所有孩子來清理容器。這裏是一個演示:ViewFlipper:除去最後一個孩子時的工件

public class MainActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     LinearLayout root = new LinearLayout(this); 
     root.setOrientation(LinearLayout.VERTICAL); 

     final ViewFlipper flipper = new ViewFlipper(this); 

     Animation in = new TranslateAnimation(-200, 0, 0, 0); 
     in.setDuration(300); 
     Animation out = new TranslateAnimation(0, 200, 0, 0); 
     out.setDuration(300); 
     flipper.setInAnimation(in); 
     flipper.setOutAnimation(out); 

     // clean it up 
     out.setAnimationListener(new AnimationListener(){ 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       flipper.post(new Runnable(){ 
        public void run() { 
         flipper.removeViews(0, flipper.getChildCount() - 1); 
        } 
       }); 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) {} 

      @Override 
      public void onAnimationStart(Animation animation) {} 
     }); 

     Button button = new Button(this); 
     button.setText("Click me"); 
     button.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       View a = makeView(); 
       flipper.addView(a); 
       flipper.showNext(); 
      } 
     }); 

     root.addView(button); 
     root.addView(flipper); 
     setContentView(root); 
    } 

    int i = 0; 

    public View makeView() { 
     TextView tv = new TextView(MainActivity.this); 
     tv.setText("TextView#" + i++); 
     tv.setTextSize(30); 
     return tv; 
    } 
} 

有時候我想刪除所有孩子,但最後添加,以節省內存,因爲這些孩子們將永遠不會被再次使用(也許我可以回收他們,但那是另一回事)。我在動畫偵聽器中使用了一個簡單的可運行的View.post(),每三次就有一次出現僞影。

使用View.post(Runnable)需要,因爲如果你直接在動畫聽者去掉兒童,NullPointerException拋出,因爲(至少在蜂窩+,它採用顯示列表繪製層次結構)。

注意:我正在開發2.1+,所以蜂窩動畫包不適合。

回答

3

出現這些「工件」是因爲在您的情況下,您嘗試刪除除頂部的所有視圖之外的所有視圖,使當前顯示的子級的索引不按順序排列。 ViewFlipper將嘗試彌補這一點,並從它的外觀不成功。但是,你仍然可以做你想做像這樣沒有視力問題是什麼:

flipper.post(new Runnable() { 
    public void run() { 

     if (flipper.getChildCount() < 4) // simulate a condition 
      return; 

     flipper.setInAnimation(null); 
     flipper.setOutAnimation(null); 

     while (flipper.getChildCount() > 1) 
      flipper.removeViewAt(0); 

     flipper.setInAnimation(in); 
     flipper.setOutAnimation(out); 

     assert flipper.getChildCount() == 1; 
    } 
}); 

這應該只留在ViewFlipper可見視圖。看看代碼是否解決了這個問題。

+0

+1,但-sorry! - 編寫演示時我犯了這個愚蠢的錯誤。查看顯示實際問題的更新代碼:**刪除** – Raffaele

+0

@Raffaele我編輯了我的答案。 – Luksprog

+0

我嘗試了與你的相同的解決方案(空動畫,然後恢復),但它不工作與'removeViews(開始,計數)',不幸的是我的邏輯是,我需要保持意見,直到一些事件,導致所有意見,但最後一個刪除。在我的自定義鰭狀肢,我有一個方法使用'removeViewAt(索引)'與空動畫,它的工作完美無瑕。然而,我只是發現了一個破解工作:我在循環中使用了'removeViewAt(0)',直到孩子數爲1爲止。我編輯了你的答案並將其標記爲接受:)謝謝 – Raffaele