国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android自定義View實(shí)現(xiàn)縱向跑馬燈效果詳解

2019-12-12 04:46:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

首先看看效果圖(錄制的gif有點(diǎn)卡,真實(shí)的效果還是很流暢的)

實(shí)現(xiàn)思路

通過(guò)上面的gif圖可以得出結(jié)論,其實(shí)它就是同時(shí)繪制兩條文本信息,然后通過(guò)動(dòng)畫(huà)不斷的改變兩條文本信息距離頂部的高度,以此來(lái)實(shí)現(xiàn)滾動(dòng)的效果。

具體實(shí)現(xiàn)

首先定義一些要用到的屬性

<declare-styleable name="MarqueeViewStyle">  <attr name="textSize" format="dimension" />  <attr name="textColor" format="color" />  <attr name="paddingLeft" format="dimension" />  <attr name="paddingTop" format="dimension" />  <attr name="paddingBottom" format="dimension" />  <attr name="paddingTopBottom" format="dimension"/>  <attr name="startDelayTime" format="integer"/> 動(dòng)畫(huà)開(kāi)始延遲時(shí)間<attr name="reRepeatDelayTime" format="integer"/> 動(dòng)畫(huà)重復(fù)延遲時(shí)間 <attr name="itemAnimationTime" format="integer"/> 單個(gè)動(dòng)畫(huà)的執(zhí)行時(shí)間</declare-styleable>

接下來(lái)解析屬性值

private void init(Context context, AttributeSet attrs) {   TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MarqueeViewStyle);   mTextColor = typedArray.getColor(R.styleable.MarqueeViewStyle_textColor, Color.BLACK);   mTextSize = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_textSize, 45);   mPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingLeft, 15);   mPaddingTop = mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingTopBottom, 25);   mPaddingTop = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingTop, mPaddingTop);   mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingBottom, mPaddingBottom);   itemAnimationTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_itemAnimationTime, 1000);   reRepeatDelayTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_reRepeatDelayTime, 1000);   startDelayTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_startDelayTime, 500);   typedArray.recycle();    mPaint = new Paint();    mPaint.setAntiAlias(true);    mPaint.setTextSize(mTextSize);    mPaint.setColor(mTextColor);    mPaint.setTextAlign(Paint.Align.LEFT);}

重寫(xiě)onMeasure方法

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    if(mTextArray == null || mTextArray.length == 0) {       super.onMeasure(widthMeasureSpec, heightMeasureSpec);    } else {        int width = MeasureSpec.getSize(widthMeasureSpec);      int height = MeasureSpec.getSize(heightMeasureSpec);       ViewGroup.LayoutParams lp = getLayoutParams();        setMeasuredDimension(getViewWidth(lp, width), getViewHeight(lp, height));    }}

數(shù)據(jù)為空時(shí)調(diào)用父類的方法,設(shè)置數(shù)據(jù)以后根據(jù)不同的布局計(jì)算寬高。

設(shè)置數(shù)據(jù)

public void setTextArray(String[] textArray) {    if(textArray == null || textArray.length <= 1) return;    mTextArray = textArray;    initTextRect();    setTextCurrentOrNextStatus(0, 1, true);    startAnimation();}

initTextRect()方法是計(jì)算出單個(gè)文本的高度和數(shù)組中最大文本的寬度,文本的高度用來(lái)計(jì)算繪制文本時(shí)的位置,文本的最大寬度在onMeasure()方法的時(shí)候會(huì)用到。

setTextCurrentOrNextStatus()方法設(shè)置當(dāng)前的position,文本以及下一個(gè)position,文本。還有文本距離頂部的初始化高度。

startAnimation() 方法 開(kāi)始執(zhí)行動(dòng)畫(huà)。

動(dòng)畫(huà)實(shí)現(xiàn)

private void startAnimation() {   va = ValueAnimator.ofFloat(0, 1);   va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {     @Override     public void onAnimationUpdate(ValueAnimator animation) {     mProgress = (float) animation.getAnimatedValue();      .   int moveOffset = (int) (mTextMoveOffset * mProgress);    mCurrentTextMoveMarginTop = mCurrentTextInitMarginTop - moveOffset;         mNextTextMoveMarginTop = mNextTextInitMarginTop - moveOffset;         postInvalidate();     }   });   va.addListener(new AnimatorListenerAdapter() {       @Override       public void onAnimationRepeat(Animator animation) {       va.pause();            setTextCurrentOrNextStatus(mNextTextPosition, mNextTextPosition + 1, false);          handler.postDelayed(new Runnable() {             @Override             public void run() {                va.resume();             }     }, reRepeatDelayTime);       }   });   va.setRepeatCount(-1);   va.setDuration(itemAnimationTime);   va.setStartDelay(startDelayTime);   va.start();}

va.setRepeatCount(-1); 設(shè)置動(dòng)畫(huà)無(wú)限重復(fù)

onAnimationUpdate() 方法得到動(dòng)畫(huà)執(zhí)行的進(jìn)度,計(jì)算出text距離頂部的距離,調(diào)用postInvalidate()方法刷新界面。

onAnimationRepeat() 方法,通過(guò)handler延遲reRepeatDelayTime時(shí)間,再重新執(zhí)行動(dòng)畫(huà)。

繪制

protected void onDraw(Canvas canvas) {   if(mTextArray == null || mTextArray.length == 0) {     super.onDraw(canvas);   } else {      canvas.drawText(mCurrentText, mPaddingLeft, mCurrentTextMoveMarginTop, mPaint);    canvas.drawText(mNextText, mPaddingLeft, mNextTextMoveMarginTop, mPaint);   }}

總結(jié)

到這里所有的代碼已經(jīng)分析完畢,其實(shí)實(shí)現(xiàn)這個(gè)效果還有很多種方法,通過(guò)繼承ViewGroup等等都可以實(shí)現(xiàn),大家有興趣可以自己嘗試。希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能有所幫助,如果有疑問(wèn)大家可以留言交流。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 灯塔市| 长岛县| 常德市| 乐东| 观塘区| 开平市| 嵊州市| 莱芜市| 永兴县| 兴隆县| 巨野县| 安阳县| 大化| 石门县| 台东市| 西华县| 双江| 双峰县| 临潭县| 绥芬河市| 宽甸| 汉阴县| 班戈县| 合江县| 恩平市| 广德县| 舟山市| 静安区| 仁怀市| 南丹县| 西华县| 嘉义市| 朝阳县| 滦平县| 崇州市| 郁南县| 新干县| 达尔| 亳州市| 石楼县| 德清县|