天天看點

FragmentTabHost實作底部菜單欄效果~~

備注:今天有空研究了一下fragmentTabHost實作底部菜單欄效果,點選和滑動的效果均已經實作,demo中注釋掉的是僅僅點選情況下的效果,如果你點選和滑動兩種情況都需要,那麼請源碼照搬,如果僅僅需要點選切換頁面,那麼可以把文中注釋掉的demo釋放,再将相關的viewPager方法注釋掉就行。本文中實作的是類似于微信那樣既可以點選,也可以滑動~~~

1.布局

  1.1底部菜單每一個Tab的布局:tab_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:paddingTop="4dp"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/image"
        android:src="@drawable/tab_conversations"//是一個布局選擇器,點選時展示自己需要的圖檔或背景
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/title"
        android:text="首頁"
        android:gravity="center"
        android:textSize="14sp"
        android:textColor="@drawable/tab_title_color"//也是一個布局選擇器
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
           

1.2 簡單寫一個背景選擇器selector(其他類似):tab_conversations.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@drawable/ic_chat_01"></item>
    <item android:drawable="@drawable/ic_chat_02"></item>
</selector>
           

  1.3 activity的布局:activity_main.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" >

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
    <FrameLayout
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
    <!--<FrameLayout-->
        <!--android:id="@+id/container_fragment"-->
        <!--android:layout_width="fill_parent"-->
        <!--android:layout_height="0dip"-->
        <!--android:layout_weight="1" />-->
    <!--<!–分割線–>-->
    <!--<View-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="1px"-->
        <!--android:background="#dcdcdc"-->
        <!--/>-->
    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black" >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />
    </android.support.v4.app.FragmentTabHost>
</LinearLayout>
           

2.擴充卡:FragmentTabAdapter.java:

public class FragmentTabAdapter extends FragmentPagerAdapter {
    private List<Fragment> mFragmentList;

    public FragmentTabAdapter(FragmentManager fm) {
        super(fm);
    }

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

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

    public void setData(List<Fragment> mFragmentList){
        this.mFragmentList = mFragmentList;
        notifyDataSetChanged();
    }
}
           

3.MainActivity的寫法:(再次強調:本文是實作了點選切換和滑動切換!!!僅僅實作點選切換的同鞋,釋放文中注釋掉的demo,并且注釋viewPager相關的demo)

public class MainActivity extends AppCompatActivity {

    private FragmentTabHost mTabHost;
    private ViewPager mViewPager;
    private List<Fragment> mFragmentList;
    private FragmentTabAdapter mAdapter;
    private int currentPosition;
    private FragmentManager fragmentManager;
    private Class mClass[] = {ConversationFragment.class, ContactsFragment.class, SettingFragment.class};
    private Fragment mFragment[] = {new ConversationFragment(),new ContactsFragment(),new SettingFragment()};
    private String mTitles[] = {"會話", "聯系人", "設定"};
    private int mImages[] = {
            R.drawable.tab_conversations,
            R.drawable.tab_contacts,
            R.drawable.tab_setting,
    };

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

        initView();
        setDataToUI();
        initEventListener();

    }

    private void initEventListener() {
        mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
            @Override
            public void onTabChanged(String tabId) {
                mViewPager.setCurrentItem(mTabHost.getCurrentTab());
            }
        });
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                TabWidget widget = mTabHost.getTabWidget();
                int oldFocusability = widget.getDescendantFocusability();
                widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
                mTabHost.setCurrentTab(position);
                widget.setDescendantFocusability(oldFocusability);
                mTabHost.getTabWidget().getChildAt(position)
                        .setBackgroundColor(Color.GRAY);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }
           
private void setDataToUI() {
        mTabHost.setup(this,getSupportFragmentManager(),R.id.view_pager);
//        mTabHost.setup(this,getSupportFragmentManager(),R.id.container_fragment);
        mTabHost.getTabWidget().setDividerDrawable(null);
        for (int i = 0;i < mClass.length;i++){
            TabHost.TabSpec tabSpec = mTabHost.newTabSpec(mTitles[i]).setIndicator(getTabView(i));
            mTabHost.addTab(tabSpec,mClass[i],null);
            mTabHost.setTag(i);
            Log.d("wang","mClass==========="+ mClass[i].toString());
            mFragmentList.add(mFragment[i]);
            Log.d("wang","mFragmentList[i]==========="+ mFragment[i].toString());
            mTabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.GRAY);
        }
        Log.d("wang","mFragmentLists==========="+ mFragmentList.size());

        mAdapter.setData(mFragmentList);
        mViewPager.setAdapter(mAdapter);
    }

    private View getTabView(int i) {
        View view = LayoutInflater.from(this).inflate(R.layout.tab_item,null);
        ImageView image = (ImageView) view.findViewById(R.id.image);
        TextView title = (TextView) view.findViewById(R.id.title);

        image.setImageResource(mImages[i]);
        title.setText(mTitles[i]);
        return view;
    }

    private void initView() {
        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mViewPager = (ViewPager) findViewById(R.id.view_pager);

        mFragmentList = new ArrayList<Fragment>();
        mAdapter = new FragmentTabAdapter(getSupportFragmentManager());
        fragmentManager = getSupportFragmentManager();
    }

    // 選擇Fragment
   /* private void switchFragment(int target) {
        if (target != currentPosition) {
            Fragment targetFragment = mFragmentList.get(target);// 目标Fragment
            Fragment currentFragment = mFragmentList.get(currentPosition);// 目前Fragment
            if (!targetFragment.isAdded())
                fragmentManager.beginTransaction().add(android.R.id.tabcontent, targetFragment).hide(currentFragment).commit();
            else
                fragmentManager.beginTransaction().show(targetFragment).hide(currentFragment).commit();
            // 記錄目前fragment位置
            currentPosition = target;
        }
    }*/
           
4.最後再簡單貼一個fragment:其餘fragment都一樣      
public class ConversationFragment extends Fragment {
    private View view;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //fangzhi每次FragmentTabHost切換fragment時會重新調用onCreateView()重新繪制UI。假如我們在onCreateView()中有網絡操作,在切換的時候也會重複進行,這樣當然不是我們希望的
        if (view == null){
            view = inflater.inflate(R.layout.conversation_main,container,false);
        }
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null){
            parent.removeView(view);
        }
        return view;
    }
}
           

5.最後看一下效果圖:

源碼下載下傳

總結:這是自己為了練手和學習,自己親自嘗試勒一下,比較麻煩,如果需要快速開發的同學,想立馬內建該架構,給大家推薦一個github上面的架構,個人感覺非常好用和簡便,隻需要往進填充資料即可,位址: https://github.com/chenpengfei88/TabContainerView