前言
Android开发中使用底部菜单栏的频次非常高,主要的实现手段有以下:
- TabWidget
- 隐藏TabWidget,使用RadioGroup和RadioButton
- FragmentTabHost
- 5.0以后的TabLayout
- 最近推出的 Bottom navigation
在这我选择的是FragmentTabHost+ViewPager
总体设计思路
- FragmentTabHost:点击切换选项卡
- ViewPager:实现页面的左右滑动效果
1、效果
2、工程文件目录
3、具体实现
MyFragmentTabHost.java
package net.lvtushiguang.nailing.widget;
import android.content.Context;
import android.support.v4.app.FragmentTabHost;
import android.util.AttributeSet;
public class MyFragmentTabHost extends FragmentTabHost {
private String mCurrentTag;
private String mNoTabChangedTag;
public MyFragmentTabHost(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onTabChanged(String tag) {
if (tag.equals(mNoTabChangedTag)) {
setCurrentTabByTag(mCurrentTag);
} else {
super.onTabChanged(tag);
mCurrentTag = tag;
}
}
public void setNoTabChangedTag(String tag) {
this.mNoTabChangedTag = tag;
}
}
MainTab.java
package net.lvtushiguang.nailing.ui;
import net.lvtushiguang.nailing.R;
import net.lvtushiguang.nailing.fragment.ContactFragment;
import net.lvtushiguang.nailing.fragment.DingFragment;
import net.lvtushiguang.nailing.fragment.MessageFragment;
import net.lvtushiguang.nailing.fragment.MineFragment;
import net.lvtushiguang.nailing.fragment.WorkFragment;
/**
* Created by 薰衣草 on 2016/12/8.
*/
public enum MainTab {
MESSAGE(0, R.string.main_tab_name_message, R.drawable.tab_icon_message,
MessageFragment.class),
DING(1, R.string.main_tab_name_ding, R.drawable.tab_icon_ding,
DingFragment.class),
WORK(2, R.string.main_tab_name_work, R.drawable.tab_icon_work,
WorkFragment.class),
CONTACT(3, R.string.main_tab_name_contact, R.drawable.tab_icon_contact,
ContactFragment.class),
MINE(4, R.string.main_tab_name_mine, R.drawable.tab_icon_mine,
MineFragment.class);
private int idx;
private int resName;
private int resIcon;
private Class<?> clz;
private MainTab(int idx, int resName, int resIcon, Class<?> clz) {
this.idx = idx;
this.resName = resName;
this.resIcon = resIcon;
this.clz = clz;
}
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public int getResName() {
return resName;
}
public void setResName(int resName) {
this.resName = resName;
}
public int getResIcon() {
return resIcon;
}
public void setResIcon(int resIcon) {
this.resIcon = resIcon;
}
public Class<?> getClz() {
return clz;
}
public void setClz(Class<?> clz) {
this.clz = clz;
}
}
tab_indicator.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:drawableTop="@drawable/tab_icon_message"
android:gravity="center"
android:text="资讯"
android:textColor="@color/primarybar_txt"
android:textSize="12sp"/>
<TextView
android:id="@+id/tab_mes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignRight="@id/tab_title"
android:layout_alignTop="@id/tab_title"
android:layout_marginLeft="1dip"/>
</RelativeLayout>
ViewPagerAdapter.java
package net.lvtushiguang.nailing.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.List;
/**
* Created by 薰衣草 on 2016/12/8.
*/
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
List<Fragment> list;
public ViewPagerAdapter(FragmentManager fm,List<Fragment> list) {
super(fm);
this.list=list;
}
@Override
public Fragment getItem(int position) {
return list.get(position);
}
@Override
public int getCount() {
return list.size();
}
}
fragment_layout.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="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Hello World"/>
</RelativeLayout>
MessageFragment.java(其他4个页面类同)
package net.lvtushiguang.nailing.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import net.lvtushiguang.nailing.R;
/**
* Created by 薰衣草 on 2016/12/8.
*/
public class MessageFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null);
TextView content = (TextView) view.findViewById(R.id.text);
content.setText(R.string.main_tab_name_message);
return view;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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=".ui.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/windows_bg">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip">
<net.lvtushiguang.nailing.widget.MyFragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:background="@color/day_colorPrimary"/>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?attr/lineColor"/>
</RelativeLayout>
</FrameLayout>
</LinearLayout>
MainActivity.java
package net.lvtushiguang.nailing.ui;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
import net.lvtushiguang.nailing.R;
import net.lvtushiguang.nailing.adapter.ViewPagerAdapter;
import net.lvtushiguang.nailing.interf.BaseViewInterface;
import net.lvtushiguang.nailing.widget.BadgeView;
import net.lvtushiguang.nailing.widget.MyFragmentTabHost;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class MainActivity extends AppCompatActivity implements BaseViewInterface,
View.OnTouchListener, TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
@BindView(R.id.pager)
public ViewPager mPager;
@BindView(android.R.id.tabhost)
public MyFragmentTabHost mTabHost;
private Unbinder unbinder;
/**
* Used to store the last screen title. For use in
* {@link #restoreActionBar()}.
*/
private CharSequence mTitle;
private BadgeView mBvNotice;
private List<Fragment> list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
unbinder = ButterKnife.bind(this);
initView();
}
@Override
public void initView() {
mTabHost.setup(this, getSupportFragmentManager(), R.id.pager);
mTabHost.getTabWidget().setDividerDrawable(null);
mTabHost.setOnTabChangedListener(this);
// if (Build.VERSION.SDK_INT > 10) {
// mTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
// }
initTabs();
mPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(), list));
mPager.addOnPageChangeListener(this);
}
private void initTabs() {
MainTab[] tabs = MainTab.values();
final int size = tabs.length;
for (int i = 0; i < size; i++) {
MainTab mainTab = tabs[i];
TabHost.TabSpec tab = mTabHost.newTabSpec(getString(mainTab.getResName()));
View indicator = LayoutInflater.from(getApplicationContext())
.inflate(R.layout.tab_indicator, null);
TextView title = (TextView) indicator.findViewById(R.id.tab_title);
Drawable drawable = this.getResources().getDrawable(mainTab.getResIcon());
title.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
title.setText(getString(mainTab.getResName()));
tab.setIndicator(indicator);
mTabHost.addTab(tab, mainTab.getClz(), null);
// mTabHost.setTag(i);
Fragment fragment = null;
try {
fragment = (Fragment) mainTab.getClz().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
list.add(fragment);
View cn = indicator.findViewById(R.id.tab_mes);
mBvNotice = new BadgeView(MainActivity.this, cn);
mBvNotice.setBadgePosition(BadgeView.POSITION_TOP_RIGHT);
mBvNotice.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
mBvNotice.setBackgroundResource(R.drawable.notification_bg);
mBvNotice.setGravity(Gravity.CENTER);
//触发刷新
mTabHost.getTabWidget().getChildAt(i).setOnTouchListener(this);
}
}
@Override
public void initData() {
}
public void restoreActionBar() {
}
@Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mPager.setCurrentItem(position, false);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
@Override
protected void onDestroy() {
super.onDestroy();
unbinder.unbind();
}
@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);//设置View覆盖子类控件而直接获得焦点
mTabHost.setCurrentTab(position);//根据位置Postion设置当前的Tab
widget.setDescendantFocusability(oldFocusability);//设置取消分割线
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
项目下载地址:http://download.csdn.net/detail/ghsfggdsfgdsf/9706445