运行效果图:


实现原理:标签布局好了以后,标签所在View响应onClick事件。添加另外的标签View,不响应点击事件,用于实现动画效果。在标签的onClick事件中调整移动的起始位置,和滑动标签的状态。
布局文件activity_label.xml:
<?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="wrap_content"
android:gravity="center" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="40dip"
android:background="@android:drawable/title_bar" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<TextView
android:id="@+id/label_1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="图片" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<TextView
android:id="@+id/label_2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="地图" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<TextView
android:id="@+id/label_3"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="搜索" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<TextView
android:id="@+id/label_4"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="问答" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<TextView
android:id="@+id/label_5"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="新闻" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<TextView
android:id="@+id/label_6"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="更多" />
</RelativeLayout>
</LinearLayout>
<TextView
android:id="@+id/label_move"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@android:drawable/editbox_background"
android:gravity="center"
android:text="图片" />
</RelativeLayout>
</LinearLayout>
说明:
- 为了让被点击的标签所占区域更大,使用了android:layout_height="fill_parent"设置;
- 使用android:layout_weight="1"控制显示的相对大小;
主要代码:
import android.app.Activity;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.animation.TranslateAnimation;
import android.widget.TextView;
public class LabelActivity extends Activity implements OnClickListener {
/**
* 标签字符
*/
private String[] labelValues = {"图片", "地图", "搜索", "问答", "新闻", "更多"};
/**
* 标签数组
*/
private TextView[] labelViews = new TextView[6];
/**
* 动画标签
*/
private TextView labelMove;
/**
* 标签宽度
*/
private int labelWidth;
/**
* 移动开始位置
*/
private int fromX;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_label);
setTitle("标签");
// 获得标签引用
labelViews[0] = (TextView) findViewById(R.id.label_1);
labelViews[1] = (TextView) findViewById(R.id.label_2);
labelViews[2] = (TextView) findViewById(R.id.label_3);
labelViews[3] = (TextView) findViewById(R.id.label_4);
labelViews[4] = (TextView) findViewById(R.id.label_5);
labelViews[5] = (TextView) findViewById(R.id.label_6);
labelMove = (TextView) findViewById(R.id.label_move);
// 添加点击事件
for (int i = 0, length = labelViews.length; i< length; i++) {
labelViews[i].setOnClickListener(this);
}
// 获得并设置标签宽度
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
labelWidth = display.getWidth() / 6;
labelMove.setWidth(labelWidth);
}
@Override
public void onClick(View v) {
int index = 0;
switch (v.getId()) {
case R.id.label_1:
index = 0;
break;
case R.id.label_2:
index = 1;
break;
case R.id.label_3:
index = 2;
break;
case R.id.label_4:
index = 3;
break;
case R.id.label_5:
index = 4;
break;
case R.id.label_6:
index = 5;
break;
default:
return;
}
// 移动View
translate(labelMove, fromX, labelWidth * index);
// 设置标题
labelMove.setText(labelValues[index]);
// 更新fromX,为下次移动做准备
fromX = labelWidth * index;
}
/**
* 将View从(fromX,0)移动到(toX,0)
* @param view
* @param fromX
* @param toX
*/
public static void translate(View view, int fromX, int toX) {
TranslateAnimation translateAnimation = new TranslateAnimation(fromX, toX, 0, 0);
translateAnimation.setDuration(200);
translateAnimation.setFillAfter(true);
view.startAnimation(translateAnimation);
}
}
说明:
- labelMove:用于移动和标识被选中标签的View,可以通过改变这个View的属性来达到想要的选中效果;
- translate:把View水平方向移动;
- onClick中的switch获得需要的index,然后设置labelMove的属性和下次移动水平的开始位置;
本文介绍了一种基于Android的标签导航栏动画实现方案。通过自定义布局和View动画,实现了标签切换时平滑的动画效果。文章详细展示了如何利用TextView和TranslateAnimation实现标签之间的平滑过渡。
846

被折叠的 条评论
为什么被折叠?



