【5年Android從零覆盤系列之八】Android自定義View(3):衍生/擴充套件式
阿新 • • 發佈:2021-01-06
技術標籤:Androidandroid自定義ViewTextView跑馬燈效果多個textview跑馬燈View的生命週期
1.簡述
簡而言之,即 如繼承TextView,修改預設background、marquee狀態時,elevation值、取消預設最小高度等。
2.前提基礎
瞭解View的生命週期,關聯Activity聯動時的函式呼叫順序
- 【View】構造方法
- 【View】onFinishInflate()
- 【Activity】 onCreate()
- 【Activity】onStart()
- 【Activity】onResume()
- 【View】onAttachedToWindow()
- 【View】onMeasure() (可能呼叫n次)
- 【View】onSizeChanged() (可能呼叫n次)
- 【View】onLayout() (可能呼叫n次)
- 【View】onDraw() (可能呼叫n次)
- 【View】onWindowFocusChanged() (呼叫Activity.onPause()前,被呼叫,hasWindowFocus==false)
- 【Activity】onPause()
- 【Activity】onStop()
- 【Activity】onDestroy()
- 【View】onDetachedFromWindow
可參考 : Android自定義View(1):基礎
細節注意:
執行時,動態更新View的兩種方法區別
1.invalidate():
簡單重繪View:如更新其文字、顏色、狀態等。只調用onDraw()方法。
2.requestLayout():
可約等於視為完全重繪整個View,因為該方法呼叫後,會從onMeasure()開始更新View
3. 實踐
改寫內容見程式碼備註
3.1 自定義View類
package com.cupster.base_super_resource;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics. Color;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class AlwaysMarqueeTextView extends TextView {
public AlwaysMarqueeTextView(Context context) {
super(context);
initExTool(context , null);
}
public AlwaysMarqueeTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initExTool(context ,attrs);
}
public AlwaysMarqueeTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initExTool(context ,attrs);
}
public AlwaysMarqueeTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initExTool(context ,attrs);
}
//========================================================================
//============================ 擴充套件1 =================================
//========================================================================
//重置父類判斷跑馬燈滾動條件1
@Override
public boolean isFocused() {
return true;
}
//重置父類判斷跑馬燈滾動條件2
@Override
public void setSelected(boolean selected) {
super.setSelected(true);
}
//========================================================================
//============================ 擴充套件2 =================================
//========================================================================
private Paint mPaint;
private int underColor = -1;
private void initExTool(Context context ,AttributeSet attrs){
mPaint = new Paint();
if (attrs == null){
mPaint.setColor(Color.BLUE);
}else {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AlwaysMarqueeTextView);
//取值
underColor= typedArray.getInt(R.styleable.AlwaysMarqueeTextView_under_color, Color.parseColor("#0000ff"));
//使用
mPaint.setColor(underColor);
//釋放
typedArray.recycle();
}
//----------------------
//------- 擴充套件3 ---------
//----------------------
initSetting();
}
@Override
protected void onDraw(Canvas canvas) {
//新增下劃線
super.onDraw(canvas);
mPaint.setColor(Color.GREEN);
canvas.drawLine( 0 ,getHeight()/2 ,getWidth() ,getHeight()/2 , mPaint);
}
//========================================================================
//============================ 擴充套件3 =================================
//========================================================================
private void initSetting() {
setEllipsize(TextUtils.TruncateAt.MARQUEE);//跑馬燈滾動
setMarqueeRepeatLimit(-1);//-1無限迴圈,1迴圈一次 ,n 迴圈n次
setSingleLine(true);
setHorizontallyScrolling(true);
setFocusable(true);
setFocusableInTouchMode(true);
}
}
3.2 自定義屬性
res/values/attrs.xml
<declare-styleable name="AlwaysMarqueeTextView">
<attr name="under_color" format="color" />
</declare-styleable>
3.3 佈局檔案中使用
<!-- <你的包名.AlwaysMarqueeTextView -->
<com.cupster.base_super_resource.AlwaysMarqueeTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:under_color="@android:color/holo_green_dark"
android:text="這是一個跑馬燈跑啊跑,滾啊滾,迴圈次數為無限次,textview擴充套件/改寫效果,總之當成事textview用就好了,"
/>