package com.aiyou.bbs.utils;
import java.text.SimpleDateFormat;
import java.util.Locale;
import com.aiyou.R;
import com.aiyou.bbs.bean.User;
import com.aiyou.utils.SwitchManager;
import com.aiyou.view.ScrollTextView;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.view.ViewHelper;
import external.otherview.CircleImageView;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
public class UserInfoLayout extends ScrollView {
private int mStartColor;
private int mEndColor;
private FrameLayout mTopFLayout;
private CircleImageView mFaceCIV;
private LinearLayout mTextLLayout;
private ScrollTextView mIdTV, mNameTV;
private LinearLayout mContentLLayout;
// 基本信息
private TextView mGenderTV, mAstroTV, mQQTV, mMsnTV, mHomePageTV;
// 论坛属性
private TextView mLevelTV, mOnlineTV, mPostCountTV, mScoreTV, mLifeTV, mLastLoginTimeTV,
mLastLoginIpTV, mFirstLoginTimeTV;
private ObjectAnimator mObjectAnim;
private int mWidth;
private int mFaceHeight, mFaceWidth, mFaceMarginTop;
private int mTextHeight;
private int mTextPaddingTop;
private int mRange1, mRange2;
private boolean mIsTouchOrRunning = false;
private boolean mIsActionCancel = true;
private Status mStatus;
private float mDetalY;
private float mLastY;
private float mMinScale;
public UserInfoLayout(Context context) {
super(context);
}
public UserInfoLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UserInfoLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@SuppressWarnings("deprecation")
@Override
public void onFinishInflate() {
super.onFinishInflate();
if (SwitchManager.getInstance(getContext()).isNightModeEnabled()) {
mStartColor = Color.parseColor("#00222222");
mEndColor = Color.parseColor("#ff222222");
} else {
mStartColor = Color.parseColor("#000099cc");
mEndColor = Color.parseColor("#ff0099cc");
}
init();
this.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
UserInfoLayout.this.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mWidth = getWidth();
}
});
mFaceCIV.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mFaceCIV.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mFaceHeight = mFaceCIV.getHeight();
mFaceWidth = mFaceCIV.getWidth();
mFaceMarginTop = ((MarginLayoutParams) (mFaceCIV.getLayoutParams())).topMargin;
mRange2 = mFaceHeight + mFaceMarginTop;
}
});
mTextLLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mTextLLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mTextHeight = mTextLLayout.getHeight();
mTextPaddingTop = mTextLLayout.getPaddingTop();
mContentLLayout.setPadding(0, mTextHeight, 0, 0);
}
});
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
if (mFaceHeight > 0) {
mMinScale = (float) (mTextHeight - mTextPaddingTop) / mFaceHeight;
mRange1 = 2 * mFaceHeight - mTextHeight + mFaceMarginTop;
if (mRange1 < 0) {
mRange1 = 0;
}
} else {
handler.post(this);
}
}
});
handler.post(new Runnable() {
@Override
public void run() {
if (mWidth > 0 && mFaceWidth > 0) {
ViewHelper.setTranslationX(mFaceCIV, (mWidth - mFaceWidth) / 2);
} else {
handler.post(this);
}
}
});
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (Build.VERSION.SDK_INT < 11) {
return super.onInterceptTouchEvent(ev);
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mIsActionCancel = false;
mIsTouchOrRunning = true;
mLastY = ev.getY();
break;
}
return super.onInterceptTouchEvent(ev);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (Build.VERSION.SDK_INT < 11) {
return super.onTouchEvent(ev);
}
if (mObjectAnim != null && mObjectAnim.isRunning()) {
ev.setAction(MotionEvent.ACTION_UP);
mIsActionCancel = true;
}
if (mIsActionCancel && ev.getAction() != MotionEvent.ACTION_DOWN) {
return false;
}
if (ev.getActionIndex() != 0 && getScrollY() < mRange2) {
ev.setAction(MotionEvent.ACTION_UP);
mIsActionCancel = true;
}
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
mIsTouchOrRunning = true;
if (getScrollY() != 0) {
mDetalY = 0;
mLastY = ev.getY();
} else {
mDetalY = ev.getY() - mLastY;
if (mDetalY > 0) {
setT((int) -mDetalY / 5);
return true;
}
}
break;
case MotionEvent.ACTION_UP:
mIsTouchOrRunning = false;
if (getScrollY() < mRange2) {
if (mDetalY != 0) {
reset();
} else {
toggle();
}
return true;
}
break;
}
return super.onTouchEvent(ev);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (Build.VERSION.SDK_INT < 11) {
return;
}
if (t > mRange2) {
updateTopPadding(t);
ViewHelper.setTranslationX(mFaceCIV, -mFaceWidth * (1 - mMinScale) / 2f);
ViewHelper.setTranslationY(mFaceCIV, mRange2 - mRange1 + mFaceHeight
* (1 - mMinScale) / 2);
ViewHelper.setScaleX(mFaceCIV, mMinScale);
ViewHelper.setScaleY(mFaceCIV, mMinScale);
mTopFLayout.setBackgroundColor(mEndColor);
} else if (!mIsTouchOrRunning && t != mRange2) {
scrollTo(0, mRange2);
ViewHelper.setTranslationY(mTopFLayout, 0);
} else if (t > mRange1) {
animateScroll2(t);
ViewHelper.setTranslationY(mTopFLayout, 0);
ViewHelper.setScaleX(mFaceCIV, mMinScale);
ViewHelper.setScaleY(mFaceCIV, mMinScale);
} else {
animateScroll1(t);
ViewHelper.setTranslationY(mTopFLayout, 0);
ViewHelper.setTranslationX(mFaceCIV, (mWidth - mFaceWidth) / 2);
mTopFLayout.setBackgroundColor(mStartColor);
}
}
private void updateTopPadding(int t) {
ViewHelper.setTranslationY(mTopFLayout, t - mRange2);
}
private void animateScroll1(int t) {
float percent = (float) t / mRange1;
percent = mMinScale + (1 - percent) * (1 - mMinScale);
ViewHelper.setScaleX(mFaceCIV, percent);
ViewHelper.setScaleY(mFaceCIV, percent);
ViewHelper.setTranslationY(mFaceCIV, mFaceHeight * (1 - percent) / 2f);
}
private void animateScroll2(int t) {
float percent = (float) (mRange2 - t) / (mRange2 - mRange1);
ViewHelper.setTranslationX(mFaceCIV, ((mWidth - mFaceWidth) / 2) * percent - (1 - percent)
* mFaceWidth * (1 - mMinScale) / 2f);
// ViewHelper.setTranslationY(mFaceCIV, mFaceHeight * (1 - percent) / 2 + mFaceHeight
// * (1 - mMinScale) / 2);
ViewHelper.setTranslationY(mFaceCIV, t - mRange1 + mFaceHeight * (1 - mMinScale) / 2);
mTopFLayout.setBackgroundColor(evaluate(1 - percent, mStartColor, mEndColor));
}
private Integer evaluate(float fraction, Object startValue, Integer endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (startA + (int) (fraction * (endA - startA))) << 24
| (startR + (int) (fraction * (endR - startR))) << 16
| (startG + (int) (fraction * (endG - startG))) << 8
| (startB + (int) (fraction * (endB - startB)));
}
public void setT(int t) {
scrollTo(0, t);
if (t < 0) {
animatePull(t);
}
}
private void animatePull(int t) {
float percent = (float) t / mRange2;
ViewHelper.setScaleX(mFaceCIV, 1 - percent);
ViewHelper.setScaleY(mFaceCIV, 1 - percent);
ViewHelper.setTranslationY(mFaceCIV, mFaceHeight * -percent / 2f);
int padding = mTextHeight - t;
mTextLLayout.setPadding(0, mTextPaddingTop - t, 0, 0);
mContentLLayout.setPadding(0, padding, 0, 0);
}
public void toggle() {
if (isOpen()) {
close();
} else {
open();
}
}
public enum Status {
Open, Close;
}
public boolean isOpen() {
return mStatus == Status.Open;
}
private void reset() {
if (mObjectAnim != null && mObjectAnim.isRunning()) {
return;
}
mObjectAnim = ObjectAnimator.ofInt(this, "t", (int) -mDetalY / 5, 0);
mObjectAnim.setDuration(150);
mObjectAnim.start();
}
public void close() {
if (mObjectAnim != null && mObjectAnim.isRunning()) {
return;
}
mObjectAnim = ObjectAnimator.ofInt(this, "t", getScrollY(), mRange2);
mObjectAnim.setInterpolator(new DecelerateInterpolator());
mObjectAnim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
mIsTouchOrRunning = true;
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
mIsTouchOrRunning = false;
mStatus = Status.Close;
}
@Override
public void onAnimationCancel(Animator arg0) {
}
});
mObjectAnim.setDuration(250);
mObjectAnim.start();
}
public void open() {
if (mObjectAnim != null && mObjectAnim.isRunning()) {
return;
}
mObjectAnim = ObjectAnimator
.ofInt(this, "t", getScrollY(), (int) (-getScrollY() / 2.2f), 0);
mObjectAnim.setInterpolator(new DecelerateInterpolator());
mObjectAnim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
mIsTouchOrRunning = true;
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
mIsTouchOrRunning = false;
mStatus = Status.Open;
}
@Override
public void onAnimationCancel(Animator arg0) {
}
});
mObjectAnim.setDuration(400);
mObjectAnim.start();
}
public void setUser(User user) {
// 头像
if (null != user.face_url) {
mFaceCIV.setImageURL(user.face_url);
}
// id
if (null != user.id) {
mIdTV.setText(user.id);
}
// 昵称
if (null != user.user_name) {
mNameTV.setText(user.user_name);
}
// 性别
if (null != user.gender) {
if ("m".equals(user.gender)) {
mGenderTV.setText("帅哥");
} else if ("f".equals(user.gender)) {
mGenderTV.setText("美女");
} else {
mGenderTV.setText("保密");
}
}
// 星座
if (null != user.astro) {
if ("".equals(user.astro)) {
mAstroTV.setText("保密");
} else {
mAstroTV.setText(user.astro);
}
}
// qq
if (null != user.qq) {
if (!"".equals(user.qq)) {
mQQTV.setText(user.qq);
}
}
// msn
if (null != user.msn) {
if (!"".equals(user.msn)) {
mMsnTV.setText(user.msn);
}
}
// 主页
if (null != user.home_page) {
if (!"".equals(user.home_page)) {
mHomePageTV.setText(user.home_page);
}
}
// 论坛等级
if (null != user.level) {
mLevelTV.setText(user.level);
}
// 是否在线
if (!user.is_online) {
mOnlineTV.setText("否");
} else {
mOnlineTV.setText("是");
}
// 发文数
if (-1 != user.post_count) {
mPostCountTV.setText(user.post_count + "篇");
}
// 积分
if (-1 != user.score) {
mScoreTV.setText(user.score + "");
}
// 生命力
if (-1 != user.life) {
mLifeTV.setText(user.life + "");
}
// 上次登录时间
if (-1 != user.last_login_time) {
mLastLoginTimeTV.setText(formatTime(user.last_login_time));
}
// 上次登录IP
if (null != user.last_login_ip) {
mLastLoginIpTV.setText(user.last_login_ip);
}
// 注册时间
if (-1 != user.first_login_time) {
mFirstLoginTimeTV.setText(formatTime(user.first_login_time));
}
}
private String formatTime(long timeStamp) {
timeStamp *= 1000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
Locale.CHINA);
return sdf.format(timeStamp);
}
private void init() {
mTopFLayout = (FrameLayout) findViewById(R.id.fl_top);
mTopFLayout.setBackgroundColor(mStartColor);
mTopFLayout.bringToFront();
mFaceCIV = (CircleImageView) findViewById(R.id.civ_face);
mFaceCIV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
toggle();
}
});
mTextLLayout = (LinearLayout) findViewById(R.id.ll_text);
mContentLLayout = (LinearLayout) findViewById(R.id.ll_content);
mIdTV = (ScrollTextView) findViewById(R.id.tv_id);
mNameTV = (ScrollTextView) findViewById(R.id.tv_name);
mGenderTV = (TextView) findViewById(R.id.tv_gender);
mAstroTV = (TextView) findViewById(R.id.tv_astro);
mQQTV = (TextView) findViewById(R.id.tv_qq);
mMsnTV = (TextView) findViewById(R.id.tv_msn);
mHomePageTV = (TextView) findViewById(R.id.tv_home_page);
mLevelTV = (TextView) findViewById(R.id.tv_level);
mOnlineTV = (TextView) findViewById(R.id.tv_is_online);
mPostCountTV = (TextView) findViewById(R.id.tv_post_count);
mScoreTV = (TextView) findViewById(R.id.tv_score);
mLifeTV = (TextView) findViewById(R.id.tv_life);
mLastLoginTimeTV = (TextView) findViewById(R.id.tv_last_login_time);
mLastLoginIpTV = (TextView) findViewById(R.id.tv_last_login_ip);
mFirstLoginTimeTV = (TextView) findViewById(R.id.tv_first_login_time);
if (Build.VERSION.SDK_INT >= 11) {
initDivider();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void initDivider() {
LinearLayout[] array = new LinearLayout[15];
array[0] = (LinearLayout) findViewById(R.id.ll1);
array[1] = (LinearLayout) findViewById(R.id.ll2);
array[2] = (LinearLayout) findViewById(R.id.ll3);
array[3] = (LinearLayout) findViewById(R.id.ll4);
array[4] = (LinearLayout) findViewById(R.id.ll5);
array[5] = (LinearLayout) findViewById(R.id.ll6);
array[6] = (LinearLayout) findViewById(R.id.ll7);
array[7] = (LinearLayout) findViewById(R.id.ll8);
array[8] = (LinearLayout) findViewById(R.id.ll9);
array[9] = (LinearLayout) findViewById(R.id.ll10);
array[10] = (LinearLayout) findViewById(R.id.ll11);
array[11] = (LinearLayout) findViewById(R.id.ll12);
array[12] = (LinearLayout) findViewById(R.id.ll13);
array[13] = (LinearLayout) findViewById(R.id.ll14);
array[14] = (LinearLayout) findViewById(R.id.ll15);
Drawable drawableH, drawableV;
if (SwitchManager.getInstance(getContext()).isNightModeEnabled()) {
drawableH = getResources().getDrawable(R.drawable.divider_white_h_night);
drawableV = getResources().getDrawable(R.drawable.divider_white_v_night);
} else {
drawableH = getResources().getDrawable(R.drawable.divider_white_h_day);
drawableV = getResources().getDrawable(R.drawable.divider_white_v_day);
}
if (drawableH != null && drawableV != null) {
for (int i = 0; i < array.length; i++) {
if (i == 0 || i == 6) {
array[i].setDividerDrawable(drawableH);
} else {
array[i].setDividerDrawable(drawableV);
}
}
}
}
}