一、實現效果
就是一個列表的多條信息,上下切換展示,上下兩條挨着滑動。實現方法,考慮是 兩個TextView 使用動畫,不斷更新text內容。
二、TextSwitcher的使用
下面代碼看到,是集成自TextSwitcher的自定義view。主要:
1、 通過setFactory()設置 用於獲取 兩個切換view的view工廠,然後重寫Factory的makeView()方法 來定義TextView的樣式(setFactory內部會創建添加此textView兩次,即有了兩個TextView);
2、設置textVIew的進出的動畫。
3、設置列表數據,調用setText()來展示下一條。
/**
* 垂直滾動的Textview 類似小喇叭通知
*/
public class AutoVerticalScrollTextView extends TextSwitcher implements ViewSwitcher.ViewFactory {
private Context mContext;
//mInUp,mOutUp分別構成向下翻頁的進出動畫
private Rotate3dAnimation mInUp;
private Rotate3dAnimation mOutUp;
private int number = 0;
private boolean isRunning = true;
private NoticeHandler noticeHandler = new NoticeHandler();
/**
* 這個數組 用來存放你需要顯示的text
*/
private ArrayList<String> data;
private AutoVerticalScrollThread mAutoVerticalScrollThread;
public AutoVerticalScrollTextView(Context context) {
this(context, null);
}
public AutoVerticalScrollTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
private void init() {
setFactory(this);
mInUp = createInAnim(true, true);
mOutUp = createOutAnim(false, true);
setInAnimation(mInUp);//當View顯示時動畫資源ID
setOutAnimation(mOutUp);//當View隱藏是動畫資源ID。
}
private Rotate3dAnimation createInAnim(boolean turnIn, boolean turnUp) {
Rotate3dAnimation rotation = new Rotate3dAnimation(turnIn, turnUp);
rotation.setDuration(1500);//執行動畫的時間
rotation.setFillAfter(false);//是否保持動畫完畢之後的狀態
rotation.setInterpolator(new AccelerateInterpolator());//設置加速模式
return rotation;
}
private Rotate3dAnimation createOutAnim(boolean turnIn, boolean turnUp) {
Rotate3dAnimation rotation = new Rotate3dAnimation(turnIn, turnUp);
rotation.setDuration(1500);//執行動畫的時間
rotation.setFillAfter(false);//是否保持動畫完畢之後的狀態
rotation.setInterpolator(new AccelerateInterpolator());//設置加速模式
return rotation;
}
/**
* 這裏返回的TextView,就是我們看到的View,可以設置自己想要的效果
*
* @return
*/
public View makeView() {
TextView textView = new TextView(mContext);
textView.setGravity(Gravity.LEFT);
textView.setTextSize(11);//這是sp的單位
textView.setGravity(Gravity.CENTER_VERTICAL);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
textView.setMarqueeRepeatLimit(1);
textView.setTextColor(getResources().getColor(R.color.colorPrimary));//TODO
textView.setBackgroundResource(R.drawable.text_switch_bg);
Drawable leftDrawable = AppCompatResources.getDrawable(mContext, R.mipmap.icon_item_detail_back);
int w = leftDrawable.getIntrinsicWidth();
int h = leftDrawable.getIntrinsicHeight();
leftDrawable.setBounds(0, 0, w, h);
textView.setCompoundDrawables(leftDrawable, null, null, null);
textView.setCompoundDrawablePadding(10);
textView.setPadding(10,10,10,10);
return textView;
}
/**
* 定義動作,向上滾動翻頁
*/
private void showAnimation() {
//顯示動畫
if (getInAnimation() != mInUp) {
setInAnimation(mInUp);
}
//隱藏動畫
if (getOutAnimation() != mOutUp) {
setOutAnimation(mOutUp);
}
}
/**
* 傳入 要展示的 內容
* @param data
*/
public void setData(ArrayList<String> data) {
this.data = data;
}
/**
* 開始滾動
*/
public void start() {
if (mAutoVerticalScrollThread == null) {
mAutoVerticalScrollThread = new AutoVerticalScrollThread();
}
isRunning = true;
number = 0;
if (!mAutoVerticalScrollThread.isAlive()) {
mAutoVerticalScrollThread.start();
}
}
class AutoVerticalScrollThread extends Thread {
@Override
public void run() {
while (isRunning) {
noticeHandler.sendEmptyMessage(199);
SystemClock.sleep(4000); // TODO 這個播放間隔時間 可以作成 自定義屬性,在xml中設置
// noticeHandler.sendEmptyMessage(200);
// SystemClock.sleep(2500);
}
}
}
/**
* 停止滾動
*/
public void stop() {
// getNextView().setFocusable(false);
// getNextView().setFocusableInTouchMode(false);
isRunning = false;
noticeHandler.removeMessages(199);
if (mAutoVerticalScrollThread.isAlive()) {
mAutoVerticalScrollThread.stop();
}
}
private class NoticeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if (msg.what == 199) {
setText(data.get(number % data.size()));
showAnimation();
number++;
//
// getCurrentView().setFocusable(false);
// getCurrentView().setFocusableInTouchMode(false);
}
else if (msg.what == 200) {
//開始 跑馬燈效果
// getCurrentView().setFocusable(true);
// getCurrentView().setFocusableInTouchMode(true);
}
}
}
class Rotate3dAnimation extends Animation {
private float mCenterX;
private float mCenterY;
private final boolean mTurnIn;
private final boolean mTurnUp;
private Camera mCamera;
public Rotate3dAnimation(boolean turnIn, boolean turnUp) {
mTurnIn = turnIn;
mTurnUp = turnUp;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
mCenterY = getHeight();
mCenterX = getWidth();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final int derection = mTurnUp ? 1 : -1;
final Matrix matrix = t.getMatrix();
camera.save();
if (mTurnIn) {
camera.translate(0.0f, derection * mCenterY * (interpolatedTime - 1.0f), 0.0f);
} else {
camera.translate(0.0f, derection * mCenterY * (interpolatedTime), 0.0f);
}
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
}