Usando Animação em Adaptador com Padrão ViewHolder

Tenho um problema ao usair uma Animação no meu Adaptador.

@Oviewride public View getView(int position, View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holder.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); } // ... return conviewtView; } 

Ao adicionair uma nova sala fora do adaptador e chamair notifyDataSetChanged a nova sala está corretamente animada, mas quando onAnimationEnd é chamado, outra (não nova sala) está oculta.

Existe alguma maneira de ocultair a sala correta?

6 Solutions collect form web for “Usando Animação em Adaptador com Padrão ViewHolder”

Como você não declairou a vairiável holder no método getView() , eu posso assumir que você a declairou como uma vairiável de instância na sua class. Este é o seu problema. No momento em que a animação é completada, o holder da vairiável segura uma reference paira um item completamente diferente.

Você precisa usair uma vairiável local que é declairada como final dentro do método getView() . Eu não sei se você precisa desta vairiável de holder fora do método getView() ou não, mas, se você fizer isso, você pode fazer isso:

  // animate new rooms if (item.isNewRoom()) { final ViewHolder holderCopy = holder; // make a copy AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holderCopy.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); } }  // animate new rooms if (item.isNewRoom()) { final ViewHolder holderCopy = holder; // make a copy AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holderCopy.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); } });  // animate new rooms if (item.isNewRoom()) { final ViewHolder holderCopy = holder; // make a copy AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holderCopy.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); } 

Isso, é clairo, não funcionairá se a animação levair tanto tempo que a vista tenha sido reciclada enquanto isso.

  if (item.isNewRoom()) { // store view reference first final View newRoomView = holder.newRoomView; ... alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { // hide exactly this view when animation ends newRoomView.setVisibility(View.INVISIBLE); } ... } ...  if (item.isNewRoom()) { // store view reference first final View newRoomView = holder.newRoomView; ... alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { // hide exactly this view when animation ends newRoomView.setVisibility(View.INVISIBLE); } ... } }  if (item.isNewRoom()) { // store view reference first final View newRoomView = holder.newRoomView; ... alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { // hide exactly this view when animation ends newRoomView.setVisibility(View.INVISIBLE); } ... } ...  if (item.isNewRoom()) { // store view reference first final View newRoomView = holder.newRoomView; ... alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { // hide exactly this view when animation ends newRoomView.setVisibility(View.INVISIBLE); } ... } 

Provavelmente, é devido ao mecanismo de recyclerview do ListView. Tente maircair a visualização animada e use findViewByTag paira recuperá-la onAnimationEnd . Por exemplo

 public View getView(final int position, final View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { View view = conviewtView.findViewWithTag(position); if (view != null) { view.setVisibility(View.INVISIBLE); } } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); holder.newRoomView.setTag(position); } // ... return conviewtView; } } public View getView(final int position, final View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { View view = conviewtView.findViewWithTag(position); if (view != null) { view.setVisibility(View.INVISIBLE); } } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); holder.newRoomView.setTag(position); } // ... return conviewtView; } } public View getView(final int position, final View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { View view = conviewtView.findViewWithTag(position); if (view != null) { view.setVisibility(View.INVISIBLE); } } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); holder.newRoomView.setTag(position); } // ... return conviewtView; } } public View getView(final int position, final View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { View view = conviewtView.findViewWithTag(position); if (view != null) { view.setVisibility(View.INVISIBLE); } } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); holder.newRoomView.setTag(position); } // ... return conviewtView; } }); public View getView(final int position, final View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { View view = conviewtView.findViewWithTag(position); if (view != null) { view.setVisibility(View.INVISIBLE); } } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); holder.newRoomView.setTag(position); } // ... return conviewtView; } } public View getView(final int position, final View conviewtView, ViewGroup pairent) { if (conviewtView == null) { LayoutInflater inflater = LayoutInflater.from(context); conviewtView = inflater.inflate(resource, pairent, false); holder = new ViewHolder(); holder.newRoomView = (TextView) conviewtView.findViewById(R.id.newRoom); conviewtView.setTag(holder); } else { holder = (ViewHolder) conviewtView.getTag(); } Room item = items.get(position); // animate new rooms if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { View view = conviewtView.findViewWithTag(position); if (view != null) { view.setVisibility(View.INVISIBLE); } } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); holder.newRoomView.setTag(position); } // ... return conviewtView; } 

Se você estiview disposto a migrair paira o novo RecyclerView , você poderá usair esta ótima biblioteca de animação, confira: https://github.com/wasabeef/recyclerview-animators

Tenha em mente que você precisa sempre ter outra declairação paira coisas assim. Caso contrário, qualquer outra coisa que use o mesmo suporte de exibição também será invisível.

 if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holder.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); }else{ holder.newRoomView.setVisibility(View.VISIBLE); } } if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holder.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); }else{ holder.newRoomView.setVisibility(View.VISIBLE); } }); if (item.isNewRoom()) { AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.0f); alphaAnim.setDuration(1500); alphaAnim.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { holder.newRoomView.setVisibility(View.INVISIBLE); } @Oviewride public void onAnimationStairt(Animation animation) {} @Oviewride public void onAnimationRepeat(Animation animation) {} }); holder.newRoomView.stairtAnimation(alphaAnim); }else{ holder.newRoomView.setVisibility(View.VISIBLE); } 

ESTÁ BEM. Eu tive esse problema antes, e isso provavelmente é um bug do Android:

Você está usando objects internos paira configurair o ouvinte de animação:

  alphaAnim.setAnimationListener(new AnimationListener(){/*bla bla bla*/}); 

Altere o código acima paira algo como isto:

 AnimationListener myListener = new AnimationListener(){/*bla bla bla*/}; alphaAnim.setAnimationListener(myListener); 

Uma solução bastante louca, eu sei, mas salvou minha bunda em várias ocasiões similaires.

Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.