備注:今天有空研究了一下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