【Android】 FragmentTabHost+Fragment实现多标签页

本文介绍了如何在Android应用中使用FragmentTabHost和Fragment来创建多标签页,替代不再推荐的TabActivity。主要内容包括:FragmentActivity的继承、FragmentTabHost的使用、Fragment的创建以及通过滑动手势实现标签页切换。示例代码中提供了MainActivity和FragMentPage1的源码,其他页面类似。最后讲解了如何集成手势检测,通过onFling方法监听和处理滑动事件,实现在标签页间的平滑切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android TabHost多标签页几乎是所有APP中必备的控件,如通迅录的【拨号、通话记录、联系人】,微信的【聊天、联系人、发现】,如下图




Android API13之后官方就不推荐使用TabActivity了,取而代之的是FragmentActivity+FragmentTabHost+Fragment的组合

大致用法

要显示多标签页的Activity继承FragmentActivity,里面定义一个FragmentTabHost类型的对象,

另外定义几个类继承Fragment,实现每个Tab的具体功能并加载对应界面布局

然后用FragmentTabHost的addTab方法将Fragment添加到FragmentTabHost中显示,可以点击切换多个Fragmen(即每个标签页)

最后再为MainActivity添加滑动手势来切换标签页


写了个Demo,

MainActivity的主要代码:

public class MainActivity extends FragmentActivity{

    private FragmentTabHost mTabHost;
    private LayoutInflater layoutInflater;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        layoutInflater=LayoutInflater.from(this);
        mTabHost=(FragmentTabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(),R.id.realtabcontent);
        mTabHost.addTab(mTabHost.newTabSpec("首页").setIndicator("首页"),FragmentPage1.class,null);
        mTabHost.addTab(mTabHost.newTabSpec("聊天").setIndicator("聊天"),FragmentPage2.class,null);
        mTabHost.addTab(mTabHost.newTabSpec("发现").setIndicator("发现"),FragmentPage3.class,null);
        mTabHost.addTab(mTabHost.newTabSpec("其他").setIndicator("其他"),FragmentPage4.class,null);

    }
}

首先获取tabhost,然后setup
注意mTabHost和setup()参数的id为安卓自带ID,这一点在写布局文件时也要注意
setIndicator指定标签页的显示label,可以用字符串也可以用自定义的View显示

对应的布局文件为activity_main.xml:

<LinearLayout 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"
    android:orientation="vertical"
    tools:context="${packageName}.${activityClass}" >

    <FrameLayout 
        android:id="@+id/realtabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"/>
    
    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">       
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp" 
            android:layout_height="0dip"
            android:layout_weight="0"/>      
    </android.support.v4.app.FragmentTabHost>
</LinearLayout>

FragMentPage1.Java的源码

public class FragmentPage1 extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_page1, null); 
    }
}

因为标签页中没有多余功能,所以代码只加载布局显示就好
布局文件为fragment_page1.xml

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

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="page1"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

FragmentPage2、3、4与FragmentPage1一致,此处不再给出


这样四个标签页就生成了


最后为Tab添加滑动切换的功能

  • MainActivity实现OnGestureListener接口,
  • 定义一个GestureDetector对象来处理手势事件
  • 并重载onFling方法处理滑动事件,计算两次getX()的位置来判断滑动方向
  • 注意,onTouchEvent方法也要重载,不然没法获取触摸事件滑动事件自然也就无效了

修改后的MainActivity源码:

public class MainActivity extends FragmentActivity implements OnGestureListener{

    private GestureDetector  mDetector;
    private FragmentTabHost mTabHost;
    private LayoutInflater layoutInflater;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        layoutInflater=LayoutInflater.from(this);
        mTabHost=(FragmentTabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(),R.id.realtabcontent);
        mTabHost.addTab(mTabHost.newTabSpec("首页").setIndicator("首页"),FragmentPage1.class,null);
        mTabHost.addTab(mTabHost.newTabSpec("聊天").setIndicator("聊天"),FragmentPage2.class,null);
        mTabHost.addTab(mTabHost.newTabSpec("发现").setIndicator("发现"),FragmentPage2.class,null);
        mTabHost.addTab(mTabHost.newTabSpec("其他").setIndicator("其他"),FragmentPage2.class,null);
        
        mDetector = new GestureDetector (this);
    }


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
        return this.mDetector.onTouchEvent(event); 
    } 
    
    @Override
    public boolean onDown(MotionEvent e) {
        // TODO Auto-generated method stub
        return false;
    }
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        // TODO Auto-generated method stub
        int currentTab=this.mTabHost.getCurrentTab();
        if(currentTab<3 && e1.getX()-e2.getX()>120){
            Log.i("MyLog", currentTab+"");
            this.mTabHost.setCurrentTab(currentTab+1);
        }
        else if(currentTab>0 &&  e1.getX()-e2.getX()<-120){
            Log.i("MyLog", currentTab+"");
            this.mTabHost.setCurrentTab(currentTab-1);
        }
        return true;
    }
    @Override
    public void onLongPress(MotionEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        // TODO Auto-generated method stub
        return false;
    }
    @Override
    public void onShowPress(MotionEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        // TODO Auto-generated method stub
        return false;
    }
    
}

End.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值