为什么80%的码农都做不了架构师?>>>
方案一、采用属性动画ValueAnimator
// 获取屏幕宽度
final int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.value_animator);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
// 当前动画值,即为当前宽度比例值
int currentValue = (Integer) animator.getAnimatedValue();
// 根据比例更改目标view的宽度
view.getLayoutParams().width = maxWidth * currentValue / 100;
view.requestLayout();
}
});
valueAnimator.start();
方案二、利用Interpolator.getInterpolation计算已经走过的距离
//利用Interpolator.getInterpolation计算已经走过的距离
package com.qianwang.qianbao.im.ui.main;
import java.util.ArrayList;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.qianwang.qianbao.im.R;
import com.qianwang.qianbao.im.ui.action.InitViews;
import com.qianwang.qianbao.im.views.pulltorefresh.internal.ViewCompat;
/**
* 主界面tab view
*
* @author zhangxiaolong
* @since qianbao3.0
*/
public class MainTabView extends LinearLayout implements InitViews, OnGlobalLayoutListener
{
private MainTabActivity mMainTabActivity;
private LinearLayout mTabLayout;
private TextView mTxtCursor;
private int mCursorMoveSpace = 0;
private float mCursorFromXDelta = 0;
private ArrayList mFragments = null;
private int tabCount = 4;
private OnTabClickListener mOntaClickListener = new OnTabClickListener();
public MainTabView(Context context) {
super(context);
initViews(context, null);
bindListener();
}
public MainTabView(Context context, AttributeSet attrs) {
super(context, attrs);
initViews(context, null);
bindListener();
}
@Override
public void initViews(Context context, View root)
{
setOrientation(LinearLayout.HORIZONTAL);
LayoutInflater layoutInflater = LayoutInflater.from(context);
layoutInflater.inflate(getLayoutId(), this);
mTxtCursor = (TextView) findViewById(R.id.cursor);
mTabLayout = (LinearLayout)findViewById(R.id.tab_layout);
postDelayed(mDismissRunnable, 3000);
}
@Override
public void bindListener()
{
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@Override
public void initData()
{
}
@Override
public int getLayoutId()
{
return R.layout.main_top_tab;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public synchronized void onGlobalLayout()
{
final int width = getWidth();
if(width != 0)
{
int tabWidth = width / tabCount;
mCursorMoveSpace = tabWidth;
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)mTxtCursor.getLayoutParams();
params.width = tabWidth;
mTxtCursor.setLayoutParams(params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
else
{
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
}
public void setTabCount(int tabCount)
{
this.tabCount = tabCount;
setCursorLayout(0);
}
public void setCursorFromXDelta(int position)
{
mCursorFromXDelta = position * mCursorMoveSpace;
}
public int getCursorMoveSpace()
{
return mCursorMoveSpace;
}
/**
* 设置cursor左边距
*
* @param leftMargin cursor 距离左边的距离
*/
public void setCursorLayout(int leftMargin)
{
mTxtCursor.clearAnimation();
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)mTxtCursor.getLayoutParams();
params.setMargins(leftMargin, 0, 0, 0);
mTxtCursor.setLayoutParams(params);
mCursorFromXDelta = leftMargin;
}
public void setMainTabActivity(MainTabActivity mainTabActivity)
{
mMainTabActivity = mainTabActivity;
}
public void setSelectedTab(int index)
{
for (int i = 0; i < tabCount; i++)
{
final View view = mTabLayout.getChildAt(i);
final TextView textView = (TextView) view.findViewById(R.id.main_tab_item_text);
final int tag = (Integer)view.getTag() ;
textView.setSelected(tag == index);
}
}
public View createTabItemView(String title, int icon, int index)
{
final View view = LayoutInflater.from(getContext()).inflate(R.layout.main_tab_item_view, null);
final TextView textView = (TextView) view.findViewById(R.id.main_tab_item_text);
// textView.setText(title);
textView.setBackgroundResource(icon);
view.setOnClickListener(mOntaClickListener);
view.setTag(index);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
params.weight = 1.0f;
mTabLayout.addView(view, params);
return view;
}
/**
* 设置tab右上角消息指示可见性
*
* @param cls tab位置上的fragment类名
* @param visibility
*/
public void setTabMsgIndicatorVisibility(int index, String fragmentName, int visibility, int count)
{
final View view = mTabLayout.getChildAt(index);
final TextView indicator = (TextView) view.findViewById(R.id.main_tab_item_msg_indicator);
if(indicator.getVisibility() != visibility)
indicator.setVisibility(visibility);
if(count > 0)
{
if(count > 99)
{
indicator.setText("99+");
}
else
{
indicator.setText(Integer.toString(count));
}
indicator.setTag(count);
indicator.setBackgroundResource(R.drawable.unread_indicator_yellow_bg);
}
else if(View.VISIBLE == visibility)
{
Object tag = indicator.getTag();
int tagCount = 0;
if(tag instanceof Integer)
{
tagCount = (Integer)tag;
}
if(tagCount == 0)
{
indicator.setText("");
indicator.setBackgroundResource(R.drawable.unread_indicator_yellow_bg_small);
}
}
else
{
indicator.setTag(0);
indicator.setText("");
indicator.setBackgroundResource(R.drawable.unread_indicator_yellow_bg_small);
}
}
public class OnTabClickListener implements View.OnClickListener
{
@Override
public void onClick(View v)
{
int index = (Integer)v.getTag();
float toXDelta = index * mCursorMoveSpace;
MarginLayoutParams params = (MarginLayoutParams) mTxtCursor.getLayoutParams();
Animation animation = new TranslateAnimation(-params.leftMargin + mCursorFromXDelta, -params.leftMargin
+ toXDelta, 0, 0);
animation.setFillAfter(true);
animation.setInterpolator(AnimationUtils.loadInterpolator(mMainTabActivity,
android.R.anim.linear_interpolator));
animation.setDuration(150);
mTxtCursor.startAnimation(animation);
if(index == mMainTabActivity.getViewPager().getCurrentItem())
{
BaseTabFragment fragment = mFragments.get(index);
fragment.onTabClick();
}
else
{
mMainTabActivity.setCurrentItem(index);
}
}
};
public void startShow()
{
if(mSmoothScrollRunnable != null)
{
mSmoothScrollRunnable.stop();
}
int fromY = mMainTabActivity.getRootView().getPaddingTop();
int toY = 0;
if(fromY == toY) return;
mSmoothScrollRunnable = new SmoothScrollRunnable(fromY, toY, 200);
post(mSmoothScrollRunnable);
}
public void startDismiss()
{
if(mSmoothScrollRunnable != null)
{
mSmoothScrollRunnable.stop();
}
int fromY = mMainTabActivity.getRootView().getPaddingTop();
int toY = -mTabLayout.getHeight();
if(fromY == toY) return;
mSmoothScrollRunnable = new SmoothScrollRunnable(fromY, toY, 500);
post(mSmoothScrollRunnable);
}
private SmoothScrollRunnable mSmoothScrollRunnable = null;
private Runnable mDismissRunnable = new Runnable()
{
@Override
public void run()
{
startDismiss();
}
};
final class SmoothScrollRunnable implements Runnable
{
private final Interpolator mInterpolator;
private final int mScrollToY;
private final int mScrollFromY;
private final long mDuration;
private boolean mContinueRunning = true;
private long mStartTime = -1;
private int mCurrentY = -1;
public SmoothScrollRunnable(int fromY, int toY, long duration)
{
mContinueRunning = true;
mScrollFromY = fromY;
mScrollToY = toY;
mInterpolator = new AccelerateInterpolator();
mDuration = duration;
}
@Override
public void run()
{
if (mStartTime == -1)
{
mStartTime = System.currentTimeMillis();
}
else
{
long normalizedTime = (1000 * (System.currentTimeMillis() - mStartTime)) / mDuration;
normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0);
final int deltaY = Math.round((mScrollFromY - mScrollToY)
* mInterpolator.getInterpolation(normalizedTime / 1000f));
mCurrentY = mScrollFromY - deltaY;
setTabScroll(mCurrentY);
}
// If we're not at the target Y, keep going...
if (mContinueRunning && mScrollToY != mCurrentY)
{
ViewCompat.postOnAnimation(MainTabView.this, this);
}
else
{
//stop...
}
}
public void stop()
{
mContinueRunning = false;
removeCallbacks(this);
}
private void setTabScroll(int value)
{
mMainTabActivity.getRootView().setPadding(0, value, 0, 0);
}
}
}
方案三、重写Animation.applyTransformation方法,在该方法中改变位置.参考SwipeRefreshLayout .java
//重写Animation.applyTransformation方法,在该方法中改变位置.参考SwipeRefreshLayout .java
package com.qianwang.qianbao.im.ui.friendscircle;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.Transformation;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class FriendsCircleLoadingImage extends ImageView
{
private static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();
private static final int ROTATION_ANIMATION_DURATION = 1200;
private static final int RETURN_TO_ORIGINAL_POSITION_TIMEOUT = 1000;
private static final float ACCELERATE_INTERPOLATION_FACTOR = 1.5f;
private final Animation mRotateAnimation;
private final Animation mAnimateToStartPosition;
private final Matrix mHeaderImageMatrix;
private final AccelerateInterpolator mAccelerateInterpolator;
private float mRotationPivotX, mRotationPivotY;
private final AnimationListener mReturnToStartPositionListener = new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
clearAnimation();
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)getLayoutParams();
lp.topMargin = 0;
setLayoutParams(lp);
}
@Override
public void onAnimationStart(Animation animation)
{
}
@Override
public void onAnimationRepeat(Animation animation)
{
}
};
public FriendsCircleLoadingImage(Context context)
{
this(context, null);
}
public FriendsCircleLoadingImage(Context context, AttributeSet attrs)
{
super(context, attrs);
setScaleType(ScaleType.MATRIX);
mHeaderImageMatrix = new Matrix();
setImageMatrix(mHeaderImageMatrix);
mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION);
mRotateAnimation.setRepeatCount(Animation.INFINITE);
mRotateAnimation.setRepeatMode(Animation.RESTART);
mAnimateToStartPosition = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
int targetTop = 0;
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)getLayoutParams();
if (lp.topMargin != 0) {
targetTop = (lp.topMargin + (int)((0 - lp.topMargin) * interpolatedTime));
}
lp.topMargin = targetTop;
setLayoutParams(lp);
}
};
mAccelerateInterpolator = new AccelerateInterpolator(ACCELERATE_INTERPOLATION_FACTOR);
}
public final void setLoadingDrawable(Drawable imageDrawable) {
setImageDrawable(imageDrawable);
if (null != imageDrawable) {
mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f);
mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f);
}
}
protected void updateState(float percent, float dy) {
float angle = percent * 360f;
mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY);
// mHeaderImageMatrix.postTranslate(0, dy);
setImageMatrix(mHeaderImageMatrix);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)getLayoutParams();
if(lp.topMargin != (int)dy)
{
lp.topMargin = (int)dy;
setLayoutParams(lp);
}
}
protected void startLoading() {
startAnimation(mRotateAnimation);
}
protected void stopLoading() {
clearAnimation();
if (null != mHeaderImageMatrix) {
mHeaderImageMatrix.reset();
setImageMatrix(mHeaderImageMatrix);
}
animateOffsetToStartPosition();
}
protected void animateOffsetToStartPosition() {
mAnimateToStartPosition.reset();
mAnimateToStartPosition.setDuration(RETURN_TO_ORIGINAL_POSITION_TIMEOUT);
mAnimateToStartPosition.setAnimationListener(mReturnToStartPositionListener);
mAnimateToStartPosition.setInterpolator(mAccelerateInterpolator);
startAnimation(mAnimateToStartPosition);
}
}