TabHost、页签

1》. TabHost 
    
绿色整体是TabHost,橙色是页签,下面是内容部分,其实是个Activity,布局一般用FrameLayout.
<TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
        <!---加入LinearLayout 让 TabWidget在上,FrameLayout在下->
      <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >
            <!--- 页签-->
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:visibility="gone" >
            </TabWidget>
  	<FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" >
            </FrameLayout>
        </LinearLayout>
</TabHost>
小知识:Android:Layout_weight的深刻理解

在java中设置好Tabhost:
① 在create ()中调用  initTabHost(),
private void initTabHost() {
	mTabHost = (TabHost) findViewById(android.R.id.tabhost);
	addTabSpec("conversation", "会话", R.drawable.tab_conversation, new Intent(this, ConversationUI.class));
	addTabSpec("folder", "文件夹", R.drawable.tab_folder, new Intent(this, FolderUI.class));
	addTabSpec("group", "群组", R.drawable.tab_group, new Intent(this, GroupUI.class));
}
/**
 * 添加一个页签
 * @param tag 标记
 * @param label 标题
 * @param icon 图标
 * @param intent 指向的activity
 */
private void addTabSpec(String tag, String label, int icon, Intent intent) {
	TabSpec newTabSpec = mTabHost.newTabSpec(tag);
	// 设置页签的标题和图标
	newTabSpec.setIndicator(label, getResources().getDrawable(icon));
	// 设置页签指向的显示内容问activity
	newTabSpec.setContent(intent);
	
	// 添加页签
	mTabHost.addTab(newTabSpec);
}
  它自带的页签不好看,把它的TabWidget Gone掉,然后在下面写上我们自己布局的页签。因为要分成3等分,用一个LinearLayout包裹起来,<LinearLayout> 3个都是相同的布局:
  <LinearLayout   android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:orientation="horizontal" >
          <RelativeLayout
              android:id="@+id/rl_conversation"
              android:layout_width="0dip"
              android:layout_height="wrap_content"
              android:layout_weight="1" >
              <LinearLayout
                  android:id="@+id/ll_conversation"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_centerInParent="true"
                  android:gravity="center_horizontal"
                  android:orientation="vertical"
                  android:paddingBottom="5dip"
                  android:paddingLeft="15dip"
                  android:paddingRight="15dip"
                  android:paddingTop="5dip" >
                  <ImageView
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:src="@drawable/tab_conversation" />
                  <TextView
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_marginTop="5dip"
                      android:text="会话"
                      android:textColor="@android:color/white" />
              </LinearLayout>
      </RelativeLayout>
   	.......
</LinearLayout>
为了增强效果,我们在给页签添加了一个整体背景,而且单个页签添加一个滑动背景,布局中把整个页签包裹下来。
 <RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/darker_gray"
    android:paddingBottom="5dip"
    android:paddingTop="5dip" >
    <View
        android:id="@+id/slide_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/slide_background" />
 	..........
</RelativeLayout>

  下面要获取移动背景的宽和高 ,让它正好包裹住页签中的元素。

   

private View mSlideView;	// 页签的滑动背景
final View llConversation = findViewById(R.id.ll_conversation);
// 初始化滑动背景的宽和高	
// 获得视图树的观察者对象, 添加一个当全部布局(layout)完成时的监听事件
llConversation.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {	
	/*** 全局布局完成时回调.	 */
	@Override
	public void onGlobalLayout() {
		// 移除全局布局的监听事件
		llConversation.getViewTreeObserver().removeGlobalOnLayoutListener(this);		
		// 得到会话布局的参数, 设置给滑动块
		LayoutParams lp = (LayoutParams) mSlideView.getLayoutParams();
		lp.width = llConversation.getWidth();
		lp.height = llConversation.getHeight();
		lp.leftMargin = llConversation.getLeft();
		mSlideView.setLayoutParams(lp);		
	}
});
其中 要移除他的监听事件,因为在 onGlobalLayout 设置布局,会调用 measure ---> layout  -->draw. 又会触发OnGlobalLayoutListener事件,这样就形成了死循环,所以要移除它。
2》. 实现背景的滑动
private int basicWidth = 0;	// 一等分的宽度
private int startX = 0;		// 记住上一次移动完成之后的x轴的偏移量

basicWidth = findViewById(R.id.rl_conversation).getWidth();
@Override
public void onClick(View view) {
	switch (view.getId()) {
	case R.id.ll_conversation: // 切换到会话页签
		if(!"conversation".equals(mTabHost.getCurrentTabTag())) {
			mTabHost.setCurrentTabByTag("conversation");
			startTranslateAnimation(startX, 0);
			startX = 0;
		}
		break;
	case R.id.ll_folder: // 切换到文件夹页签
		if(!"folder".equals(mTabHost.getCurrentTabTag())) {
			mTabHost.setCurrentTabByTag("folder");
			startTranslateAnimation(startX, basicWidth);
			startX = basicWidth;
		}
		break;
	case R.id.ll_group: // 切换到群组页签
		if(!"group".equals(mTabHost.getCurrentTabTag())) {
			mTabHost.setCurrentTabByTag("group");
			startTranslateAnimation(startX, basicWidth * 2);
			startX = basicWidth * 2;
		}
		break;
	default:
		break;
	}
}
/**
 * 给滑动块执行移动动画
 * @param fromXDelta 开始位移x轴的偏移量(都是相对于自身来言的偏移量)
 * @param toXDelta   结束位移x轴的偏移量
 */
private void startTranslateAnimation(int fromXDelta, int toXDelta) {
	TranslateAnimation ta = new TranslateAnimation(
			fromXDelta, toXDelta, 0, 0);
	ta.setDuration(500);
	ta.setFillAfter(true);	// 停留在动画结束的位置上
	mSlideView.startAnimation(ta);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值