android--解决方案--自定义tabhost(动态添加选项+带自动水平滑动选项卡+手势切换选项卡及内容功能)

本文主要解决自定义tabhost的实现,以及集成通过代码动态添加选项卡功能、选项卡水平自动滑动功能、以及通过手势来切换选项卡功能。

下面跟我一起来完成这个完美的解决方案:

1、定义tabwidget选项卡的布局:tab_button.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="119dip"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_tabs_tabHost"
        android:layout_width="119dip"
        android:layout_height="39dip"
        android:gravity="center"
        android:text="tab1" />

</LinearLayout>

2、主页面tab控件的布局文件:activity_tabhost.xml

        <TabHost
            android:id="@+id/tabhost"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <!-- 水平滚动 -->

                <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" >

                    <HorizontalScrollView
                        android:id="@+id/hScroller_mytabhostactivity"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:fadingEdge="none"
                        android:saveEnabled="false"
                        android:scrollbars="none" >

                        <TabWidget
                            android:id="@android:id/tabs"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content" />
                    </HorizontalScrollView>
                </RelativeLayout>

                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="match_parent"
                    android:layout_height="0dip"
                    android:layout_weight="1" />
            </LinearLayout>
        </TabHost>

3、主页面MyTabHostActivity.java

首先定义如下变量:

	// tabhost
	private static TabHost tbProductHost;
	// 滑动手势
	private GestureDetector detector;
	// tab widget水平滑动条
	private HorizontalScrollView hScroller;
	private int screenWidth;// 屏幕宽度 单位:dp

其中oncreate方法:

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_tabhost);
		// 初始化tabhost
		tbProductHost = (TabHost) findViewById(R.id.tabhost);
		tbProductHost.setup(CaptureMultiActivity.this.getLocalActivityManager());
		// 获取手机屏幕的宽高
		DisplayMetrics displayMetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
		screenWidth = Methods.px2dip(CaptureMultiActivity.this,
				displayMetrics.widthPixels);// dp
		// 初始化TabHost,根据arr
		for (int i=0;i<10;i++) {
			View view = LayoutInflater.from(MyTabHostActivity.this).inflate(
					R.layout.tab_button, null);
			TextView tView = (TextView) view.findViewById(R.id.tv_tabs_tabHost);
			tView.setText("tab"+i);
			tbProductHost.addTab("tab"+i)
					.setIndicator(view).setContent(MyTabHostActivity.this);
			updateTab(tbProductHost);//调用方法设置tabWidget选项卡的颜色
			tbProductHost.setOnTabChangedListener(new OnTabChangedListener());
		}
		hScroller = (HorizontalScrollView) findViewById(R.id.hScroller_scan);

	}


其中Methods类中的px2dip(int tt)方法为:

	/**
	 * px 转 dip
	 * 
	 * @param context
	 * @param pxValue
	 * @return
	 */
	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}


其中updateTab(Tabhost tb)方法主要用于设置tabwidget选项卡的颜色,以及选中时的颜色如下:

	/**
	 * 更新Tab标签的颜色,和字体的颜色
	 * 
	 * @param tabHost
	 */
	private void updateTab(final TabHost tabHost) {
		for (int i = 0; i < tabHost.getTabWidget().getChildCount(); i++) {
			View view = tabHost.getTabWidget().getChildAt(i);
			TextView tv = (TextView) tabHost.getTabWidget().getChildAt(i)
					.findViewById(R.id.tv_tabs_tabHost);
			tv.setTextSize(16);
			tv.setTypeface(Typeface.SERIF, 2); // 设置字体和风格
			if (tabHost.getCurrentTab() == i) {// 选中
				view.setBackgroundColor(getResources().getColor(
						R.color.color_text_red));// 选中后的背景 #eb037f
				tv.setTextColor(this.getResources().getColorStateList(
						android.R.color.black));
			} else {// 不选中
				view.setBackgroundColor(getResources().getColor(
						R.color.color_text_yellow));// 非选择的背景 #f8c514
				tv.setTextColor(this.getResources().getColorStateList(
						android.R.color.white));
			}
		}
	}
其中OnTabChangedListener类:

	class OnTabChangedListener implements OnTabChangeListener {
		@Override
		public void onTabChanged(String tabId) {
			tbProductHost.setCurrentTabByTag(tabId);
			System.out.println("tabid " + tabId);
			System.out.println("curreny after: "
					+ tbProductHost.getCurrentTabTag());
			updateTab(tbProductHost);
		}
	}

另外MyTabHostActivity类要实现TabContentFactory, OnGestureListener共计两个接口,并实现里面的方法:

	@Override
	public View createTabContent(String arg0) {
		// 初始化tabHost里面某一个选项卡的内容,可以通过Inflater来加载已经定义好的xml布局文件
                //to-do
		return view;
	}


	public void flingLeft() {
		// 切换选项卡
		int currentTab = tbProductHost.getCurrentTab();
		if (currentTab != 0) {
			currentTab--;
			switchTab(currentTab);
		}
		// 水平滑动
		hScrollManagment(true, currentTab);
	}

	public void flingRight() {
		// 切换选项卡
		int currentTab = tbProductHost.getCurrentTab();
		if (currentTab != tbProductHost.getTabWidget().getChildCount()) {
			currentTab++;
			switchTab(currentTab);
		}
		// 水平滑动
		hScrollManagment(false, currentTab);
	}
        //用于在切换选项卡时自动居中所选中的选项卡的位置
	private void hScrollManagment(boolean isToLeft, int currentTab) {
		int count = tbProductHost.getTabWidget().getChildCount();
		System.out.println("000111:hScrollManagment count=" + count);
		if (179 * count > screenWidth) {
			int nextPosX = (int) (currentTab + 0.5) * 179 - screenWidth / 2;//此处的179可以自行修改
			// hScroller.scrollTo(nextPosX, 0);
			hScroller.smoothScrollTo(nextPosX, 0);
		}
	}

	private static void switchTab(final int toTab) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				tbProductHost.post(new Runnable() {
					@Override
					public void run() {
						tbProductHost.setCurrentTab(toTab);
					}
				});
			}
		}).start();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return this.detector.onTouchEvent(event);
	}

	@Override
	public boolean onDown(MotionEvent arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		if (e1.getX() - e2.getX() < -120) {
			flingLeft();
			return true;
		} else if (e1.getX() - e2.getX() > 120) {
			flingRight();
			return true;
		}

		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

至此,一个完美的tabhost自定义解决方案完成。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。