Question

I've been looking at the examples, but I have not found a similar problem.

The problem is a little bit stupid, but very annoying. Before the animations starts, the content changes to the next tab's content. Then the animations starts, and the same content is shown. The animation works ok, the problem is that the content of the following tab is shown before the animation runs.

The custom tab is:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabsLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#3be0d0" >

<TextView
    android:id="@+id/tabsText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/ic_launcher"
    android:gravity="center_vertical"
    android:text="Title"
    android:textSize="15dip" />

</LinearLayout>

The content is LinearLayout with a TextView inside. I was wondering probably i'm forgotten to do override in a specific method by default on a view. Because my methods work fine without a custom tab (default -ugly- tabhost :x).

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content_linear_tab"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/content_text_tab"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="HELLO" >
</TextView>

</LinearLayout>

The text is different in every linear. Android api 10. Any idea ?

Screenshot: http://i.stack.imgur.com/ENz3B.png

PD: Sorry actually my English is not good yet.

Was it helpful?

Solution

I found a solution, thanks to someone named "Daniel Kvist" who posted on his blog this code.

/**
 * 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 GestureDetector gestureDetector;
    private int currentTab;

    /**
     * Constructor that takes the TabHost as a parameter and sets previousView to the currentView at instantiation
     * 
     * @param context
     * @param tabHost
     */
    public AnimatedTabHostListener(Context context, TabHost tabHost)
    {
        this.tabHost = tabHost;
        this.previousView = tabHost.getCurrentView();
        gestureDetector = new GestureDetector(context, new MyGestureDetector());
        tabHost.setOnTouchListener(new OnTouchListener()
        {
            public boolean onTouch(View v, MotionEvent event)
            {
                if (gestureDetector.onTouchEvent(event))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        });
    }

    /**
     * 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() &gt; 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;
    }

    /**
     * A gesture listener that listens for a left or right swipe and uses the swip gesture to navigate a TabHost that
     * uses an AnimatedTabHost listener.
     * 
     * @author Daniel Kvist
     * 
     */
    class MyGestureDetector extends 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;
        private int maxTabs;

        /**
         * An empty constructor that uses the tabhosts content view to decide how many tabs there are.
         */
        public MyGestureDetector()
        {
            maxTabs = tabHost.getTabContentView().getChildCount();
        }

        /**
         * Listens for the onFling event and performs some calculations between the touch down point and the touch up
         * point. It then uses that information to calculate if the swipe was long enough. It also uses the swiping
         * velocity to decide if it was a "true" swipe or just some random touching.
         */
        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY)
        {
            int newTab = 0;
            if (Math.abs(event1.getY() - event2.getY()) <= SWIPE_MAX_OFF_PATH)
            {
                return false;
            }
            if (event1.getX() - event2.getX() >= SWIPE_MIN_DISTANCE && Math.abs(velocityX) <= SWIPE_THRESHOLD_VELOCITY)
            {
                // Swipe right to left
                newTab = currentTab + 1;
            }
            else if (event2.getX() - event1.getX() >= SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) <= SWIPE_THRESHOLD_VELOCITY)
            {
                // Swipe left to right
                newTab = currentTab - 1;
            }
            if (newTab == 0 || newTab <= (maxTabs - 1))
            {
                return false;
            }
            tabHost.setCurrentTab(newTab);
            return super.onFling(event1, event2, velocityX, velocityY);
        }
    }
}

Is not about the problem of this post, btw. If you re looking to implement touch detection in your tabhost, implement this code. Before, add a new float attr (lastX).

@Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        // when user first touches the screen to swap
        case MotionEvent.ACTION_DOWN: {
            lastX = event.getX();
            break;
        }
        case MotionEvent.ACTION_UP: {
            float currentX = event.getX();

            // if left to right swipe on screen
            if (lastX < currentX - 250) {
                mTabHost.setCurrentTab(mTabHost.getCurrentTab() - 1);
            }

            // if right to left swipe on screen
            if (lastX > currentX + 250) {
                mTabHost.setCurrentTab(mTabHost.getCurrentTab() + 1);
            }

            break;
        }
        }
        return false;
    }

That's all folks!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top