這篇文章主要是分析網易主頁的tabhost的製作和動態的移動背景實現,首先說一下tabhost這個組件,android原生的tabhost的tab導航是在屏幕上方顯示顯示的,如果要使tab導航在屏幕下方需要在xml佈局文件中把TabWidget佈局到tabcontent下方即可,下面來看下具體是怎樣佈局的:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabHost
android:id="@+id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/column_navi" >
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="41.0dip" >
<LinearLayout
android:id="@+id/tab_news"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
<FrameLayout
android:id="@+id/tab_topic"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
<LinearLayout
android:id="@+id/tab_images"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/pictures_bg"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="@+id/tab_notes"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
<RelativeLayout
android:id="@+id/tab_vote"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/top_weight_bg" />
</RelativeLayout>
<include
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
layout="@layout/loadingbar" />
</FrameLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="43.0dip"
android:layout_alignParentBottom="true"
android:background="@drawable/tab_bg" />
<ImageView
android:id="@+id/tab_front_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@android:id/tabs"
android:layout_alignLeft="@android:id/tabs"
android:src="@drawable/tab_front_bg" />
<ImageView
android:id="@+id/tab_bg_bg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@android:id/tabs"
android:background="@drawable/bottom_weight_bg" />
</RelativeLayout>
</TabHost>
</LinearLayout>
大家可以看到在TabWidget標籤下面放了2張圖片,這2張圖片分別是實現動態移動的背景圖片和TabWidget的整體背景圖片,通過分析這2張圖片的佈局方式大家應該可以看得出來,這裏都不多說。
現在佈局弄好了,現在的問題就是怎樣讓我們選着一個tab項後面的背景也跟這移動到我選擇的位置呢?
其實很簡單,我是這樣實現的,首先在給tab標籤添加setIndicator(View view)的時候加入自定義的view,然後分別給自定義view控件添加onTouch()監聽,監聽的作用就是每次手指點擊到這個控件時,就獲取這個控件在屏幕上的座標位置,然後讓tab_front_bg圖片移動到當前座標即可。具體實現背景移動的細節可以參考我的另一片文章http://blog.csdn.net/yaoyeyzq/article/details/7579938
下面是實現的部分源碼:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TextView;
import com.yzq.text.custom.TabListener;
public class TestActivity extends Activity {
/** Called when the activity is first created. */
// private ScrollLayout scroll;
private ImageView tab_front_bg;
private TabHost host;
private TabListener tabListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
initView();
}
private void initView() {
host = (TabHost) findViewById(R.id.tabhost);
tab_front_bg = (ImageView) findViewById(R.id.tab_front_bg);
host.setup();
tabListener = new TabListener(tab_front_bg, this, host);
host.addTab(host.newTabSpec("xw").setIndicator(getIndicatorView(1))
.setContent(R.id.tab_news));
host.addTab(host.newTabSpec("ht").setIndicator(getIndicatorView(2))
.setContent(R.id.tab_topic));
host.addTab(host.newTabSpec("tp").setIndicator(getIndicatorView(3))
.setContent(R.id.tab_images));
host.addTab(host.newTabSpec("gt").setIndicator(getIndicatorView(4))
.setContent(R.id.tab_notes));
host.addTab(host.newTabSpec("tp").setIndicator(getIndicatorView(5))
.setContent(R.id.tab_vote));
host.setCurrentTab(0);
}
private View getIndicatorView(int location) {
LinearLayout layout = new LinearLayout(this);
TextView textView = new TextView(this);
switch (location) {
case 1:
textView.setId(R.id.news);
textView.setBackgroundDrawable(getResources().getDrawable(
R.drawable.current_news_tab));
break;
case 2:
textView.setId(R.id.topic);
textView.setBackgroundDrawable(getResources().getDrawable(
R.drawable.back_topic_tab));
break;
case 3:
textView.setId(R.id.picture);
textView.setBackgroundDrawable(getResources().getDrawable(
R.drawable.back_picture_tab));
break;
case 4:
textView.setId(R.id.comment);
textView.setBackgroundDrawable(getResources().getDrawable(
R.drawable.back_comment_tab));
break;
case 5:
textView.setId(R.id.vote);
textView.setBackgroundDrawable(getResources().getDrawable(
R.drawable.back_vote_tab));
break;
}
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, -1);
textView.setOnTouchListener(tabListener);
layout.addView(textView, params);
return layout;
}
}
下面是移動背景和動態改變tab圖片狀態的具體實現源碼:
import android.app.Activity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TabHost;
import android.widget.TextView;
import com.yzq.test.R;
/**
* @author Administrator
*
*/
public class TabListener implements OnTouchListener {
private int lastX = 0;
private TextView up_text;
private ImageView column_slide_bar;
private Activity cotext;
private TabHost host;
public TabListener(ImageView column_slide_bar, Activity cotext, TabHost host) {
super();
this.column_slide_bar = column_slide_bar;
this.cotext = cotext;
this.host = host;
}
/*
* (non-Javadoc)
*
* @see android.view.View.OnTouchListener#onTouch(android.view.View,
* android.view.MotionEvent)
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (up_text != null) {
switch (up_text.getId()) {
case R.id.news:
up_text.setBackgroundDrawable(cotext.getResources()
.getDrawable(R.drawable.back_news_tab));
break;
case R.id.topic:
up_text.setBackgroundDrawable(cotext.getResources()
.getDrawable(R.drawable.back_topic_tab));
break;
case R.id.picture:
up_text.setBackgroundDrawable(cotext.getResources()
.getDrawable(R.drawable.back_picture_tab));
break;
case R.id.comment:
up_text.setBackgroundDrawable(cotext.getResources()
.getDrawable(R.drawable.back_comment_tab));
break;
case R.id.vote:
up_text.setBackgroundDrawable(cotext.getResources()
.getDrawable(R.drawable.back_vote_tab));
break;
}
} else {
TextView news = (TextView) cotext.findViewById(R.id.news);
news.setBackgroundDrawable(cotext.getResources().getDrawable(
R.drawable.back_news_tab));
}
translateImage(event);
TextView tv = (TextView) v;
switch (tv.getId()) {
case R.id.news:
tv.setBackgroundDrawable(cotext.getResources().getDrawable(
R.drawable.current_news_tab));
host.setCurrentTab(0);
break;
case R.id.topic:
tv.setBackgroundDrawable(cotext.getResources().getDrawable(
R.drawable.current_topic_tab));
host.setCurrentTab(1);
break;
case R.id.picture:
tv.setBackgroundDrawable(cotext.getResources().getDrawable(
R.drawable.current_picture_tab));
host.setCurrentTab(2);
break;
case R.id.comment:
tv.setBackgroundDrawable(cotext.getResources().getDrawable(
R.drawable.current_comment_tab));
host.setCurrentTab(3);
break;
case R.id.vote:
tv.setBackgroundDrawable(cotext.getResources().getDrawable(
R.drawable.current_vote_tab));
host.setCurrentTab(4);
break;
}
up_text = tv;
}
return true;
}
private void translateImage(MotionEvent event) {
float x = event.getX();
float rx = event.getRawX();
final float nx = rx - x;
TranslateAnimation trans = null;
if (nx > lastX) {
trans = new TranslateAnimation(0, nx - lastX, 0, 0);
} else if (nx < lastX) {
trans = new TranslateAnimation(0, (lastX - nx) * -1, 0, 0);
} else {
return;
}
trans.setDuration(300);
trans.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
RelativeLayout.LayoutParams params = (LayoutParams) column_slide_bar
.getLayoutParams();
params.leftMargin = (int) nx;
column_slide_bar.setLayoutParams(params);
}
});
trans.setFillEnabled(true);
column_slide_bar.startAnimation(trans);
lastX = (int) nx;
}
}