【Android筆記】Android 自定義 TextView 實現垂直漸變字體顏色(支持 XML 配置)

在這里插入圖片描述

Android 自定義 TextView 實現垂直漸變字體顏色(支持 XML 配置)

在 Android UI 設計中,字體顏色的漸變效果能讓界面看起來更加精致與現代。常見的漸變有從左到右、從上到下等方向,但 Android 的 TextView 默認并不支持垂直漸變。

本文將帶你從原理到實現,一步步完成一個支持 上到下顏色漸變TextView,并且支持在 XML 中直接配置漸變顏色,無須每次寫 Java 代碼去設置。

本文最終實現效果:文字顏色可從頂部到底部漸變,顏色、方向均可在 XML 中自定義,支持陰影效果,性能開銷低,可直接在項目中復用。


文章目錄

  • **Android 自定義 TextView 實現垂直漸變字體顏色(支持 XML 配置)**
    • 1. 漸變字體效果原理
    • 2. 自定義 VerticalGradientTextView(支持 XML 配置)
      • 2.1 添加自定義屬性
      • 2.2 編寫自定義 TextView 類
    • 3. 在 XML 中使用漸變字體 TextView
    • 4. 優化與擴展
      • 4.1 性能優化
      • 4.2 支持更多漸變類型
      • 4.3 與動畫結合
    • 總結


1. 漸變字體效果原理

在 Android 中,要實現漸變文字的關鍵是使用 Shader(著色器),其中 LinearGradient 是最常用的線性漸變工具。

LinearGradient 的構造函數如下:

LinearGradient(float x0, float y0, // 漸變起點坐標float x1, float y1, // 漸變終點坐標int color0,         // 起始顏色int color1,         // 結束顏色Shader.TileMode tile
)

當我們把 LinearGradient 設置給 TextViewPaint 時,文字在繪制時就會自動按照漸變色進行渲染。

例如,如果我們想要讓文字從紅色漸變到藍色,由上到下,可以這么寫:

Shader shader = new LinearGradient(0, 0, 0, getHeight(),Color.RED,Color.BLUE,Shader.TileMode.CLAMP
);
paint.setShader(shader);

Shader.TileMode.CLAMP 表示漸變會被拉伸填充到末端,不會重復或鏡像。


2. 自定義 VerticalGradientTextView(支持 XML 配置)

為了讓漸變文字可以在布局 XML 中直接配置,我們需要自定義一個 TextView,并且支持讀取自定義屬性(startColorendColorgradientOrientation)。


2.1 添加自定義屬性

首先,在 res/values/attrs.xml 中定義漸變顏色相關的屬性:

<resources><declare-styleable name="VerticalGradientTextView"><!-- 漸變起始顏色 --><attr name="startColor" format="color" /><!-- 漸變結束顏色 --><attr name="endColor" format="color" /><!-- 漸變方向:vertical(默認)、horizontal --><attr name="gradientOrientation" format="enum"><enum name="vertical" value="0" /><enum name="horizontal" value="1" /></attr></declare-styleable>
</resources>

這樣,XML 中就可以像設置 android:textColor 一樣設置漸變顏色。


2.2 編寫自定義 TextView 類

package com.example.gradienttextview;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;import androidx.appcompat.widget.AppCompatTextView;public class VerticalGradientTextView extends AppCompatTextView {private int startColor;private int endColor;private int orientation; // 0: vertical, 1: horizontalpublic VerticalGradientTextView(Context context) {this(context, null);}public VerticalGradientTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public VerticalGradientTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.VerticalGradientTextView);startColor = ta.getColor(R.styleable.VerticalGradientTextView_startColor, 0xFFFF4081);endColor = ta.getColor(R.styleable.VerticalGradientTextView_endColor, 0xFF3F51B5);orientation = ta.getInt(R.styleable.VerticalGradientTextView_gradientOrientation, 0);ta.recycle();}@Overrideprotected void onDraw(Canvas canvas) {Paint paint = getPaint();Shader shader;if (orientation == 0) {// 垂直漸變shader = new LinearGradient(0, 0, 0, getHeight(),startColor,endColor,Shader.TileMode.CLAMP);} else {// 水平漸變shader = new LinearGradient(0, 0, getWidth(), 0,startColor,endColor,Shader.TileMode.CLAMP);}paint.setShader(shader);super.onDraw(canvas);}
}

3. 在 XML 中使用漸變字體 TextView

創建布局文件 activity_main.xml,直接使用我們的自定義控件:

<com.example.gradienttextview.VerticalGradientTextViewandroid:layout_width="112dp"android:layout_height="40dp"android:text="示例文本"android:textSize="28sp"android:gravity="center"android:shadowColor="#40000000"android:shadowDx="0dp"android:shadowDy="4dp"android:shadowRadius="3.0"app:startColor="#FF4081"app:endColor="#3F51B5"app:gradientOrientation="vertical"/>

這樣,文字就會從粉紅色(#FF4081)到藍色(#3F51B5)垂直漸變,并且保留陰影效果。


4. 優化與擴展

4.1 性能優化

  • onDraw() 中每次都會創建 LinearGradient,對于頻繁重繪的場景(如動畫)可能會增加開銷。可以將 LinearGradient 緩存到成員變量,并在 onSizeChanged() 時重新計算。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);updateShader(w, h);
}private void updateShader(int w, int h) {if (orientation == 0) {shader = new LinearGradient(0, 0, 0, h, startColor, endColor, Shader.TileMode.CLAMP);} else {shader = new LinearGradient(0, 0, w, 0, startColor, endColor, Shader.TileMode.CLAMP);}
}

這樣 onDraw() 里只需要 paint.setShader(shader);,無需每次創建對象。


4.2 支持更多漸變類型

  • 多色漸變:LinearGradient 支持傳入顏色數組和對應位置數組,可以實現三色或更多顏色漸變。
  • 角度漸變:通過計算不同的起止坐標,可以實現任意角度漸變。

4.3 與動畫結合

漸變字體可以和 ValueAnimator 結合,讓顏色動態變化,實現炫酷的標題效果。

ValueAnimator animator = ValueAnimator.ofArgb(Color.RED, Color.BLUE);
animator.addUpdateListener(animation -> {startColor = (int) animation.getAnimatedValue();invalidate();
});
animator.setDuration(2000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.start();

總結

通過以上步驟,我們實現了一個:

  • 支持 XML 配置漸變顏色和方向
  • 保持陰影效果
  • 性能優化可選
  • 可擴展為多色漸變和動畫

垂直漸變字體 TextView

無論是用于游戲 UI、主題標題,還是特殊提示文字,都可以讓界面更具視覺沖擊力,同時保持代碼的靈活性與可維護性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92896.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92896.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CANopen Magic調試軟件使用

一、軟件安裝與硬件連接1.1 系統要求操作系統&#xff1a;Windows 7/10/11 (64位)硬件接口&#xff1a;支持Vector/PEAK/IXXAT等主流CAN卡推薦配置&#xff1a;4GB內存&#xff0c;2GHz以上CPU1.2 安裝步驟運行安裝包CANopen_Magic_Setup.exe選擇安裝組件&#xff08;默認全選&…

前端css學習筆記3:偽類選擇器與偽元素選擇器

本文為個人學習總結&#xff0c;如有謬誤歡迎指正。前端知識眾多&#xff0c;后續將繼續記錄其他知識點&#xff01; 目錄 前言 一、偽類選擇器 1.概念 2.動態選擇器&#xff08;用戶交互&#xff09; 3.結構偽類 &#xff1a;first-child&#xff1a;選擇所有兄弟元素的…

深入探索 PDF 數據提取:PyMuPDF 與 pdfplumber 的對比與實戰

在數據處理和分析領域&#xff0c;PDF 文件常常包含豐富的文本、表格和圖形信息。然而&#xff0c;從 PDF 中提取這些數據并非易事&#xff0c;尤其是當需要保留格式和顏色信息時。幸運的是&#xff0c;Python 社區提供了多個強大的庫來幫助我們完成這項任務&#xff0c;其中最…

Springboot注冊過濾器的三種方式(Order 排序)

一、使用 Component Order&#xff08;簡單但不夠靈活&#xff09; 適用于全局過濾器&#xff0c;無需手動注冊&#xff0c;Spring Boot 會自動掃描并注冊。 Component Order(1) // 數字越小&#xff0c;優先級越高 public class AuthFilter implements Filter {Autowired /…

電腦硬件詳解

前幾天我的風扇轉的很快&#xff0c;而且cpu占用率很高&#xff0c;然后我在想怎么回事&#xff0c;然后就淺淺研究了一下電腦的硬件。 筆記本主板&#xff1a; 臺式機主板&#xff1a; 圖1&#xff1a; 圖2&#xff1a; 電腦硬件詳解 電腦的硬件是組成計算機系統的物理設…

力扣47:全排列Ⅱ

力扣47:全排列Ⅱ題目思路代碼題目 給定一個可包含重復數字的序列 nums &#xff0c;按任意順序 返回所有不重復的全排列。 思路 又是任意順序和所有不重復的排列&#xff0c;顯而易見我們要使用回溯的辦法。 首先是回溯的結束條件即新數組的長度等于nums的長度。這道題的難點…

學習筆記091——如何實現web登錄時,密碼復雜度校驗?(后端)

1、創建工具類 /*** 密碼復雜度校驗* param password 密碼*/ public static void validatePassword(String password) {// 至少8位if (password.length() < 8) {throw new IllegalArgumentException("密碼長度至少為8位");}// 包含大小寫字母if (!password.matche…

雪花算法snowflake分布式id生成原理詳解,以及對解決時鐘回撥問題幾種方案討論

一、前言在日趨復雜的分布式系統中&#xff0c;數據量越來越大&#xff0c;數據庫分庫分表是一貫的垂直水平做法&#xff0c;但是需要一個全局唯一ID標識一條數據或者MQ消息&#xff0c;數據庫id自增就顯然不能滿足要求了。因為場景不同&#xff0c;分布式ID需要滿足以下幾個條…

【PCB設計經驗】去耦電容如何布局?

0805 和 0603 以及更小 封裝的電容用作于對中高頻的去耦,其擺放位置是有要求的: 一、建議盡可能的靠近主控芯片的 電源管腳放置。 二、使用較寬和短的引線連接到電源和地過孔可以采用如下 圖 4–1 中的圖 ( 2 )、( 3)、 ( 4 )任意一種方式,避免使用長線或者較細的…

自動化運維實驗

目錄 一、實驗拓撲 二、實驗目的 三、實驗步驟 實驗思路&#xff1a; 代碼部分&#xff1a; 四、實驗結果&#xff1a; 一、實驗拓撲 二、實驗目的 利用python腳本&#xff0c;在本地&#xff0c;或者虛擬機里實現&#xff0c;設備CRC數量統計&#xff0c;并輸出成表格 三、實驗…

Wed前端第二次作業

一、作業1&#xff1a;完成自己學校的官網&#xff0c;動忘內容直接貼&#xff0c;至少三個不同的頁面1、界面1&#xff08;1&#xff09;相關代碼<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&quo…

第5節 大模型分布式推理通信優化與硬件協同

前言 在分布式推理中,多設備(如GPU、CPU)之間的數據傳輸(通信)是連接計算的“橋梁”。如果通信效率低下,即使單設備計算能力再強,整體性能也會大打折扣。想象一下:如果工廠之間的物流卡車跑得比生產速度還慢,再多的工廠也無法提高整體產量。 本節將從最基礎的單設備內…

XGBoost 的適用場景以及與 CNN、LSTM 的區別

XGBoost 的核心優勢與適用場景XGBoost 是一種梯度提升決策樹算法&#xff0c;屬于集成學習方法。它在處理結構化/表格化數據方面表現極其出色&#xff0c;是 Kaggle 競賽和工業界廣泛應用的“冠軍”模型。其核心優勢和應用場景包括&#xff1a;1. 結構化/表格化數據數據形式&a…

快速設計簡單嵌入式操作系統(3):動手實操,基于STC8編寫單任務執行程序,感悟MCU指令的執行過程

引言 前面我們陸續學習了操作系統常見的基礎概念&#xff0c;接著簡單了解了一下8051單片機的內存結構和執行順序切換的相關概念。接下來&#xff0c;我們就開始進行實操&#xff0c;基于8051單片機STC8來編寫一個簡單的操作系統&#xff0c;這里我們先實現一個單任務的執行程…

Spring AI Alibaba - 聊天機器人快速上手

本節對應 Github&#xff1a;https://github.com/JCodeNest/JCodeNest-AI-Alibaba/tree/master/spring-ai-alibaba-helloworld 本文將以阿里巴巴的通義大模型為例&#xff0c;通過 Spring AI Alibaba 組件&#xff0c;手把手帶你完成從零到一的構建過程&#xff1a;首先&#…

串口通信學習

不需要校驗位就選8位&#xff0c;需要校驗位就選9位&#xff01;USRTUSART框圖STM32的外設引腳這是USART的基本結構。數據幀&#xff0c;八位是這個公式還是很重要的&#xff01;如果在編輯器里面使用printf打印漢字的話&#xff0c;會出現亂碼的話&#xff0c;前提是你的編碼格…

面試經典150題[001]:合并兩個有序數組(LeetCode 88)

合并兩個有序數組&#xff08;LeetCode 88&#xff09; https://leetcode.cn/problems/merge-sorted-array/?envTypestudy-plan-v2&envIdtop-interview-150 1. 題目背景 你有兩個已經排好序的數組&#xff1a; nums1&#xff1a;前面是有效數字&#xff0c;后面是空位&…

快速安裝達夢8測試庫

計劃&#xff1a;數據庫名實例名PORT_NUMMAL_INST_DW_PORTMAL_HOSTMAL_PORTMAL_DW_PORTDMDWDBINST_1533615101192.168.207.612510135101*****[2025-08-11 15:14:34]***** Last login: Fri Jul 25 17:36:04 2025 from 192.168.88.48 [rootdm01 ~]# ip a 1: lo: <LOOPBACK,UP,…

Hive中優化問題

一、小文件合并優化Hive中的小文件分為Map端的小文件和Reduce端的小文件。(1)、Map端的小文件優化是通過CombineHiveInputFormat操作。相關的參數是&#xff1a;set hive.input.formatorg.apache.hadoop.hive.ql.io.CombineHiveInputFormat;(2)、Reduce端的小文件合并Map端的小…

tlias智能學習輔助系統--Maven高級-繼承

目錄 一、打包方式與應用場景 二、父子工程繼承關系 1. 父工程配置 2. 子工程配置 三、自定義屬性與引用屬性 1. 定義屬性 2. 在 dependencyManagement 中引用 3. 子工程中引用 四、dependencyManagement 與 dependencies 的區別 五、項目結構示例 六、小結 在實際開…