用Fragment+FragmentTabHost++ViewPager 實現底部菜單欄

總體思路圖

這裏寫圖片描述

總體設計思路

  • Fragment:存放不同選項的頁面內容
  • FragmentTabHost:點擊切換選項卡
  • ViewPager:實現頁面的左右滑動效果

概念介紹

FragmentTabHost

用於實現點擊選項進行切換選項卡的自定義效果

使用FragmentTabHost,就是先用TabHost“裝着”Fragment,然後放進MainActivity裏面

ViewPager

  • 定義

ViewPager是android擴展包v4包中的類

android.support.v4.view.ViewPager
  • 作用

左右切換當前的view,實現滑動切換的效果

注:

1.ViewPager類直接繼承了ViewGroup類,和LinearLayout等佈局一樣,都是一個容器,需要在裏面添加我們想要顯示的內容。

2.ViewPager類需要PagerAdapter適配器類提供數據,與ListView類似

3.Google官方建議ViewPager配合Fragment使用

Fragment

  • 定義

Fragment是activity的界面中的一部分或一種行爲

1.把Fragment認爲模塊化的一段activity

2.它具有自己的生命週期,接收它自己的事件,並可以在activity運行時被添加或刪除

3.Fragment不能獨立存在,它必須嵌入到activity中,而且Fragment的生命週期直接受所在的activity的影響。例如:當activity暫停時,它擁有的所有的Fragment們都暫停了,當activity銷燬時,它擁有的所有Fragment們都被銷燬。

  • 作用

主要是爲了支持更動態、更靈活的界面設計(從3.0開始引入)

實現步驟

  1. 在主xml佈局裏面定義一個FragmentTabHost控件
  2. 定義底部菜單欄佈局
  3. 定義每個Fragment佈局
  4. 定義每個Fragment的Java類
  5. 定義適配器以關聯頁卡和ViewPage
  6. 定義MainActivity(具體實現請看註釋)

具體實現實例

步驟1:在主xml佈局裏面定義一個FragmentTabHost控件

主xml佈局:Main_tab_layout.xml

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

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" /><!--裝4個Fragment-->

<FrameLayout
    android:visibility="gone"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

<!--定義FragmentTabHost控件-->
<android.support.v4.app.FragmentTabHost
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/black" ><!--裝4個Fragment-->

    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="0" /><!--裝Tab的內容-->
 </android.support.v4.app.FragmentTabHost>
</RelativeLayout>

步驟2:定義底部菜單欄佈局

tab_content.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:gravity="center"   
    android:orientation="vertical"    
    android:background="#ffffff">    
<ImageView        
    android:id="@+id/tab_imageview"        
    android:layout_width="wrap_content"        
    android:layout_height="wrap_content" />    
<TextView        
    android:id="@+id/tab_textview"        
    android:layout_width="wrap_content"        
    android:layout_height="wrap_content"        
    android:text=""        
    android:textColor="@drawable/selector_text_background" />
</LinearLayout>

步驟3:定義Fragment佈局

fragment_item1.xml&fragment_item2.xml

這裏使用兩個選項,由於fragment_item1.xml與fragment_item2.xml相同,這裏只貼出一個

fragment_item1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="fragment1"
    android:textSize="20sp"/>
</LinearLayout>

步驟4: 定義每個Fragment的Java類

1.這裏使用兩個選項:Fragment1.java&fragmen2.java

2.由於Fragment1.java&fragmen2.java相同,這裏只貼出一個

Fragment1.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment

{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_item1, null);
    return view;
     }
}

步驟5: 定義適配器關聯頁卡和ViewPage

MyFragmentAdapter.java

package com.example.carson_ho.tab_menu_demo;

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

import java.util.List;

public class MyFragmentAdapter extends FragmentPagerAdapter{
    List<Fragment> list;
    public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
    super(fm);
    this.list=list;
}//寫構造方法,方便賦值調用
    @Override
    public Fragment getItem(int arg0) {
    return list.get(arg0);
}//根據Item的位置返回對應位置的Fragment,綁定item和Fragment

    @Override
    public int getCount() {
    return list.size();
}//設置Item的數量

}

步驟6: 定義MainActivity

具體實現看註釋
MainActivity.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;

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

public class MainActivity extends FragmentActivity implements
    ViewPager.OnPageChangeListener, TabHost.OnTabChangeListener {

private FragmentTabHost mTabHost;
private LayoutInflater layoutInflater;
private Class fragmentArray[] = { Fragment1.class, Fragment2.class };
private int imageViewArray[] = { R.drawable.tab_home_btn, R.drawable.tab_view_btn };
private String textViewArray[] = { "首頁", "分類"};
private List<Fragment> list = new ArrayList<Fragment>();
private ViewPager vp;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();//初始化控件
    initPage();//初始化頁面
}

//    控件初始化控件
private void initView() {
    vp = (ViewPager) findViewById(R.id.pager);

    /*實現OnPageChangeListener接口,目的是監聽Tab選項卡的變化,然後通知ViewPager適配器切換界面*/
    /*簡單來說,是爲了讓ViewPager滑動的時候能夠帶着底部菜單聯動*/

    vp.addOnPageChangeListener(this);//設置頁面切換時的監聽器
    layoutInflater = LayoutInflater.from(this);//加載佈局管理器

    /*實例化FragmentTabHost對象並進行綁定*/
    mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);//綁定tahost
    mTabHost.setup(this, getSupportFragmentManager(), R.id.pager);//綁定viewpager

    /*實現setOnTabChangedListener接口,目的是爲監聽界面切換),然後實現TabHost裏面圖片文字的選中狀態切換*/
    /*簡單來說,是爲了當點擊下面菜單時,上面的ViewPager能滑動到對應的Fragment*/
    mTabHost.setOnTabChangedListener(this);

    int count = textViewArray.length;

    /*新建Tabspec選項卡並設置Tab菜單欄的內容和綁定對應的Fragment*/
    for (int i = 0; i < count; i++) {
        // 給每個Tab按鈕設置標籤、圖標和文字
        TabHost.TabSpec tabSpec = mTabHost.newTabSpec(textViewArray[i])
                .setIndicator(getTabItemView(i));
        // 將Tab按鈕添加進Tab選項卡中,並綁定Fragment
        mTabHost.addTab(tabSpec, fragmentArray[i], null);
        mTabHost.setTag(i);
        mTabHost.getTabWidget().getChildAt(i)
                .setBackgroundResource(R.drawable.selector_tab_background);//設置Tab被選中的時候顏色改變
    }
}

/*初始化Fragment*/
private void initPage() {
    Fragment1 fragment1 = new Fragment1();
    Fragment2 fragment2 = new Fragment2();

    list.add(fragment1);
    list.add(fragment2);

    //綁定Fragment適配器
    vp.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(), list));
    mTabHost.getTabWidget().setDividerDrawable(null);
}

private View getTabItemView(int i) {
    //將xml佈局轉換爲view對象
    View view = layoutInflater.inflate(R.layout.tab_content, null);
    //利用view對象,找到佈局中的組件,並設置內容,然後返回視圖
    ImageView mImageView = (ImageView) view
            .findViewById(R.id.tab_imageview);
    TextView mTextView = (TextView) view.findViewById(R.id.tab_textview);
    mImageView.setBackgroundResource(imageViewArray[i]);
    mTextView.setText(textViewArray[i]);
    return view;
}

@Override
public void onPageScrollStateChanged(int arg0) {

}//arg0 ==1的時候表示正在滑動,arg0==2的時候表示滑動完畢了,arg0==0的時候表示什麼都沒做,就是停在那。

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {

}//表示在前一個頁面滑動到後一個頁面的時候,在前一個頁面滑動前調用的方法

@Override
public void onPageSelected(int arg0) {//arg0是表示你當前選中的頁面位置Postion,這事件是在你頁面跳轉完畢的時候調用的。
    TabWidget widget = mTabHost.getTabWidget();
    int oldFocusability = widget.getDescendantFocusability();
    widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);//設置View覆蓋子類控件而直接獲得焦點
    mTabHost.setCurrentTab(arg0);//根據位置Postion設置當前的Tab
    widget.setDescendantFocusability(oldFocusability);//設置取消分割線
}

@Override
public void onTabChanged(String tabId) {//Tab改變的時候調用
    int position = mTabHost.getCurrentTab();
    vp.setCurrentItem(position);//把選中的Tab的位置賦給適配器,讓它控制頁面切換
     }
}

效果圖:

這裏寫圖片描述

源碼:https://github.com/luojunquan/DiLan.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章