2012-10-13 2 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()을 통해 스케줄 된 간단한 실행 파일을 사용하고, 정확히 3 번마다 아티팩트가 있습니다. View.post(Runnable)를 사용

는 애니메이션 리스너에서 직접 아이들을 제거하는 경우, NullPointerException 때문에 (적어도 계층 구조를 그리는 표시 목록을 사용 벌집 +에) 발생되기 때문에 필요합니다.

참고 : 저는 2.1+ 용으로 개발 중이므로 Honeycomb 애니메이션 패키지는 적합하지 않습니다.

답변

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,하지만 - 죄송합니다! - 데모를 쓸 때 어리석은 실수를 저질 렀습니다. 실제 문제를 보여주는 업데이트 된 코드를 참조하십시오. ** removals ** – Raffaele

+0

@Raffaele 내 대답을 편집했습니다. – Luksprog

+0

나는 널 애니메이션 (null 애니메이션, 복원)과 같은 솔루션을 시도했지만'removeViews (start, count)'와 작동하지 않으며 불행히도 내 논리는 모든 이벤트가 발생할 때까지 뷰를 유지해야한다는 것입니다. 마지막보기가 삭제되었습니다. 내 사용자 지정 플리퍼에는 null 애니메이션과 함께'removeViewAt (index)'를 사용하는 메소드가 있으며 완벽하게 작동합니다. 그러나 난 그냥 작동하도록 해킹을 발견 : 나는'removeViewAt (0)'루프에서 자식 카운트 때까지 사용됩니다. 나는 당신의 대답을 편집하고 받아 들인 것으로 표시 :) 감사 – Raffaele

관련 문제