Android - TabHost 与 Fragment 制作页面切换效果

Android - TabHost 与 Fragment 制作页面切换效果

Android API 19 , API 23

三个标签页置于顶端

效果图:
Android - TabHost 与 Fragment 制作页面切换效果Android - TabHost 与 Fragment 制作页面切换效果
在文件BoardTabHost.java中定义页面切换的效果;切换页面时,当前页面滑出,目标页面滑入。这是2个不同的动画
设定动画时要区分对待


import android.content.Context;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.TabHost;

public class BoardTabHost extends TabHost {

    private int currentTab = 0;
    int duration = 1000;// ms; the bigger the slower

    public BoardTabHost(Context context) {
        super(context);
    }

    public BoardTabHost(Context context, AttributeSet attr) {
        super(context, attr);
    }

    @Override
    public void setCurrentTab(int index) {
        // we need two animation here: first one is fading animation, 2nd one is coming animation
        // translateAnimation of fading fragment
        if (index > currentTab) {// fly right to left and leave the screen
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    Animation.RELATIVE_TO_SELF/* fromXType */, 0f/* fromXValue */,
                    Animation.RELATIVE_TO_SELF/* toXType */, -1.0f/* toXValue */,
                    Animation.RELATIVE_TO_SELF, 0f,
                    Animation.RELATIVE_TO_SELF, 0f
            );
            translateAnimation.setDuration(duration);
            getCurrentView().startAnimation(translateAnimation);
        } else if (index < currentTab) {// fly left to right
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    Animation.RELATIVE_TO_SELF, 0f,
                    Animation.RELATIVE_TO_SELF, 1.0f,
                    Animation.RELATIVE_TO_SELF, 0f,
                    Animation.RELATIVE_TO_SELF, 0f
            );
            translateAnimation.setDuration(duration);
            getCurrentView().startAnimation(translateAnimation);
        }
        super.setCurrentTab(index);// the current tab is index now
        // translateAnimation of adding fragment
        if (index > currentTab) {
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    Animation.RELATIVE_TO_PARENT, 1.0f,/* fly into screen */
                    Animation.RELATIVE_TO_PARENT, 0f,  /* screen location */
                    Animation.RELATIVE_TO_PARENT, 0f,
                    Animation.RELATIVE_TO_PARENT, 0f
            );
            translateAnimation.setDuration(duration);
            getCurrentView().startAnimation(translateAnimation);
        } else if (index < currentTab) {
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    Animation.RELATIVE_TO_PARENT, -1.0f,
                    Animation.RELATIVE_TO_PARENT, 0f,
                    Animation.RELATIVE_TO_PARENT, 0f,
                    Animation.RELATIVE_TO_PARENT, 0f
            );
            translateAnimation.setDuration(duration);
            getCurrentView().startAnimation(translateAnimation);
        }
        currentTab = index;
    }
}

对应的布局文件activity_board.xml
使用BoardTabHost,装载一个竖直的LinearLayout;上面是TabWidget,装载标签;后面是fragment的FrameLayout
可以看到这里有3个fragment,待会在activity中也设置3个标签

<?xml version="1.0" encoding="utf-8"?>
<com.rust.tabhostdemo.BoardTabHost
    android:id="@android:id/tabhost"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.rust.tabhostdemo.BoardActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <fragment
                android:id="@+id/fragment_tab1"
                android:name="com.rust.tabhostdemo.TabFragment1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

            <fragment
                android:id="@+id/fragment_tab2"
                android:name="com.rust.tabhostdemo.TabFragment2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

            <fragment
                android:id="@+id/fragment_tab3"
                android:name="com.rust.tabhostdemo.TabFragment3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </FrameLayout>
    </LinearLayout>
</com.rust.tabhostdemo.BoardTabHost>

值得一提的是,这里的id要用android指定的id;
比如@android:id/tabhost@android:id/tabcontent@android:id/tabs;否则系统找不到对应控件而报错

BoardActivity.java中设置了3个标签页,并指定了标签对应的fragment

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;

public class BoardActivity extends FragmentActivity {

    public static final String TAB1 = "tab1";
    public static final String TAB2 = "tab2";
    public static final String TAB3 = "tab3";

    public static BoardTabHost boardTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_board);

        boardTabHost = (BoardTabHost) findViewById(android.R.id.tabhost);
        boardTabHost.setup();

        boardTabHost.addTab(boardTabHost.newTabSpec(TAB1).setIndicator(getString(R.string.tab1_name))
                .setContent(R.id.fragment_tab1));
        boardTabHost.addTab(boardTabHost.newTabSpec(TAB2).setIndicator(getString(R.string.tab2_name))
                .setContent(R.id.fragment_tab2));
        boardTabHost.addTab(boardTabHost.newTabSpec(TAB3).setIndicator(getString(R.string.tab3_name))
                .setContent(R.id.fragment_tab3));

        boardTabHost.setCurrentTab(0);

    }
}

主要文件目录:
── layout
├── activity_board.xml
├── fragment_tab1.xml
├── fragment_tab2.xml
└── fragment_tab3.xml

── tabhostdemo
├── BoardActivity.java
├── BoardTabHost.java
├── TabFragment1.java
├── TabFragment2.java
└── TabFragment3.java

上一篇:Java学习笔记----如何保证线程安全


下一篇:[Python笔记]第四篇:内置函数