<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.tabanim.MainActivity" >
<TextView
android:id="@+id/textView0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/linearLayout1">
<ImageView
android:id="@+id/imageView"
android:layout_width="360dp"
android:layout_height="wrap_content"
android:src="@drawable/abc_tab_selected_pressed_holo">
</ImageView>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="120dp"
android:layout_height="60dp"
android:background="#ffcc00"
android:text="TextView" />
<TextView
android:id="@+id/textView2"
android:layout_width="120dp"
android:layout_height="60dp"
android:background="#dd00ff"
android:text="TextView" />
<TextView
android:id="@+id/textView3"
android:layout_width="120dp"
android:layout_height="60dp"
android:background="#aacc00"
android:text="TextView" />
</LinearLayout>
<Button
android:id="@+id/Cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel" />
</LinearLayout>
</LinearLayout>
package com.example.tabanim;import android.animation.Animator;import android.animation.ValueAnimator;import android.animation.ValueAnimator.AnimatorUpdateListener;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.animation.LinearInterpolator;import android.widget.Button;import android.widget.ImageView;import android.widget.ImageView.ScaleType;import android.widget.LinearLayout;import android.widget.TextView;public class MainActivity extends Activity {private ImageView image; private TextView btn1, btn2, btn3, btn4; private Button cancel;private TabIndicatorAnim mTabIndicatorAnim;private int mWidth = (int) (1080/3.0);private int mLastPos = 0; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView)findViewById(R.id.imageView); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) image .getLayoutParams(); lp.width = mWidth; image.setLayoutParams(lp); image.setScaleType(ScaleType.FIT_XY); btn1 = (TextView)findViewById(R.id.textView1); btn2 = (TextView)findViewById(R.id.textView2); btn3 = (TextView)findViewById(R.id.textView3); // btn4 = (Button)findViewById(R.id.button4); cancel = (Button)findViewById(R.id.Cancel); mTabIndicatorAnim = new TabIndicatorAnim(image, mWidth); image.setTranslationX(mLastPos*mWidth); btn1.setOnClickListener(new Button.OnClickListener(){//创建监听 public void onClick(View v) { mTabIndicatorAnim.startAnim(mLastPos, 0); mLastPos = 0; } }); btn2.setOnClickListener(new Button.OnClickListener(){//创建监听 public void onClick(View v) { mTabIndicatorAnim.startAnim(mLastPos, 1); mLastPos = 1; } }); btn3.setOnClickListener(new Button.OnClickListener(){//创建监听 public void onClick(View v) { mTabIndicatorAnim.startAnim(mLastPos, 2); mLastPos = 2; } }); cancel.setOnClickListener(new Button.OnClickListener(){//创建监听 public void onClick(View v) { mTabIndicatorAnim.cancelAnim(); float f1 = 360.0f; int f2 = mWidth; int retval = Float.compare(f1, f2); if(retval > 0) { Log.e("suosuo", "f1 is greater than f2"); } else if(retval < 0) { Log.e("suosuo", "f1 is less than f2"); } else { Log.e("suosuo", "f1 is equal to f2"); } } }); // btn4.setOnClickListener(new Button.OnClickListener(){//创建监听 // public void onClick(View v) { // mTabIndicatorAnim.startAnim(mLastPos, 3);// mLastPos = 3;// } // }); } class TabIndicatorAnim { private int mWidth; private View mView; private int mCancelLastStartPos = -1; private ValueAnimator mAnimator; private float mScaleUpProp = 130; private float mTotalProp = 480; private int mDuration = 5000;//480; private float mScaleDownValue = 1.0f; private float mScaleUpValue = 2.0f; TabIndicatorAnim(View view, int width) { mView = view; mWidth = width; } public void startAnim(int from, int to){ //cancelAnim(); if (from == to) { return; } else if (from < to) { // from left to right cancelAnim(); anim(from, to, 1, to-from); } else { // from right to left cancelAnim(); anim(from, to, 0, from-to); } } private void cancelAnim(){ if (mAnimator != null) mAnimator.cancel(); } private void anim(final int from, final int to, final int l2r, final int count) { mAnimator = ValueAnimator.ofFloat(0, mScaleUpProp, mTotalProp); mAnimator.setTarget(mView); mAnimator.setDuration(mDuration).start(); // mAnimator.setInterpolator(new LinearInterpolator()); mAnimator.addUpdateListener(new AnimatorUpdateListener() { boolean isAfterScaleUp = false; boolean isAfterLeaveGap = false; int afterScaleUpX = 0; float orginalScaleX = mView.getScaleX(); float orginalTranslationX = mView.getTranslationX(); int transXCmpRet = Float.compare(orginalTranslationX, from*mWidth); int scaleXCmpRet = Float.compare(2.0f, orginalScaleX); int test = 1; public void onAnimationUpdate(ValueAnimator animation) { Float value = (Float) animation.getAnimatedValue(); Log.e("suosuoa", "from " + from + " to " + to + " value " + value + " orginalScaleX " + orginalScaleX + " orginalTranslationX " + orginalTranslationX); if (test == 1) { } else if (test == 2) { if (l2r == 1) { if (transXCmpRet > 0) { // 1->0 cancel, 0->1 anim start if (orginalScaleX > mScaleDownValue) { Log.e("suosuoa", "ccccccc orginalScaleX" + orginalScaleX); mView.setPivotX((l2r == 1)?(mWidth):(0)); mView.setScaleX((float) (orginalScaleX-(orginalScaleX-mScaleDownValue)*(value)/mTotalProp)); //scale 2 to 1 } } else if (transXCmpRet < 0) { //0->1 cancel, 1->2 startAnim Log.e("suosuoa", "0->1 cancel, 1->2 startAnim"); if (scaleXCmpRet == 0) { // scale up done and scale down if (!isAfterScaleUp) { mView.setPivotX((l2r == 1)?(mWidth):(0)); if (mCancelLastStartPos != -1) { Log.e("mCancelLastStartPos", "mCancelLastStartPos " + mCancelLastStartPos); afterScaleUpX = (l2r == 1)?((mCancelLastStartPos+1)*mWidth):((mCancelLastStartPos-1)*mWidth); mView.setTranslationX(afterScaleUpX); } isAfterScaleUp = true; } else { mView.setScaleX((float) (mScaleUpValue-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1 Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX() + " value " + value); if (to-mCancelLastStartPos > 1) { mView.setTranslationX((l2r == 1)? (afterScaleUpX+(to-mCancelLastStartPos-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)): (afterScaleUpX-(to-mCancelLastStartPos-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX()); } } } else if (scaleXCmpRet > 0) { // start scale up and scale up doing mView.setPivotX((l2r == 1)?(0):(mWidth)); Log.e("suosuo", "aaaa value " + value); float updateScaleX = orginalScaleX + (value/mScaleUpProp)*(mScaleUpValue-orginalScaleX); if (updateScaleX > mScaleUpValue) updateScaleX = mScaleUpValue; mView.setScaleX(updateScaleX); scaleXCmpRet = Float.compare(mScaleUpValue, updateScaleX); } } else {// from begin point if (scaleXCmpRet == 0) { // scale up done and scale down if (!isAfterScaleUp) { mView.setPivotX((l2r == 1)?(mWidth):(0)); if (count == 1) { mView.setTranslationX(to*mWidth); Log.e("suosuo", "getTranslationX2 " + mView.getTranslationX()); } else { afterScaleUpX = (l2r == 1)?((from+1)*mWidth):((from-1)*mWidth); mView.setTranslationX(afterScaleUpX); } isAfterScaleUp = true; } else { mView.setScaleX((float) (mScaleUpValue-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1 Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX() + " value " + value); if (count > 1) { mView.setTranslationX((l2r == 1)? (afterScaleUpX+(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)): (afterScaleUpX-(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX()); } } } else if (scaleXCmpRet > 0) { // start scale up and scale up doing mView.setPivotX((l2r == 1)?(0):(mWidth)); Log.e("suosuo", "aaaa value " + value); float updateScaleX = orginalScaleX + (mScaleUpValue-orginalScaleX)*(value)/mTotalProp; if (updateScaleX > mScaleUpValue) updateScaleX = mScaleUpValue; mView.setScaleX(updateScaleX); scaleXCmpRet = Float.compare(mScaleUpValue, updateScaleX); } } } else { // right to left if (transXCmpRet > 0) { //2->1 cancel, 1->0 startAnim Log.e("suosuoa", "2->1 cancel, 1->0 startAnim"); if (scaleXCmpRet == 0) { // scale up done and scale down if (!isAfterScaleUp) { mView.setPivotX((l2r == 1)?(mWidth):(0)); if (mCancelLastStartPos != -1) { Log.e("mCancelLastStartPos", "mCancelLastStartPos " + mCancelLastStartPos); afterScaleUpX = (l2r == 1)?((mCancelLastStartPos+1)*mWidth):((mCancelLastStartPos-1)*mWidth); mView.setTranslationX(afterScaleUpX); } isAfterScaleUp = true; } else { mView.setScaleX((float) (mScaleUpValue-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1 Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX() + " value " + value); int count = (l2r == 1)?(to-mCancelLastStartPos):(mCancelLastStartPos - to); if (count > 1) { mView.setTranslationX((l2r == 1)? (afterScaleUpX+(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)): (afterScaleUpX-(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX()); } } } else if (scaleXCmpRet > 0) { // start scale up and scale up doing mView.setPivotX((l2r == 1)?(0):(mWidth)); Log.e("suosuo", "aaaa value " + value); float updateScaleX = orginalScaleX + (value/mScaleUpProp)*(mScaleUpValue-orginalScaleX); if (updateScaleX > mScaleUpValue) updateScaleX = mScaleUpValue; mView.setScaleX(updateScaleX); scaleXCmpRet = Float.compare(mScaleUpValue, updateScaleX); } } else if (transXCmpRet < 0) { if (to == mCancelLastStartPos) { // 0->1 cancel, 1->0 anim start if (orginalScaleX > mScaleDownValue) { Log.e("suosuoa", "ccccccc orginalScaleX" + orginalScaleX); mView.setPivotX((l2r == 1)?(mWidth):(0)); mView.setScaleX((float) (orginalScaleX-(orginalScaleX-mScaleDownValue)*(value)/mTotalProp)); //scale 2 to 1 } } else if (to > mCancelLastStartPos) { // 0->2 cancel, 2->1 anim start } } else {// from begin point if (scaleXCmpRet == 0) { // scale up done and scale down if (!isAfterScaleUp) { mView.setPivotX((l2r == 1)?(mWidth):(0)); if (count == 1) { mView.setTranslationX(to*mWidth); Log.e("suosuo", "getTranslationX2 " + mView.getTranslationX()); } else { afterScaleUpX = (l2r == 1)?((from+1)*mWidth):((from-1)*mWidth); mView.setTranslationX(afterScaleUpX); } isAfterScaleUp = true; } else { mView.setScaleX((float) (2-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1 Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX() + " value " + value); if (count > 1) { mView.setTranslationX((l2r == 1)? (afterScaleUpX+(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)): (afterScaleUpX-(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX()); } } } else if (scaleXCmpRet > 0) { // start scale up and scale up doing mView.setPivotX((l2r == 1)?(0):(mWidth)); Log.e("suosuo", "aaaa value " + value); float updateScaleX = orginalScaleX + (mScaleUpValue-orginalScaleX)*(value)/mTotalProp; if (updateScaleX > 2.0f) updateScaleX = 2.0f; mView.setScaleX(updateScaleX); scaleXCmpRet = Float.compare(2.0f, updateScaleX); } } } } else { if (value < mScaleUpProp){ mView.setPivotX((l2r == 1)?(0):(mWidth)); mView.setScaleX((float) (1+value/mScaleUpProp)); // scale 1 to 2 //Log.e("suosuo", "getTranslationX1 " + mView.getTranslationX()); } else if (value < mTotalProp) {//-50){ if (!isAfterScaleUp) { mView.setPivotX((l2r == 1)?(mWidth):(0)); if (count == 1) { mView.setTranslationX(to*mWidth); //Log.e("suosuo", "getTranslationX2 " + mView.getTranslationX()); } else { afterScaleUpX = (l2r == 1)?((from+1)*mWidth):((from-1)*mWidth); mView.setTranslationX(afterScaleUpX); } isAfterScaleUp = true; } else { mView.setScaleX((float) (2-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1 if (count > 1) { mView.setTranslationX((l2r == 1)? (afterScaleUpX+(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)): (afterScaleUpX-(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX()); } } } // else if (value < mTotalProp-20){// if (!isAfterLeaveGap) {// mView.setPivotX((l2r == 1)?(mWidth):(0));// if (count == 1) {// mView.setTranslationX(to*mWidth+40);// Log.e("suosuo", "getTranslationX2 " + mView.getTranslationX());// } else {// afterScaleUpX = (l2r == 1)?((from+1)*mWidth):((from-1)*mWidth);// mView.setTranslationX(afterScaleUpX); // }// isAfterLeaveGap = true;// } else {// mView.setScaleX((float) (2-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1// if (count > 1) { // mView.setTranslationX((l2r == 1)?// (afterScaleUpX+(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)):// (afterScaleUpX-(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)));// Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX());// }// }// } else {// if (!isAfterScaleUp) {// mView.setPivotX((l2r == 1)?(mWidth):(0));// if (count == 1) {// mView.setTranslationX(to*mWidth);// Log.e("suosuo", "getTranslationX2 " + mView.getTranslationX());// } else {// afterScaleUpX = (l2r == 1)?((from+1)*mWidth):((from-1)*mWidth);// mView.setTranslationX(afterScaleUpX); // }// isAfterScaleUp = true;// } else {// mView.setScaleX((float) (2-(value-mScaleUpProp)/(mTotalProp-mScaleUpProp))); //scale 2 to 1// if (count > 1) { // mView.setTranslationX((l2r == 1)?// (afterScaleUpX+(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)):// (afterScaleUpX-(count-1)*mWidth*(value-mScaleUpProp)/(mTotalProp-mScaleUpProp)));// Log.e("suosuo", "getTranslationX3 " + mView.getTranslationX());// }// }// } } } }); mAnimator.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationCancel(Animator arg0) {// TODO Auto-generated method stubLog.e("suosuo", "onAnimationCancel");mCancelLastStartPos = from;}@Overridepublic void onAnimationEnd(Animator arg0) {// TODO Auto-generated method stub// mView.setScaleX(1); // mView.setTranslationX(to*mWidth);}@Overridepublic void onAnimationRepeat(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub} }); } }}
</pre><pre name="code" class="java">