1. 程式人生 > >TextView實現高仿京東活動倒計時

TextView實現高仿京東活動倒計時

京東
  電商活動是比較多的,所以活動倒計時功能是必不可少的,自己當初實現的時候是採用複合佈局,最近突然發現京東的竟然是用原生的ImageView實現的,666啊!於是就開始Google,終於找到了類似的實現方法,就是利用android的ImageSpan實現的,看到這篇文章後,頓時醒悟,之前有了解過各種Span,沒有想到還可以這麼用.
  那就開始我們今天的重點
  ImageSpan,

public class BackgroundSpan extends ImageSpan {
    private Rect mTextBound;
    private int maxHeight = 0
; private int maxWidth = 0; private int mPaddingLeft = 20; private int mPaddingRight = 20; private int mPaddingTop = 20; private int mPaddingBottom = 20; private int mTextColor = Color.GREEN; private int mTextSize = 50; public BackgroundSpan(Drawable d, int verticalAlignment) { super
(d, verticalAlignment); mTextBound = new Rect(); } public BackgroundSpan setTimerTextColor(int mTextColor) { this.mTextColor = mTextColor; return this; } public BackgroundSpan setTimerTextSize(int textSize) { this.mTextSize = textSize; return
this; } public BackgroundSpan setTimerPadding(int left, int top, int right, int bottom) { this.mPaddingLeft = left; this.mPaddingRight = right; this.mPaddingBottom = bottom; this.mPaddingTop = top; return this; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { //繪制文字的內容的背景 paint.setTextSize(mTextSize); //測量文字的寬度和高度,通過mTextBound得到 paint.getTextBounds(text.toString(), start, end, mTextBound); //設定文字背景的寬度和高度,傳入的是left,top,right,bottom四個引數 maxWidth = maxWidth < mTextBound.width() ? mTextBound.width() : maxWidth; maxHeight = maxHeight < mTextBound.height() ? mTextBound.height() : maxHeight; //設定最大寬度和最大高度是為了防止在倒計時在數字切換的過程中會重繪,會導致倒計時邊框的寬度和高度會抖動, // 所以每次取得最大的高度和寬度而不是每次都去取測量的高度和寬度 getDrawable().setBounds(0, 0, maxWidth + mPaddingLeft + mPaddingRight, mPaddingTop + mPaddingBottom + maxHeight); //設定文字的顏色 paint.setColor(mTextColor); //設定字型的大小 paint.setTextSize(mTextSize); int mGapX = (getDrawable().getBounds().width() - maxWidth) / 2; //繪制文字內容 canvas.drawText(text.subSequence(start, end).toString(), x + mGapX, y , paint); //解決設定ImageSpan後其它文字不居中的問題 Drawable b = getDrawable(); canvas.save(); int transY = 0; //獲得將要顯示的文字高度-圖片高度除2等居中位置+top(換行情況) transY = ((bottom-top) - b.getBounds().bottom)/2+top; //偏移畫布後開始繪製 canvas.translate(x, transY); b.draw(canvas); canvas.restore(); } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { Drawable d = getDrawable(); Rect rect = d.getBounds(); if (fm != null) { //解決設定ImageSpan後其它文字不居中的問題 Paint.FontMetricsInt fmPaint=paint.getFontMetricsInt(); //獲得文字、圖片高度 int fontHeight = fmPaint.bottom - fmPaint.top; int drHeight=rect.bottom-rect.top; int top= drHeight/2 - fontHeight/4; int bottom=drHeight/2 + fontHeight/4; fm.ascent=-bottom; fm.top=-bottom; fm.bottom=top; fm.descent=top; } return rect.right; } }

  還要簡單的說明一下,如果我們只簡單的重寫draw方法,我們會發現沒有設定ImageSpan的文字不會居中,所以我們需要處理一下,核心就是getSize()方法以及draw()裡面畫布的偏移.
  接下來就是我們今天的第二位明星
  CountDownTimer

public class MyCountDownTimer extends CountDownTimer {
    private Context mContext;
    protected TextView mDateTv;
    private String mTimePattern = "HH:mm:ss";
    private String mTimeStr;
    private int mDrawableId;
    private boolean flag = false;
    protected String[] numbers;//此陣列用於生存每個倒計時字元拆分後的天,時,分,秒的數值
    protected List mBackSpanList;
    protected List mTextColorSpanList;
    //用於倒計時樣式的內間距,字型大小,字型顏色,倒計時間隔的顏色
    private int mSpanPaddingLeft, mSpanPaddingRight, mSpanPaddingTop, mSpanPaddingBottom;
    private int mSpanTextSize;
    private int mSpanTextColor;
    protected int mGapSpanColor;
    private SpannableString mSpan;


    public MyCountDownTimer(Context context, long millisInFuture, long countDownInterval, String timePattern, int drawableId, TextView textView) {
        super(millisInFuture, countDownInterval);
        mContext = context;
        mTimePattern = timePattern;
        mDrawableId = drawableId;
        mBackSpanList = new ArrayList<>();
        mTextColorSpanList = new ArrayList<>();
        mDateTv = textView;
    }

    @Override
    public void onTick(long millisUntilFinished) {
        //此處也是一個核心所在,DurationFormatUtils.formatDuration這是apache的org.apache.commons的lang裡面的,所以還需要引入它的jar包
        mTimeStr = DurationFormatUtils.formatDuration(millisUntilFinished, mTimePattern);
        setBackgroundSpan(mTimeStr);
    }

    @Override
    public void onFinish() {

    }

    public void setBackgroundSpan(String timeStr) {
        if (!flag) {
            initSpanData(timeStr);
            flag = true;
        }
        int mGapLen = 1;
        mSpan = new SpannableString(timeStr);
        for (int i = 0; i < mBackSpanList.size(); i++) {
            int start = i * numbers[i].length() + i * mGapLen;
            int end = start + numbers[i].length();
            //為數字設定ImageSpan
            setContentSpan(mSpan, mBackSpanList.get(i), start, end);
            if (i < mTextColorSpanList.size()) {//這裡為了就是防止12:36:27這種樣式,這種樣式距離只有2個以是須要做斷定,防止陣列越界
                setContentSpan(mSpan, mTextColorSpanList.get(i), end, end + mGapLen);
            }
        }
        mDateTv.setMovementMethod(LinkMovementMethod.getInstance());//此要領很主要須要挪用,不然繪製出來的倒計時就是重疊的樣式
        mDateTv.setText(mSpan);
    }

    public void initSpanData(String timeStr) {
        numbers = getNumInTimerStr(timeStr);
        for (int i = 0; i < numbers.length; i++) {
            BackgroundSpan backgroundColorSpan = new BackgroundSpan(ContextCompat.getDrawable(mContext, mDrawableId), ALIGN_BASELINE);
            initBackSpanStyle(backgroundColorSpan);
            mBackSpanList.add(backgroundColorSpan);
        }
    }

    protected void initBackSpanStyle(BackgroundSpan mBackSpan) {
        mBackSpan.setTimerPadding(mSpanPaddingLeft, mSpanPaddingTop, mSpanPaddingRight, mSpanPaddingBottom);
        mBackSpan.setTimerTextColor(mSpanTextColor);
        mBackSpan.setTimerTextSize(mSpanTextSize);
    }


    public void cancelTimer() {
        this.cancel();
    }

    public void startTimer() {
        this.start();
    }

    public String getmTimeStr() {
        return mTimeStr;
    }

    public MyCountDownTimer setTimerTextSize(int textSize) {
        this.mSpanTextSize = textSize;
        return this;
    }

    public MyCountDownTimer setTimerPadding(int left, int top, int right, int bottom) {
        this.mSpanPaddingLeft = left;
        this.mSpanPaddingBottom = bottom;
        this.mSpanPaddingRight = right;
        this.mSpanPaddingTop = top;
        return this;
    }

    public MyCountDownTimer setTimerTextColor(int color) {
        this.mSpanTextColor = color;
        return this;
    }

    public MyCountDownTimer setTimerGapColor(int color) {
        this.mGapSpanColor = color;
        return this;
    }
    //得到倒計時數字部分
    public static String[] getNumInTimerStr(String mTimerStr){
        return mTimerStr.split("[^\\d]");
    }
    //設定內容的Span
    public static void setContentSpan(SpannableString mSpan, Object span, int start,
                                      int end) {
        mSpan.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}

  使用方法如下:

new MyCountDownTimer(mContext,1000*60*60,1000,"HH:mm:ss",
R.drawable.timer_shape,mTextViewDurationFormat)
.setTimerPadding(10,10,10,10)
                .setTimerTextColor(Color.YELLOW)
                .setTimerTextSize(16)
                .setTimerGapColor(Color.BLACK);

相關推薦

TextView實現仿京東活動倒計時

  電商活動是比較多的,所以活動倒計時功能是必不可少的,自己當初實現的時候是採用複合佈局,最近突然發現京東的竟然是用原生的ImageView實現的,666啊!於是就開始Google,終於找到了類似的實現方法,就是利用android的ImageSpan實現的

淺談android中僅僅使用一個TextView實現仿京東,淘寶各種倒計時

  今天給大家帶來的是僅僅使用一個TextView實現一個高仿京東、淘寶、唯品會等各種電商APP的活動倒計時。最近公司一直加班也沒來得及時間去整理,今天難得休息想把這個分享給大家,只求共同學習,以及自己後續的複習。為什麼會想到使用一個TextView來實現呢?因為最近公司在

vue省市區三級聯動(仿京東

destroy 傳參 sla solid 列表 git type tom ott 該栗子是我直接從公司的項目單獨拉出來的(懶得重新寫一次了),所以代碼會有些冗余,下面直接看效果: 接著上代碼: html: <template> <div>

js實現仿京東搜尋欄隨滑動透明度漸變

注意:不相容IE8及以下,IE11和360的IE相容模式測試通過====IE8不支援opacity 此效果採用的opacity做的透明漸變 html部分 1 <header class="module-layer"> 2 <div class="module-laye

卡拉OK歌詞原理和實現仿Android網易雲音樂

大家好,我們是愛學啊,繼上一篇講解了【LRC歌詞原理和實現高仿Android網易雲音樂】,今天給大家帶來一篇關於卡拉OK歌詞原理和在Android上如何實現歌詞逐字滾動的效果,本文來自【Android開發專案實戰我的雲音樂】課程。 效果圖 相信大家都懂一張圖勝過千言萬語。 效果和現在市面上大部分播放

LRC歌詞原理和實現仿Android網易雲音樂

大家好,我們是愛學啊,今天給大家帶來一篇關於LRC歌詞原理和在Android上如何實現歌詞逐行滾動的效果,本文來自【Android開發專案實戰我的雲音樂】課程;逐字滾動下一篇文章講解。 效果圖 相信大家都懂一張圖勝過千言萬語。 效果和現在市面上大部分播放器差不多,當然如果要運用到商業專案中,肯定還需

android仿京東快報(垂直迴圈滾動新聞欄)

京東的垂直滾動新聞欄的實現原理: 就是一個自定義的LinearLayout,並且textView能夠迴圈垂直滾動,而且條目可以點選,顯示區域最多顯示2個條目,並且還有交替的屬性垂直移動的動畫效果,通過執行緒來控制滾動的實現。 不多說看效果:

Android之仿京東APP首頁“京東快報”自動向上滾動的廣告條

##前言 上次在京東APP上買東西時,發現首頁中間有塊叫“京東快報”的欄目,其中廣告條能自動向上滾動,效果還不錯,看到這個效果,第一個念頭就是我能不能實現,於是就誕生了這篇文章。 我們看看實現後的效果: ##實現原理 起初看到這個效果時,第一個想法就是向上移

Android仿京東淘寶商品列表佈局切換效果

商品列表佈局切換效果很常見,因為淘寶京東有的介面下面很多公司都會給風模仿 當然,我們公司也不例外,最近版本更新添加了這個功能; 在專案中直接使用RecyclerView實現切換功能; 如果不瞭解RecyclerView的可以先看下:  RecyclerView使用詳解

Android 實現仿iOS桌面效果之可拖動的GridView(上)

     最近專案中遇到一個LIstview的拖動效果,github上一搜發現有叫DragListview的開源專案,然後自己再小手一搜拖動排序的GridView,卻沒發現什麼很全很好的開源專案,後

一句程式碼叫你實現仿qq的側滑選單

           今天下午  小編在與同事們研究側滑選單的時候    百度搜索了很多例子    差不多都是一個人的專案   但是   使用起來  報錯  報錯  報錯      研究了好久   差點崩潰-------------於是我們打算自己研究    於是就這樣動了

一步一步實現仿支付寶金額圓環圖

現在應用裡面整合圖表是很常見的事了,簡單、直觀能給使用者更直觀的感受,包括支付寶,招商銀行App等,雖然有很多第三方的圖示庫,但是自己實現一個是不是很有成就感?主要優勢還是體現在自己可以實現一些特殊需求以及自己實現程式碼量小,不到150行。現在我們就來一步一步實現一個帶動畫的圓環圖,先放效果圖。 初始化一

仿京東分類效果(Scroll+Fragment)

實現思路:首先說下佈局,整個是一個橫向的線性佈局,左邊是一個ScrollView,右邊是一個FrameLayout, 在程式碼中動態向ScrollView中新增TextView,然後根據TextView的點選事件使用Fragment替換FrameLayout 首先看下

Vue2.0實現仿餓了麼專案裡的小球飛入動畫

在學習Vue.js高仿餓了麼專案的過程中,有一個小球飛入購物車的動畫效果。專案是基於vue1.0的,如果是vue2.0的專案,該如何實現呢?自己也花時間研究了一會,從迷惑不解,各種嘗試未果,到後來咬文嚼字研讀vue 2.0官網關於過渡的章節,再到最終實現效果,心情十分愉悅,同

純JS、CSS3實現仿IOS訊息alert彈窗(警告框,確認框,提示框)。老鐵們,沒毛病。

簡潔,大方的ios彈窗風格。網上有很多關於alert 彈窗的栗子可以借鑑使用。本文章主要應用在移動端上面的彈窗實現。 在專案沒有應用到其他框架彈窗的基礎上, 此例項應該可以滿足大部分彈窗上的要求,可直接應用於專案之中。使用方法: 1、引入依賴的樣式檔案和指

Android 之仿活動時分秒倒計時

import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import an

Android京東仿首頁秒殺倒計時

xml配置 <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"

仿京東淘寶的秒殺倒計時實現

//菜鳥一枚請多指教 //這個是佈局檔案 <LinearLayout android:id="@+id/ll_xsqg" android:layout_width="match_parent" android:layout_height="wrap_conten

仿京東、天貓app的商品詳情頁的布局架構, 以及功能實現

enter layout 顯示 效果 寫上 idt theme brush 2.2.0 一、介紹 這個類是繼承自ImageView的,所以對於這個控件我們可以使用ImageView的所有屬性 二、使用準備, 在as 的 build.grade文件中寫上 compile ‘

iOS活動倒計時的兩種實現方式

ofo orm ren 年-月 ats omd string 分享 截圖 代碼地址如下:<br>http://www.demodashi.com/demo/11076.html 在做些活動界面或者限時驗證碼時, 經常會使用一些倒計時突出展現. 現提供兩種方