Android两级导航菜单栏的实现--FragmentTabHost+自定义二级导航菜单栏

        前两篇博文分别采用 FragmentTabHost嵌套FragmentTabHostFragmentTabHost+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;
	

	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);

		Bundle bundle = getArguments();
		if (null != bundle) {
			//
		}
	}

	@Override
	public 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);

	}

	@Override
	public 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){
		
		FragmentTransaction	transaction =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 {

	@Override
	public 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

猜你喜欢

转载自blog.csdn.net/yalinfendou/article/details/44727299
今日推荐