Android自定義view-打造酷炫的字型滑動高亮控制元件
前言:
相信很多時候開發會遇到類似於音樂歌詞同步,播放到哪句歌詞的哪個詞時會逐漸高亮,這樣的描述還是不夠準確,iPhone的滑動解鎖的那種效果,相信很多人都會熟悉吧。今天,我們的首要任務就是開發一個類似於這種效果的安卓控制元件,以便在以後的專案中直接使用,看起來高大上有木有。其實也不用害怕,需要我們分析和撰寫的內容並不多,廢話不多說,開始我們今天的教程吧。
正文:
在開始講解之前,需要準備的知識點有:
- 必要的安卓基礎
- 安卓view 的執行流程
- Android畫筆的LinearGradient線性渲染
- 執行構造方法
- onFinishInflate
- onSizeChanged
- onDraw
- ....
public LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions,Shader.TileMode tile)
引數:
float x0: 漸變起始點x座標
float y0:漸變起始點y座標
float x1:漸變結束點x座標
float y1:漸變結束點y座標
int[] colors:顏色 的int 陣列
float[] positions: 相對位置的顏色陣列,可為null, 若為null,可為null,顏色沿漸變線均勻分佈
Shader.TileMode tile: 渲染器平鋪模式
public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,Shader.TileMode tile)
float x0: 漸變起始點x座標
float y0:漸變起始點y座標
float x1:漸變結束點x座標
float y1:漸變結束點y座標
int color0: 起始漸變色
int color1: 結束漸變色
Shader.TileMode tile: 渲染器平鋪模式
Shader.TileMode有3種引數可供選擇,分別為CLAMP、REPEAT和MIRROR:
CLAMP的作用是如果渲染器超出原始邊界範圍,則會複製邊緣顏色對超出範圍的區域進行著色
REPEAT的作用是在橫向和縱向上以平鋪的形式重複渲染點陣圖
MIRROR的作用是在橫向和縱向上以映象的方式重複渲染點陣圖
知識準備已經完成了,開始動手擼程式碼了。
public class HightLightTextView extends TextView
Step2:重寫三個構造方法,當然根據需要,重寫一個兩個引數的構造方法也行。我複寫三個是為了以後能夠使用自定義屬性。
// 構造方法 public HightLightTextView(Context context) { this(context, null); } public HightLightTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public HightLightTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
Step3:在onSizeChanged方法中初始化引數。
/**
* view的呼叫過程:構造方法->onFinishInflate->onSizeChanged->onDraw
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 獲取view的寬度,初始化畫筆等初始屬性
if (mTextViewWidth == 0) {
mTextViewWidth = getMeasuredWidth();
// 如果寬度大於0的話,則初始化
if (mTextViewWidth > 0) {
// 初始化畫筆
mPaint = getPaint();
// 線性渲染
mLinearGradient = new LinearGradient(-mTextViewWidth, 0, 0, 0, new int[] { 0X55FFFFFF, 0XFFFFFFFF, 0X55FFFFFF }, new float[] { 0, 0.5f, 1 }, TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
matrix = new Matrix();
}
}
}
這裡有個細節,就是畫筆的獲取,我們不是new出來的,而是通過getPaint()獲取父類中的畫筆,所以接下來的onDraw中沒有用到paint,不要懷疑程式碼有問題哦。 至於LinearGradient的每個引數對照我們的知識準備應該不難理解各種引數對應的意思。那麼,還剩下一個問題,這裡的mTextViewWidth為什麼是負的,喏,其實我們的matrix的移動是從-mTextViewWidth<=translate<=mTextViewWidth,可能還是不能理解吧。我們到下面畫個圖解釋一下就清楚了。 Step4:在onDraw中繪製view
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isAnimateOn && matrix != null) {
mTranslateX += mTextViewWidth / 10;
// 如果移動的距離大於兩倍的寬度,則重新開始移動
if (mTranslateX > 2 * mTextViewWidth) {
mTranslateX = -mTextViewWidth;
}
// 平移matrix
matrix.setTranslate(mTranslateX, 0);
// 設定線性變化的matrix
mLinearGradient.setLocalMatrix(matrix);
// 延遲100ms重繪
postInvalidateDelayed(100);
}
}
其實我們移動的就是藍色的matrix,移動了兩倍的textview之後,再重置matrix,然後就postInvalidateDelayed繪製我們的view。okay了,看到這裡應該很熟悉怎麼去寫這樣的一個效果了吧。如果你覺得滑動慢,改變一些重繪的時間,如果你覺得顏色需要改變,那就設定對外的介面,或者直接修改view裡的顏色即可,至於擴充套件,留給大家擴充套件了。 這裡貼上view 的全部程式碼以及如何使用: HightLightTextView.java
package com.beyole.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.widget.TextView;
public class HightLightTextView extends TextView {
// 儲存view的寬度
private int mTextViewWidth = 0;
// 畫筆
private Paint mPaint;
// 線性渲染
private LinearGradient mLinearGradient;
// 儲存變換的matrix
private Matrix matrix;
// 移動距離
private int mTranslateX = 0;
// 是否開啟動畫
private boolean isAnimateOn = true;
// 構造方法
public HightLightTextView(Context context) {
this(context, null);
}
public HightLightTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HightLightTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* view的呼叫過程:構造方法->onFinishInflate->onSizeChanged->onDraw
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 獲取view的寬度,初始化畫筆等初始屬性
if (mTextViewWidth == 0) {
mTextViewWidth = getMeasuredWidth();
// 如果寬度大於0的話,則初始化
if (mTextViewWidth > 0) {
// 初始化畫筆
mPaint = getPaint();
// 線性渲染
mLinearGradient = new LinearGradient(-mTextViewWidth, 0, 0, 0, new int[] { 0X55FFFFFF, 0XFFFFFFFF, 0X55FFFFFF }, new float[] { 0, 0.5f, 1 }, TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
matrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isAnimateOn && matrix != null) {
mTranslateX += mTextViewWidth / 10;
// 如果移動的距離大於兩倍的寬度,則重新開始移動
if (mTranslateX > 2 * mTextViewWidth) {
mTranslateX = -mTextViewWidth;
}
// 平移matrix
matrix.setTranslate(mTranslateX, 0);
// 設定線性變化的matrix
mLinearGradient.setLocalMatrix(matrix);
// 延遲100ms重繪
postInvalidateDelayed(100);
}
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/demo"
>
<com.beyole.view.HightLightTextView
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dip"
android:textSize="22sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="滑動解鎖" />
</RelativeLayout>
好了,教程到此為止結束了。
相關推薦
Android自定義view-打造酷炫的字型滑動高亮控制元件
前言: 相信很多時候開發會遇到類似於音樂歌詞同步,播放到哪句歌詞的哪個詞時會逐漸高亮,這樣的描述還是不夠準確,iPhone的滑動解鎖的那種效果,相信很多人都會熟悉吧。今天,我們的首要任務就是開發一個類似於這種效果的安卓控制元件,以便在以後的專案中直接使用,看起來高大上有木有
Android 自定義View實現動態炫酷按鈕
普通按鈕也就那麼幾種樣式,看著都審美疲勞,先放效果圖,演示Demo+原始碼在最後面 你會不會以為這個按鈕是集結了很多動畫的產物,我告訴你,並沒有。所有的實現都是基於自定義View,採用最底層的onDraw一點一點的畫出來的。沒有采用一丁點的動畫。雖然演示時間很短,但是要
android自定義view-打造圓形ImageView(一)
package com.beyole.view; import com.beyole.roundimageview.R; import android.content.Context; import android.content.res.TypedArray; import android.graphi
android自定義view-打造圓形ImageView(四)終結篇
package com.beyole.view; import java.lang.ref.WeakReference; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitm
android自定義view-打造圓形ImageView(二)
package com.beyole.view; import java.lang.ref.WeakReference; import android.content.Context; import android.content.res.TypedArray; import android.graphi
android自定義View打造自己的專屬控制元件——風車控制元件
Android 自定義View——打造自己的專屬控制元件 前段時間看到一個天氣應用,介面做的很好看。裡面一個風車轉動動畫和一個日出日落的動畫挺有意思的,於是自己也照著他的介面做了一個。 先看一下介面 自定義View一般有兩種情況 繼承自原有控制元件
Android自定義View,實現全屏滑動的DrawerLayout
對與DrawerLayout大家應該用過,是Google官方推出的一種抽屜式導航控制元件。開啟左右兩邊選單的方式是從手機屏 幕的邊緣處滑動來觸發,不過總有些**的需求要讓它可以全屏滑動觸發選單,網上也有一些解決辦法,無非就是用 setDrawerLeftE
Android自定義View之實現簡單炫酷的球體進度球
前言 最近一直在研究自定義view,正好專案中有一個根據下載進度來實現球體進度的需求,所以自己寫了個進度球,程式碼非常簡單。先看下效果: 效果還是非常不錯的。 準備知識 要實現上面的效果我們只要掌握兩個知識點就好了,一個是Handler機制,用於發訊息重新整理我們的進度球,一個是clip
Android自定義View實現炫酷的主題切換動畫(仿酷安客戶端)
前兩日偶然看到了一個很炫酷的動畫效果: 判斷它是不是用的ValueAnimator, 如果是的話, 我們可以在設定-開發者選項裡面設定 “動畫時長縮放”來改變動畫時長. 所以這次我們通過設定這個選項, 把動畫速度降低之後, 很快就看出了其中的奧妙
Android自定義view(一),打造絢麗的驗證碼
前言:我相信信念的力量,信念可以支撐起一個人,一個名族,一個國家。正如“人沒有夢想和鹹魚有什麼區別”一樣,我有信念,有理想,所以我正在努力向著夢想前進~。 自定義view,如果是我,我首先要看到自定義view的效果圖,然後再想想怎麼實現這種效果或功能,所以先貼
android自定義view實現字型變色
上次看了鴻洋的部落格,其中有一篇部落格實現的是字型逐漸變色的效果,不過其使用的是clipRect實現的,今天給大家帶來另一種實現方式,通過XferMode來實現。先看效果吧。 先說下實現原理:我們首先繪製當前顯示的文字內容,然後設定xfermode的值為P
手把手教你打造一個心電圖效果View Android自定義View
大家好,看我像不像蘑菇…因為我在學校呆的發黴了。 思而不學則殆 麗麗說得對,我有奇怪的疑問,大都是思而不學造成的,在我書讀不夠的情況下想太多,大多等於白想,所以革命沒成功,同志仍需努力。 好了廢話不說了,由於布總要做一個心電圖的玩意,所以做來練練手
Android 自定義View
wid declare created odi lex getwidth 實現 tdi led 最近在看鴻洋大神的博客,在看到自定義部分View部分時,想到之前案子中經常會要用到"圖片 + 文字"這類控件,如下圖所示: 之前的做法是在布局文件中,將一個Imag
Android自定義view詳解
this boolean mar 處理 都是 並且 jdk text 命名 從繼承開始 懂點面向對象語言知識的都知道:封裝,繼承和多態,這是面向對象的三個基本特征,所以在自定義View的時候,最簡單的方法就是繼承現有的View 通過上面這段代碼,我定義了一個Ske
Android -- 自定義view實現keep歡迎頁倒計時效果
super onfinish -m use new getc awt ttr alt 1,最近打開keep的app的時候,發現它的歡迎頁面的倒計時效果還不錯,所以打算自己來寫寫,然後就有了這篇文章。 2,還是老規矩,先看一下我們今天實現的效果 相較於我們常見的倒計時
Android自定義View效果目錄
class 重寫 自定義 textview 居中 url 冒泡 and 雷達圖 1、絢麗的loading動效的實現 2、Android自定義View:進度條+冒泡文本 3、Android雷達圖(蜘蛛網圖) 4、Android文本閃爍 5、Android繪制圓形進度條 6、重
Android自定義View——實現水波紋效果類似剩余流量球
string 三個點 pre ber block span 初始化 move 理解 最近突然手癢就想搞個貝塞爾曲線做個水波紋效果玩玩,終於功夫不負有心人最後實現了想要的效果,一起來看下吧: 效果圖鎮樓 一:先一步一步來分解一下實現的過程 需要繪制一個正弦曲線(sin
Android 自定義 View 知識點
移動 encode swe em1 red 鋸齒 枚舉類 map() tex 根據 Hencoder 提供的知識點,進行學習和總結。 三個要點: 布局 繪制 觸摸反饋 繪制 自定義繪制:由自己實現繪制過程 常用繪制方法 onDraw(Canvas canvas) 繪制
Android自定義view與activity的傳值
重復 轉動 自定義 activit 廣播 內部 代碼 view 等待 昨晚在寫團隊項目的時候,遇到一個問題,直到今天早上才解決。。。即在自定義view“轉盤”結束轉動後獲取結果的處理中,我是想吧值傳到activity中的一個textview中的,但我的自定義view類不是a
Android 自定義View - 助記詞
UI今天給了個需求,把亂序的單詞拼成一句話,如下圖: 本來計劃是用ViewGroup+TextView寫的,突然腦子抽了想用paint來畫(寫完就後悔了-.-) 先看一下完成後的效果 前期的思路是這樣的: 1.測量每個單詞的高度和寬度,計算出所有單詞排列後的高*2,就是view