Android两级导航菜单栏的实现--FragmentTabHost+自定义二级导航菜单栏
来源:互联网 发布:西安高新区软件新城 编辑:程序博客网 时间:2024/05/21 22:24
前两篇博文分别采用 FragmentTabHost嵌套FragmentTabHost和FragmentTabHost+PagerSlidingTabStrip 与ViewPager的方式实现了子Tab导航菜单栏的效果,虽是好用,但有时候却不灵活。
本篇中将要实现自定义Tab导航菜单栏效果。
如果你对FragmentTabHost和Fragment还不熟悉,一定要先看前面的博文。
仍然先看看效果图
重写fragment_message1.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:background="#F5F7FA" android:orientation="vertical" > <include layout="@layout/top_sub_tab" /> <FrameLayout android:id="@+id/id_content" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" > </FrameLayout></LinearLayout>
顶部的Tab导航为自定义top_sub_tab.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="40dp" android:background="#eee" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="37dp" android:orientation="horizontal" > <LinearLayout android:id="@+id/lin_sub1" android:layout_width="3dp" android:orientation="horizontal" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="新闻" android:textColor="#008000" /> </LinearLayout> <LinearLayout android:id="@+id/lin_sub2" android:layout_width="3dp" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:text="财经" /> </LinearLayout> <LinearLayout android:id="@+id/lin_sub3" android:layout_width="3dp" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:text="旅游" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/imv_tabline" android:layout_width="100dp" android:layout_height="3dp" android:background="#FF8D42" /></LinearLayout>
重写 FragmentMessage
public class FragmentMessage extends Fragment implements OnClickListener {private static String TAG = FragmentMessage.class.getName();private LinearLayout lin_sub1, lin_sub2, lin_sub3;private Fragment subFragment1;private Fragment subFragment2;private Fragment subFragment3;private ImageView mTabline;private int mScreen1_3;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Bundle bundle = getArguments();if (null != bundle) {//}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {T.showShort(getActivity(), "FragmentMessage==onCreateView");View view = inflater.inflate(R.layout.fragment_message1, null);initView(view);setLinstener();initData();return view;}private void initView(View view) {lin_sub1 = (LinearLayout) view.findViewById(R.id.lin_sub1);lin_sub2 = (LinearLayout) view.findViewById(R.id.lin_sub2);lin_sub3 = (LinearLayout) view.findViewById(R.id.lin_sub3);mTabline = (ImageView) view.findViewById(R.id.imv_tabline);}protected void initData() {// Display display = getWindow().getWindowManager().getDefaultDisplay();Display display = getActivity().getWindowManager().getDefaultDisplay();DisplayMetrics outMetrics = new DisplayMetrics();display.getMetrics(outMetrics);mScreen1_3 = outMetrics.widthPixels / 3;LayoutParams lp = (LayoutParams) mTabline.getLayoutParams();lp.width = mScreen1_3;mTabline.setLayoutParams(lp);//初次显示设置setSubFragment(0);setmTabline(0);}protected void setLinstener() {lin_sub1.setOnClickListener(this);lin_sub2.setOnClickListener(this);lin_sub3.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.lin_sub1:setSubFragment(0);setmTabline(0);break;case R.id.lin_sub2:setSubFragment(1);setmTabline(1);break;case R.id.lin_sub3:setSubFragment(2);setmTabline(2);break;default:break;}}public void setmTabline(int i) {LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) mTabline.getLayoutParams();lp.leftMargin = i * mScreen1_3;mTabline.setLayoutParams(lp);}public void setSubFragment(int i){FragmentTransactiontransaction =getFragmentManager().beginTransaction();if(0 == i ){subFragment1 = (subFragment1 == null ? new SubFragment1():subFragment1);transaction.replace(R.id.id_content,subFragment1);//transaction.addToBackStack(null);transaction.commit();}else if(1 == i ){subFragment2 = (subFragment2 == null ? new SubFragment2():subFragment2);transaction.replace(R.id.id_content,subFragment2);//transaction.addToBackStack(null);transaction.commit();}else if(2 == i ){subFragment3 = (subFragment3 == null ? new SubFragment3():subFragment3);transaction.replace(R.id.id_content,subFragment3);//transaction.addToBackStack(null);transaction.commit();}}}
再添加 SubFragment1(这里只给出一个,其它类似)
public class SubFragment1 extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {T.showShort(getActivity(), "SubFragment1==onCreateView");TextView tv = new TextView(getActivity());tv.setTextSize(25);tv.setBackgroundColor(Color.parseColor("#FFA07A"));tv.setText("新闻");tv.setGravity(Gravity.CENTER);return tv;}}
好了,代码就这么简单……你会发现每次切换二级Tab导航菜单栏的时候,子Fragment会重新绘制,只需再稍微改造一下就OK了
/* * 显示subFragment,subFragment不会重复onCreateView */public void showSubFragment(int i) {FragmentTransaction transaction = getFragmentManager().beginTransaction();hideSubFragment(transaction);if (0 == i) {subFragment1 = (subFragment1 == null ? new SubFragment1(): subFragment1);if(!subFragment1.isAdded()){transaction.add(R.id.id_content, subFragment1);}// transaction.addToBackStack(null);transaction.show(subFragment1);transaction.commit();} else if (1 == i) {subFragment2 = (subFragment2 == null ? new SubFragment2(): subFragment2);if(!subFragment2.isAdded()){transaction.add(R.id.id_content, subFragment2);}// transaction.addToBackStack(null);transaction.show(subFragment2);transaction.commit();} else if (2 == i) {subFragment3 = (subFragment3 == null ? new SubFragment3(): subFragment3);if(!subFragment3.isAdded()){transaction.add(R.id.id_content, subFragment3);}// transaction.addToBackStack(null);transaction.show(subFragment3);transaction.commit();}}public void hideSubFragment(FragmentTransaction transaction) {if (subFragment1 != null) {transaction.hide(subFragment1);}if (subFragment2 != null) {transaction.hide(subFragment2);}if (subFragment3 != null) {transaction.hide(subFragment3);}}
几点注意的地方:
1 在transaction.add()方法时候,先判断subFragment1.isAdded(),避免该异常:java.lang.IllegalStateException: Fragment already added:2 FragmentTransaction事务 只能执行一次commit()操作,所以定义成局部变量。
3 transaction.replace()时有一个移除操作和一个添加操作,即先remove()再add(),remove()的时候Fragment实例已经被销毁,所以在方式一种每次切换子Tab导航菜单栏,subFragment都会执行OncreateView();
4 hide()和show()方法,看字面意义就理解了。hide()只是隐藏,不会销毁,而show()就是把隐藏的显示出来。
关于Android Tab导航菜单栏--FragmentTabHost+Fragment的博客就到这里了。小生不权威,肯定有很多疏漏和出错的地方,想好好玩Android,看谷歌官方文档和Android源码才是王道。
小生这里只是写的一些超级基础的Demo,仅仅是提供思路,在实际项目开发中的情况复杂的多。
但愿小生所做的事对别人有所帮助,就算莫大的荣幸了。
Demo下载地址(子Fragment会重复onCreateView):http://download.csdn.net/detail/yalinfendou/8543999
Demo下载地址(子Fragment不会重复onCreateView):http://download.csdn.net/detail/yalinfendou/8544017
3 0
- Android两级导航菜单栏的实现--FragmentTabHost+自定义二级导航菜单栏
- Android两级导航菜单栏的实现--FragmentTabHost嵌套FragmentTabHost
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
- Android Tab导航菜单栏--FragmentTabHost+Fragment实现(基础篇)
- Android Tab导航菜单栏--FragmentTabHost+Fragment实现(转载)
- 二级导航菜单栏
- 二级导航菜单栏
- 纯CSS制作的二级导航菜单栏(通过变化菜单栏的样式实现)
- Android左边菜单栏导航
- 首页-底部Tab导航(菜单栏)的实现:FragmentTabHost+ViewPager+Fragment
- 首页-底部Tab导航(菜单栏)的实现:FragmentTabHost+ViewPager+Fragment
- 导航菜单栏
- 如何实现导航菜单栏中的二级下拉菜单?
- 如何实现导航菜单栏中的二级下拉菜单?
- 如何实现导航菜单栏中的二级下拉菜单?
- 利用JQuery实现简单的菜单栏导航
- reactNative底部导航菜单栏实现
- 排序算法之插入算法
- 如何从R中获得免费的小型数据集
- 第三周项目3 - 程序的多文件组织
- Java循环结构与判断结构
- Twisted学习记录
- Android两级导航菜单栏的实现--FragmentTabHost+自定义二级导航菜单栏
- 移动端开发工具整理
- C#从字符串获取文件路径
- 认真画线2
- USB大容量存储设备Bulk Only传输过程
- Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置
- Java 多线程同步--synchronized
- FragmentPagerAdapter与FragmentStatePagerAdapter区别
- HDU2063 过山车(二分图匹配-匈牙利算法模版题)