android自带的有TabHost,但好像无法满足要求,

本文只记录使用 TabLayout + Fragment  和 android 自带的 BottomNavigationView + Fragment 来实现

由于测试的时候使用的是一个工程,所以看起来可能有点乱,但是里面的工程目录没有变化,变化的只是代码部分

需要新建的部分如下:

新建一个工程,如果是在做项目,不要在原项目中进行操作,以免损坏原项目,

通用部分,Fragment部分,(xml和对应的java代码),Androidstudio中会自带代码,不需要改动里面的代码

添加对应的包依赖

menu是 BottomNavigationView + Fragment需要的,如果工程中不使用自带的新建的话,可以不需要建立这一部分,

接下来先介绍 TabLayout + Fragment :

主页面的布局代码,

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     android:orientation="vertical"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent">
 7 
 8     <FrameLayout
 9         android:id="@+id/home_container"
10         android:layout_width="match_parent"
11         android:layout_height="0dp"
12         android:layout_weight="1"
13         >
14     </FrameLayout>
15 
16     <View android:layout_width="match_parent"
17         android:layout_height="0.5dp"
18         android:alpha="0.6"
19         android:background="@android:color/darker_gray"
20         />
21     <android.support.design.widget.TabLayout
22         android:id="@+id/bottom_tab_layout"   
23         android:layout_width="match_parent"
24         app:tabIndicatorHeight="0dp"
25         app:tabSelectedTextColor="@android:color/black"
26         app:tabTextColor="@android:color/darker_gray"
27         android:layout_height="48dp">
28         <!--app:menu="@menu/tab_menu" 如果需要使用 BottomNavigationView + Fragment 布局的话取消注释,更改id即可-->
29 
30     </android.support.design.widget.TabLayout>
31 
32 </LinearLayout>

 

 3 import android.content.Context;
 4 import android.support.v4.app.Fragment;
 5 import android.view.LayoutInflater;
 6 import android.view.View;
 7 import android.widget.ImageView;
 8 import android.widget.TextView;
 9 
10 import com.example.tabhostcostom.AttentionFragment;
11 import com.example.tabhostcostom.DiscoveryFragment;
12 import com.example.tabhostcostom.HomeFragment;
13 import com.example.tabhostcostom.ProfileFragment;
14 import com.example.tabhostcostom.R;
15 
16 public class DataGenerator {
17 
18     public static final int []mTabRes = new int[]{R.mipmap.index_blue_icon, R.mipmap.index_message, R.mipmap.index_publish, R.mipmap.index_ying, R.mipmap.index_me};
19     //public static final int []mTabResPressed = new int[]{R.drawable.ic_tab_strip_icon_feed_selected,R.drawable.ic_tab_strip_icon_category_selected,R.drawable.ic_tab_strip_icon_pgc_selected,R.drawable.ic_tab_strip_icon_profile_selected};
20     public static final String []mTabTitle = new String[]{"首页","发现","", "关注","我的"};
21 
22     public static Fragment[] getFragments(String from){
23         Fragment fragments[] = new Fragment[4];
24         fragments[0] = HomeFragment.newInstance(from, "a");
25         fragments[1] = DiscoveryFragment.newInstance(from, "b");
26         fragments[2] = AttentionFragment.newInstance(from, "c");
27         fragments[3] = ProfileFragment.newInstance(from, "d");
28         return fragments;
29     }
30 
31     /**
32      * 获取Tab 显示的内容
33      * @param context
34      * @param position
35      * @return
36      */
37     public static View getTabView(Context context, int position){
38         View view = LayoutInflater.from(context).inflate(R.layout.home_tab_content,null);
39         ImageView tabIcon =  view.findViewById(R.id.tab_content_image);
40         tabIcon.setImageResource(DataGenerator.mTabRes[position]);
41         TextView tabText = view.findViewById(R.id.tab_content_text);
42         tabText.setText(mTabTitle[position]);
43         return view;
44     }
45 }

以上是一个工具类将所有的数据全部封装在一块,

我也没搞明白为什么需要传两个参数,应该是可以改的吧,自己没有尝试,随便传一个字符串即可,

主函数中也就是主页面的代码

  1 import android.net.Uri;
  2 import android.support.annotation.Nullable;
  3 import android.support.design.widget.BottomNavigationView;
  4 import android.support.annotation.NonNull;
  5 import android.support.design.widget.TabLayout;
  6 import android.support.v4.app.Fragment;
  7 import android.support.v7.app.AppCompatActivity;
  8 import android.os.Bundle;
  9 import android.view.MenuItem;
 10 import android.view.View;
 11 import android.widget.ImageView;
 12 import android.widget.TextView;
 13 import android.widget.Toast;
 14 
 15 import com.example.tabhostcostom.Utils.DataGenerator;
 16 
 17 public class MainActivity extends AppCompatActivity implements HomeFragment.OnFragmentInteractionListener, DiscoveryFragment.OnFragmentInteractionListener ,
 18         AttentionFragment.OnFragmentInteractionListener, ProfileFragment.OnFragmentInteractionListener
 19 {
 20 
 21     private BottomNavigationView mBottomNavigationView;
 22     //private Fragment []mFragments;
 23     private TabLayout mTabLayout;
 24     private Fragment []mFragmensts;
 25 
 26     @Override
 27     protected void onCreate(@Nullable Bundle savedInstanceState) {
 28         super.onCreate(savedInstanceState);
 29         setContentView(R.layout.activity_main);
 30 
 31         mFragmensts = DataGenerator.getFragments("TabLayout Tab");
 32 
 33         initView();
 34     }
 35 
 36     private void initView() {
 37             mTabLayout = findViewById(R.id.bottom_tab_layout);
 38 
 39             mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
 40                 @Override
 41                 public void onTabSelected(TabLayout.Tab tab) {
 42                     onTabItemSelected(tab.getPosition());
 43                     // Tab 选中之后,改变各个Tab的状态,如果点击下面的导航栏,需要改变颜色的话取消注释,同时取消掉工具类中的注释即可
 44                     /*
 45                     for (int i=0;i<mTabLayout.getTabCount();i++){
 46                         View view = mTabLayout.getTabAt(i).getCustomView();
 47                         ImageView icon = (ImageView) view.findViewById(R.id.tab_content_image);
 48                         TextView text = (TextView) view.findViewById(R.id.tab_content_text);
 49 
 50                         if(i == tab.getPosition()){ // 选中状态
 51                             icon.setImageResource(DataGenerator.mTabResPressed[i]);
 52                             text.setTextColor(getResources().getColor(android.R.color.black));
 53                         }else{// 未选中状态
 54                             icon.setImageResource(DataGenerator.mTabRes[i]);
 55                             text.setTextColor(getResources().getColor(android.R.color.darker_gray));
 56                         }
 57                     }*/
 58 
 59 
 60                 }
 61 
 62                 @Override
 63                 public void onTabUnselected(TabLayout.Tab tab) {
 64 
 65                 }
 66 
 67                 @Override
 68                 public void onTabReselected(TabLayout.Tab tab) {
 69 
 70                 }
 71             });
 72 
 73         for(int i=0;i<5;i++){
 74             mTabLayout.addTab(mTabLayout.newTab().setCustomView(DataGenerator.getTabView(this,i)));
 75         }
 76 
 77         }
 78 
 79     private void onTabItemSelected(int position){
 80         Fragment fragment = null;
 81         switch (position){
 82             case 0:
 83                 fragment = mFragmensts[0];
 84                 break;
 85             case 1:
 86                 fragment = mFragmensts[1];
 87                 break;
 88             case 2:
 89                 fragment = mFragmensts[2];
 90                 break;
 91             case 3:
 92                 fragment = mFragmensts[3];
 93                 break;
 94             case 4:
 95                 fragment = mFragmensts[3];
 96                 break;
 97         }
 98         if(fragment!=null) {
 99             getSupportFragmentManager().beginTransaction().replace(R.id.home_container,fragment).commit();
100         }
101     }
102 
103     @Override
104     public void onFragmentInteraction(Uri uri) {
105         Toast.makeText(this, "hello", Toast.LENGTH_SHORT).show();
106     }
107 }

这是 TabLayout + Fragment 全部代码

下面介绍 BottomNavigationView + Fragment 实现,带有动画效果,点击的那个会自动将其他的挤出去,所以建议使用上面的布局方式,当然,需要动画效果的布局也可以

需要 menu 菜单

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 3     <item
 4         android:id="@+id/tab_menu_home"
 5         android:icon="@mipmap/index_blue_icon"
 6         android:title="首页"
 7         />
 8     <item
 9         android:id="@+id/tab_menu_discovery"
10         android:icon="@mipmap/index_message"
11         android:title="发现"
12         />
13     <item
14         android:id="@+id/tab_menu_attention1"
15         android:icon="@mipmap/index_publish"
16         android:title=""
17         />
18     <item
19         android:id="@+id/tab_menu_profile"
20         android:icon="@mipmap/index_ying"
21         android:title="Ying"
22         />
23     <item
24         android:id="@+id/tab_menu_attention"
25         android:icon="@mipmap/index_me"
26         android:title="我"
27         />
28 
29 </menu>

主函数中代码:

package com.example.tabhostcostom;

import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomNavigationView;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.tabhostcostom.Utils.DataGenerator;

public class MainActivity extends AppCompatActivity implements HomeFragment.OnFragmentInteractionListener, DiscoveryFragment.OnFragmentInteractionListener ,
        AttentionFragment.OnFragmentInteractionListener, ProfileFragment.OnFragmentInteractionListener
{

    private BottomNavigationView mBottomNavigationView;
    private Fragment []mFragments;
    private TabLayout mTabLayout;
    private Fragment []mFragmensts;

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

        mFragments = DataGenerator.getFragments("TabLayout Tab");

        initView();
    }


    private void initView() {
        mBottomNavigationView = findViewById(R.id.bottom_navigation_view);
        //mBottomNavigationView.getMaxItemCount()

        mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                onTabItemSelected(item.getItemId());
                return true;
            }
        });

        // 由于第一次进来没有回调onNavigationItemSelected,因此需要手动调用一下切换状态的方法
        onTabItemSelected(R.id.tab_menu_home);
    }

    private void onTabItemSelected(int id){
        Fragment fragment = null;
        switch (id){
            case R.id.tab_menu_home:
                fragment = mFragments[0];
                break;
            case R.id.tab_menu_discovery:
                fragment = mFragments[1];
                break;

            case R.id.tab_menu_attention:
                fragment = mFragments[2];
                break;
            case R.id.tab_menu_profile:
                fragment = mFragments[3];
                break;
        }
        if(fragment!=null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.home_container,fragment).commit();
        }
    } 

    @Override
    public void onFragmentInteraction(Uri uri) {
        Toast.makeText(this, "hello", Toast.LENGTH_SHORT).show();
    }
}

 大致就这么多,因为是将两个布局杂糅在一块,如果有问题可以在博客后面进行留言,