TabLayoutBottomDemo【TabLayout实现底部选项卡】

版权声明:本文为博主原创文章,未经博主允许不得转载。

前言

使用TabLayout实现底部选项卡切换功能。

效果图

代码分析

1、演示固定模式的展现

2、演示自定义布局的实现

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

引入依赖库

在APP的build.gradle文件中添加以下代码【注意:版本号和com.android.support:appcompat-v7保持一致】

apply plugin: ‘com.android.application‘

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.why.project.tablayoutbottomdemo"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
        }
    }
}

dependencies {
    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2‘, {
        exclude group: ‘com.android.support‘, module: ‘support-annotations‘
    })
    compile ‘com.android.support:appcompat-v7:25.3.1‘
    testCompile ‘junit:junit:4.12‘
    //TabLayout
    compile ‘com.android.support:design:25.3.1‘
}

将选项卡子项布局文件tab_bottom_item.xml文件复制到项目中

<?xml version="1.0" encoding="utf-8"?>
<!-- 底部选项卡区域的子选项卡布局文件 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/tab_bg_normal"
    android:gravity="center" >

    <!-- android:checkMark="?android:attr/listChoiceIndicatorMultiple"代表多选
         android:checkMark="?android:attr/listChoiceIndicatorSingle" 代表单选
         该属性不添加的话,不会显示方框或者圆点
       -->

       <!-- android:drawableTop的属性值使用drawable目录下的selector选择器 -->
       <!-- android:tag="tag1"用于checkedTextview的索引 -->

       <!-- 选项卡的内容(图片+文字)类似RadioButton -->
    <!--android:textAlignment="center" 文本居中-->
    <CheckedTextView
        android:id="@+id/bottomtab_checkedTextView"
        android:tag="tag1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text=""
        android:textSize="@dimen/tab_text_size"
        android:textColor="@color/tab_text_normal"
        android:textAlignment="center"
        />
</RelativeLayout>

tab_bottom_item

将图片资源和selector文件复制到项目中【后续可根据实际情况更换图片】

 

在colors.xml文件中添加以下代码:【后续可根据实际情况更改背景颜色、文字颜色值】

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <!-- *********************************底部选项卡区域********************************* -->
    <!-- 底部选项卡底部背景色 -->
    <color name="tab_bg_normal">#00000000</color>
    <color name="tab_bg_selected">#00000000</color>
    <!-- 底部选项卡文本颜色 -->
    <color name="tab_text_normal">#8a8a8a</color>
    <color name="tab_text_selected">#38ADFF</color>
</resources>

在dimens.xml文件中添加以下代码:【后续可根据实际情况更改底部选项卡区域的高度值、文字大小值】

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

    <!-- *********************************底部选项卡区域********************************* -->
    <!--底部选项卡高度值-->
    <dimen name="tab_bottom_background_height">56dp</dimen>
    <!-- 底部选项卡文本大小 -->
    <dimen name="tab_text_size">14sp</dimen>
    <dimen name="tab_medium_text_size">16sp</dimen>
    <dimen name="tab_larger_text_size">18sp</dimen>
    <dimen name="tab_larger_small_text_size">20sp</dimen>

</resources>

在strings.xml文件中添加以下代码:【后续可根据实际情况更改底部选项卡的文字内容】

<resources>
    <string name="app_name">TabLayoutBottomDemo</string>

    <!-- *********************************底部选项卡区域********************************* -->
    <string name="home_function_home">首页</string>
    <string name="home_function_message">消息</string>
    <string name="home_function_contact">我的</string>

</resources>

至此,选项卡子项的布局所需的文件已集成到项目中了。

三、使用方法

在Activity布局文件中引用TabLayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.why.project.tablayoutbottomdemo.MainActivity">

    <!-- viewpager区域 -->
    <android.support.v4.view.ViewPager
        android:id="@+id/vp_tab"
        android:layout_width="match_parent"
        android:layout_height="0.0dp"
        android:layout_weight="1"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#cfcfcf">
    </View>

    <!-- 选项卡区域 -->
    <!--设置TabLayout的模式 app:tabMode 默认是fixed:固定的,标签很多时候会被挤压,不能滑动。-->
    <!--设置整个TabLayout的颜色 app:tabBackground-->
    <!--设置选中字体的颜色 app:tabSelectedTextColor-->
    <!--设置未选中字体的颜色 app:tabTextColor-->
    <!--设置指示器下标的颜色 app:tabIndicatorColor-->
    <!--设置指示器下标的高度 app:tabIndicatorHeight,如果设置的是0.0dp,则代表没有下划线-->
    <!--设置内容的显示模式 app:tabGravity,center : 居中,如果是fill,则是充满-->
    <android.support.design.widget.TabLayout
        android:id="@+id/tl_top"
        android:layout_width="match_parent"
        android:layout_height="@dimen/tab_bottom_background_height"
        app:tabBackground="@android:color/transparent"
        app:tabMode="fixed"
        app:tabIndicatorHeight="0dp"
        app:tabGravity="fill"
        />
</LinearLayout>

创建需要用到的fragment类和布局文件【后续可根据实际情况更改命名,并且需要重新import R文件】

 

创建选项卡子项model类TabItemModel

package com.why.project.tablayoutbottomdemo.model;

/**
 * Created by HaiyuKing
 * Used
 */

public class TabItemModel {
    private String tabTitle;
    private int tabImgResd;

    public TabItemModel(String tabTitle, int tabImgResd){
        this.tabTitle = tabTitle;
        this.tabImgResd = tabImgResd;
    }

    public String getTabTitle() {
        return tabTitle;
    }

    public void setTabTitle(String tabTitle) {
        this.tabTitle = tabTitle;
    }

    public int getTabImgResd() {
        return tabImgResd;
    }

    public void setTabImgResd(int tabImgResd) {
        this.tabImgResd = tabImgResd;
    }
}

创建viewpager的适配器

package com.why.project.tablayoutbottomdemo.adapter;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import com.why.project.tablayoutbottomdemo.model.TabItemModel;

import java.util.List;

/**
 * Created by HaiyuKing
 * Used
 */

public class ContentPagerAdapter extends FragmentPagerAdapter {

    private List<TabItemModel> tabIndicators;
    private List<Fragment> tabItemList;

    public ContentPagerAdapter(FragmentManager fm, List<TabItemModel> tabIndicators, List<Fragment> tabItemList) {
        super(fm);
        this.tabIndicators = tabIndicators;
        this.tabItemList = tabItemList;
    }

    @Override
    public Fragment getItem(int position) {
        return tabItemList.get(position);
    }

    @Override
    public int getCount() {
        return tabItemList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabIndicators.get(position).getTabTitle();
    }
}

在Activity中使用如下【继承FragmentActivity或者其子类】

package com.why.project.tablayoutbottomdemo;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckedTextView;

import com.why.project.tablayoutbottomdemo.adapter.ContentPagerAdapter;
import com.why.project.tablayoutbottomdemo.fragment.ContactFragment;
import com.why.project.tablayoutbottomdemo.fragment.HomeFragment;
import com.why.project.tablayoutbottomdemo.fragment.MessageFragment;
import com.why.project.tablayoutbottomdemo.model.TabItemModel;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager mTabViewPager;

    /**碎片声明*/
    private HomeFragment homeFragment;//首页
    private MessageFragment messageFragment;//消息
    private ContactFragment contactFragment;//我的

    private List<TabItemModel> tabIndicators;
    private List<Fragment> tabFragments;
    private ContentPagerAdapter contentAdapter;

    //选项卡的各个选项的CheckedTextView的集合:用于切换时改变图标和文字颜色
    private List<CheckedTextView> bottomTab_checkeds = new ArrayList<CheckedTextView>();

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

        initViews();
        initDatas();
        initEvents();
    }

    private void initViews() {
        mTabLayout = (TabLayout) findViewById(R.id.tl_top);
        mTabViewPager = (ViewPager) findViewById(R.id.vp_tab);
    }

    private void initDatas() {
        //初始化选项卡子项的文本、图标model集合
        tabIndicators = new ArrayList<TabItemModel>();
        tabIndicators.add(new TabItemModel(getResources().getString(R.string.home_function_home),
                R.drawable.home_tab_home_selector));
        tabIndicators.add(new TabItemModel(getResources().getString(R.string.home_function_message),
                R.drawable.home_tab_message_selector));
        tabIndicators.add(new TabItemModel(getResources().getString(R.string.home_function_contact),
                R.drawable.home_tab_contact_selector));
        //初始化碎片集合
        tabFragments = new ArrayList<>();
        homeFragment = HomeFragment.getInstance(HomeFragment.class,null);
        messageFragment = MessageFragment.getInstance(MessageFragment.class,null);
        contactFragment = ContactFragment.getInstance(ContactFragment.class,null);
        tabFragments.add(homeFragment);
        tabFragments.add(messageFragment);
        tabFragments.add(contactFragment);
        //实例化Adapter
        contentAdapter = new ContentPagerAdapter(getSupportFragmentManager(),tabIndicators,tabFragments);
        mTabViewPager.setAdapter(contentAdapter);
        //TabLayout和ViewPager相关联
        mTabLayout.setupWithViewPager(mTabViewPager);

        //自定义布局的话,必须放到setupWithViewPager后面
        for (int i = 0; i < tabIndicators.size(); i++) {
            TabLayout.Tab itemTab = mTabLayout.getTabAt(i);
            if (itemTab!=null){
                itemTab.setCustomView(R.layout.tab_bottom_item);
                View bottomtabitemView = itemTab.getCustomView();
                //===========设置CheckedTextView控件的图片和文字==========
                final CheckedTextView bottomtab_checkedTextView = (CheckedTextView) bottomtabitemView.findViewById(R.id.bottomtab_checkedTextView);

                //设置CheckedTextView控件的android:drawableTop属性值
                Drawable drawable = ContextCompat.getDrawable(this,tabIndicators.get(i).getTabImgResd());
                //setCompoundDrawables 画的drawable的宽高是按drawable.setBound()设置的宽高
                //而setCompoundDrawablesWithIntrinsicBounds是画的drawable的宽高是按drawable固定的宽高,即通过getIntrinsicWidth()与getIntrinsicHeight()自动获得
                drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
                bottomtab_checkedTextView.setCompoundDrawables(null, drawable, null, null);
                //bottomtab_checkedTextView.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);

                //设置CheckedTextView的文字
                bottomtab_checkedTextView.setText(tabIndicators.get(i).getTabTitle());

                bottomTab_checkeds.add(bottomtab_checkedTextView);
            }
        }

        //设置第一选项卡为选中状态
        mTabLayout.getTabAt(0).getCustomView().setSelected(true);
        bottomTab_checkeds.get(0).setTextColor(getResources().getColor(R.color.tab_text_selected));
    }

    private void initEvents() {
        mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //选中了tab的逻辑
                bottomTab_checkeds.get(tab.getPosition()).setTextColor(getResources().getColor(R.color.tab_text_selected));
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                //未选中了tab的逻辑
                bottomTab_checkeds.get(tab.getPosition()).setTextColor(getResources().getColor(R.color.tab_text_normal));
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //再次选中了tab的逻辑
            }
        });
    }
}

混淆配置

参考资料

Android TabLayout 分分钟打造一个滑动标签页

Design库-TabLayout属性详解

Design库-TabLayout仿京东商品详情Tab

TabLayout

项目demo下载地址

https://github.com/haiyuKing/TabLayoutBottomDemo

时间: 2024-08-29 10:13:10

TabLayoutBottomDemo【TabLayout实现底部选项卡】的相关文章

FragmentTabHostBottomDemo【FragmentTabHost + Fragment实现底部选项卡】

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 使用FragmentTabHost实现底部选项卡效果. 备注:该Demo主要是演示FragmentTabHost的一些设置和部分功能,实际中需要参考其他Demo. 效果图 代码分析 1.该Demo中采用的是FragmentTabHost的布局方案之一[命名为非常规布局写法]:[建议使用常规布局写法,见<FragmentTabHostTopDemo[FragmentTabHost固定宽度且居中]>] 2.未使用自定义的FragmentT

HTML5 开发APP(头部和底部选项卡)

我们开发app有一定固定的样式,比如头部和底部选项卡部分就是公共部分就比如我在做的app进来的主页面就像图片显示的那样 我们该怎么实现呢,实现我们应该建一个主页面index.html,然后建五个子页面,通过mui来实现切换功能. 在index的html部分写下这样的代码 <body> <header class="mui-bar mui-bar-nav" style="padding-right: 15px;background: #00be68;"

MUI组价五:开关、底部选项卡、9宫格和分页

1.switch(开关) mui提供了开关控件,点击滑动两种手势都可以对开关控件进行操作,UI如下:默认开关控件,带on/off文字提示,打开时为绿色背景,基本class类为.mui-switch..mui-switch-handle,DOM结构如下: <div class="mui-switch"> <div class="mui-switch-handle"></div> </div> 若希望开关默认为打开状态,只

vue2.0中使用mint ui做底部选项卡切换

首先在vue2.0中webpack中下载 mint ui 然后再main.js引入 这样就可以使用mint ui里面的布局组件了html部分(就是你要使用底部选项卡的部分) <!--底部选项卡--><mt-tab-container v-model="selected"> <mt-tab-container-item id="one"> one </mt-tab-container-item> <mt-tab-c

MUI底部选项卡链接跳转不了

问题描述: 用MUI例子中的选项卡,底部的导航只能实现div切换,链接无法跳转. 查看控制台,输出:Unable to preventDefault inside passive event listener due to target 的警告. 问题解决: 经检查相关资料,加入以下代码,即可解决问题. mui('body').on('tap','a',function(){document.location.href=this.href;}); 问题原因: MUI在选项卡中的文字中已说明: 通

TabLayout实现底部导航栏(2)

TabLayout是android.support.design里的一个控件,使用它可以很方便的做出顶部导航和底部导航.类似于这样的,能设置选中时字体的颜色和选中时的图片. 效果如图: 首先我们在 build.gradle中引入 compile 'com.android.support:design:23.2.1' 布局文件如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:

031实现仿iPhone的底部选项卡

效果如下: ViewController.h 1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UITabBarController 4 @end ViewController.m 1 #import "ViewController.h" 2 #import "SampleScene.h" 3 4 @interface ViewController () 5 - (void)layoutU

支付宝底部选项卡

支付宝小程序app.js中代码如下 editTabBar: function () { var e = this.globalData.tabbar, a = getCurrentPages(), t = a[a.length - 1], s = t.route; console.log(t) console.log(s) 0 != s.indexOf("/") && (s = "/" + s); for (var n in e.items) e.i

FragmentTabHostAutoDemo【FragmentTabHost可滑动的选项卡】

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 使用FragmentTabHost实现顶部选项卡(可滑动的效果)展现. 效果图 代码分析 1.该Demo中采用的是FragmentTabHost的布局方案之一[命名为常规布局写法]: 2.使用自定义的FragmentTabHost: 3.实现可滑动效果: 4.设置下划线的宽度和文字的宽度一致: 使用步骤 一.项目组织结构图 注意事项: 1.  导入类文件后需要change包名以及重新import R文件路径 2.  Values目录下的