2012-04-04 15 views
6

Estoy tratando de agregar una animación a mi TabActivty. Por ejemplo, cuando el usuario selecciona la segunda pestaña, quiero que la nueva actividad provenga de la derecha. Cuando el usuario selecciona la primera pestaña, quiero que la actividad provenga de la izquierda.Android - TabActivity con animación de transición

He encontrado cómo agregar una animación, pero quiero agregar una nuevamente. Aquí está el código que estoy usando:

public Animation inFromRightAnimation() 
{ 
    Animation inFromRight = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT, +1.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f); 
    inFromRight.setDuration(240); 
    inFromRight.setInterpolator(new AccelerateInterpolator()); 
    return inFromRight; 
} 

Y

getTabHost().setOnTabChangedListener(new OnTabChangeListener() { 
     public void onTabChanged(String tabId) 
     { 
      View currentView = getTabHost().getCurrentView(); 
      currentView.setAnimation(inFromRightAnimation()); 
     } 
}); 

¿Cómo puedo hacer eso?

Gracias.

Atentamente.

V.

+0

puede ser útil: http://www.techienjoy.com/android-tab-example.php – Nimit

Respuesta

12

Esto funciona correctamente:

getTabHost().setOnTabChangedListener(new OnTabChangeListener() { 
    public void onTabChanged(String tabId) 
    { 
      View currentView = getTabHost().getCurrentView(); 
      if (getTabHost().getCurrentTab() > currentTab) 
      { 
       currentView.setAnimation(inFromRightAnimation()); 
      } 
      else 
      { 
       currentView.setAnimation(outToRightAnimation()); 
      } 

      currentTab = getTabHost().getCurrentTab(); 
    } 
}); 

Y las animaciones:

public Animation inFromRightAnimation() 
{ 
    Animation inFromRight = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT, +1.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f); 
    inFromRight.setDuration(240); 
    inFromRight.setInterpolator(new AccelerateInterpolator()); 
    return inFromRight; 
} 

public Animation outToRightAnimation() 
{ 
    Animation outtoLeft = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT, -1.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f, 
      Animation.RELATIVE_TO_PARENT, 0.0f); 
    outtoLeft.setDuration(240); 
    outtoLeft.setInterpolator(new AccelerateInterpolator()); 
    return outtoLeft; 
} 
1

Usted tiene que usar String tabId y comprobar if este tabId==firstTab a continuación, poner la animación de izquierda else animación de derecha.

+0

Ok gracias. Pero lo que quiero es algo como 'if (previous_tab> tabId) animation = 'left to right'' y' if (previous_tab Manitoba

1

Si lo desea, puede utilizar Android Support Package - http://developer.android.com/sdk/compatibility-library.html

Con poco esfuerzo se puede modificar la actividad para usar fragmentos para que sus pestañas puedan tener animaciones de transición al igual que la aplicación de YouTube. Aquí es un código de ejemplo de cómo implementarlo - http://developer.android.com/sdk/compatibility-library.html

Editar: Si no desea utilizar el paquete de soporte, tal vez esta aplicación le ayudará

MyGestureDetector clase privada se extiende SimpleOnGestureListener {

 private static final int SWIPE_MIN_DISTANCE = 120; 
     private static final int SWIPE_MAX_OFF_PATH = 250; 
     private static final int SWIPE_THRESHOLD_VELOCITY = 200; 

     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     //get density 
      final DisplayMetrics metrics = getResources().getDisplayMetrics(); 
      final float density = metrics.density; 
     //System.out.println(" in onFling() :: "); 
      //off path 
      if (Math.abs(e1.getY() - e2.getY()) > density*SWIPE_MAX_OFF_PATH) 
       return false; 
      //fling from right to left 
      if (e1.getX() - e2.getX() > density*SWIPE_MIN_DISTANCE && Math.abs(velocityX) > density*SWIPE_THRESHOLD_VELOCITY) { 
       //if the first tab is selected 
       if(currentSelection.equalsIgnoreCase(getString(R.string.tab_details_info))) { 
        //switch to second tab and save current selection 
        tabs.setCurrentTab(1); 
        currentSelection = tabs.getCurrentTabTag(); 
       } 
       //if the second tab is selected 
       else if(currentSelection.equalsIgnoreCase(getString(R.string.tab_details_details))) { 
        //switch to second tab and save current selection 
        tabs.setCurrentTab(2); 
        currentSelection = tabs.getCurrentTabTag(); 
       } 
      } 
      //fling from left to right 
      else if (e2.getX() - e1.getX() > density*SWIPE_MIN_DISTANCE && Math.abs(velocityX) > density*SWIPE_THRESHOLD_VELOCITY) { 

       //if the second tab is selected 
       if(currentSelection.equalsIgnoreCase(getString(R.string.tab_details_details))) { 
        //switch to second tab and save current selection 
        tabs.setCurrentTab(0); 
        currentSelection = tabs.getCurrentTabTag(); 
       } 
       //if the third tab is selected 
       else if(currentSelection.equalsIgnoreCase(getString(R.string.tab_details_company))) { 
        //switch to second tab and save current selection 
        tabs.setCurrentTab(1); 
        currentSelection = tabs.getCurrentTabTag(); 
       } 
      } 
      return super.onFling(e1, e2, velocityX, velocityY); 
     } 
} 

y luego, en la pestaña modificada del oyente solo cargue la animación adecuada, ya que sabe cuál fue seleccionada antes del gesto, y la que estamos cambiando después.

 @Override 
     public void onTabChanged(String tabId) { 



      //if the first tab is selected 
      if(currentSelection.equalsIgnoreCase(getResources().getString(R.string.tab_details_info))) { 
       //if we switch to second 
       if(tabId.equalsIgnoreCase(getResources().getString(R.string.tab_details_details))) { 
        linearInfo.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_out)); 
        linearDetails.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_in)); 
        linearCompany.setAnimation(null); 
       } 
       //if switch to third 
       else if(tabId.equalsIgnoreCase(getResources().getString(R.string.tab_details_company))) { 
        linearInfo.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_out)); 
        linearDetails.setAnimation(null); 
        linearCompany.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_in)); 
       } 
      } 
      //if the second tab is selected 
      else if(currentSelection.equalsIgnoreCase(getResources().getString(R.string.tab_details_details))) { 
       //if we switch to first 
       if(tabId.equalsIgnoreCase(getResources().getString(R.string.tab_details_info))) { 
        linearInfo.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_in)); 
        linearDetails.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_out)); 
        linearCompany.setAnimation(null); 
       } 
       //if switch to third 
       else if(tabId.equalsIgnoreCase(getResources().getString(R.string.tab_details_company))) { 
        linearInfo.setAnimation(null); 
        linearDetails.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_out)); 
        linearCompany.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_in)); 
       } 
      } 
      //if the third tab is selected 
      else if(currentSelection.equalsIgnoreCase(getResources().getString(R.string.tab_details_company))) { 
       //if we switch to first 
       if(tabId.equalsIgnoreCase(getResources().getString(R.string.tab_details_info))) { 
        linearInfo.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_in)); 
        linearDetails.setAnimation(null); 
        linearCompany.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_out)); 
       } 
       //if switch to second 
       else if(tabId.equalsIgnoreCase(getResources().getString(R.string.tab_details_details))) { 
        linearInfo.setAnimation(null); 
        linearDetails.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_in)); 
        linearCompany.setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_out)); 
       } 
      } 

      currentSelection = tabId; 
     } 
    }; 

También hay que coger el gesto reemplazando el onTouchListener contigo detector gesto personalizado (y tal vez representan el diferente densidad pantalla de la hora de determinar si un gesto es una acción de golpe)

Lo siento por la respuesta larga , pero espero que ayude :)

+0

Sí, sé que puedo hacer eso con fragmentos y su pila, pero quiero que mi aplicación use el nivel más bajo de la API.Además, mi aplicación está casi terminada. Solo necesito implementar ese gesto. – Manitoba

5

Escribí un OnTabChangeListener personalizado basado en este código que quería compartir. Con suerte alguien puede usarlo :). El crédito es para Vomenki por el código original.

package net.danielkvist.receipttracker.listener; 

import android.view.View; 
import android.view.animation.AccelerateInterpolator; 
import android.view.animation.Animation; 
import android.view.animation.TranslateAnimation; 
import android.widget.TabHost; 
import android.widget.TabHost.OnTabChangeListener; 

/** 
* A custom OnTabChangeListener that uses the TabHost its related to to fetch information about the current and previous 
* tabs. It uses this information to perform some custom animations that slide the tabs in and out from left and right. 
* 
* @author Daniel Kvist 
* 
*/ 
public class AnimatedTabHostListener implements OnTabChangeListener 
{ 

    private static final int ANIMATION_TIME = 240; 
    private TabHost tabHost; 
    private View previousView; 
    private View currentView; 
    private int currentTab; 

    /** 
    * Constructor that takes the TabHost as a parameter and sets previousView to the currentView at instantiation 
    * 
    * @param tabHost 
    */ 
    public AnimatedTabHostListener(TabHost tabHost) 
    { 
     this.tabHost = tabHost; 
     this.previousView = tabHost.getCurrentView(); 
    } 

    /** 
    * When tabs change we fetch the current view that we are animating to and animate it and the previous view in the 
    * appropriate directions. 
    */ 
    @Override 
    public void onTabChanged(String tabId) 
    { 

     currentView = tabHost.getCurrentView(); 
     if (tabHost.getCurrentTab() > currentTab) 
     { 
      previousView.setAnimation(outToLeftAnimation()); 
      currentView.setAnimation(inFromRightAnimation()); 
     } 
     else 
     { 
      previousView.setAnimation(outToRightAnimation()); 
      currentView.setAnimation(inFromLeftAnimation()); 
     } 
     previousView = currentView; 
     currentTab = tabHost.getCurrentTab(); 

    } 

    /** 
    * Custom animation that animates in from right 
    * 
    * @return Animation the Animation object 
    */ 
    private Animation inFromRightAnimation() 
    { 
     Animation inFromRight = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 1.0f, Animation.RELATIVE_TO_PARENT, 0.0f, 
       Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f); 
     return setProperties(inFromRight); 
    } 

    /** 
    * Custom animation that animates out to the right 
    * 
    * @return Animation the Animation object 
    */ 
    private Animation outToRightAnimation() 
    { 
     Animation outToRight = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 1.0f, 
       Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f); 
     return setProperties(outToRight); 
    } 

    /** 
    * Custom animation that animates in from left 
    * 
    * @return Animation the Animation object 
    */ 
    private Animation inFromLeftAnimation() 
    { 
     Animation inFromLeft = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -1.0f, Animation.RELATIVE_TO_PARENT, 0.0f, 
       Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f); 
     return setProperties(inFromLeft); 
    } 

    /** 
    * Custom animation that animates out to the left 
    * 
    * @return Animation the Animation object 
    */ 
    private Animation outToLeftAnimation() 
    { 
     Animation outtoLeft = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, -1.0f, 
       Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f); 
     return setProperties(outtoLeft); 
    } 

    /** 
    * Helper method that sets some common properties 
    * @param animation the animation to give common properties 
    * @return the animation with common properties 
    */ 
    private Animation setProperties(Animation animation) 
    { 
     animation.setDuration(ANIMATION_TIME); 
     animation.setInterpolator(new AccelerateInterpolator()); 
     return animation; 
    } 
} 
+0

¡Gracias por el esfuerzo, funciona muy bien! – wufoo

+0

He agregado gestos para deslizar entre pestañas también ahora, puedes encontrar la clase aquí: http://danielkvist.net/portfolio/animated-tabhost-with-slide-gesture-in-android – span

Cuestiones relacionadas