这篇文章主要是分析网易主页的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;
}
}