IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 自定义View-一个能定义shape的View -> 正文阅读

[移动开发]自定义View-一个能定义shape的View

每次给View加shape时都要写一堆的drawable文件,不容易管理,所以封装一下。

大体效果是这样的:

可以定义的属性有5种形状(shape_type),边线颜色(shape_line_color),边线宽度(shape_line_width),圆角矩形的角度(shape_radius),是否填充中间(shape_solid),填充中间颜色(shape_solid_color,该属性在shape_solid为true时生效)。

具体代码:

<com.ycq.ycqlibrary.view.ShapeView
            android:layout_width="200dp"
            android:layout_height="60dp"
            android:layout_marginLeft="10dp"
            android:gravity="center"
            android:layout_marginTop="10dp"
            android:text="你好,世界"
            android:textSize="30sp"
            app:shape_line_color="@color/purple_200"
            app:shape_line_width="4dp"
            app:shape_radius="4dp"
            app:shape_solid="true"
            app:shape_solid_color="@color/read"
            app:shape_type="both_circle" />

?下边是全部的代码:

package com.ycq.ycqlibrary.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import com.ycq.ycqlibrary.R

/**
 * 标签View,主要解决各种各样的View的外框
 * 目前有:
 * 圆角矩形 rectangle
 * 圆形 circle
 * 左半圆+右圆角矩形 left_circle
 * 右半圆+左圆角矩形 right_circle
 * 两边半圆+中间矩形 both_circle
 */
class ShapeView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
    androidx.appcompat.widget.AppCompatTextView(context, attrs, defStyleAttr) {
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, -1)

    constructor(context: Context) : this(context, null)


    companion object {
        const val rectangle = 0
        const val circle = 1
        const val left_circle = 2
        const val right_circle = 3
        const val both_circle = 4
        const val default_line_width = 1f
        const val default_radius = 5f
    }


    private var shapeType: Int = 0
    private var shapeSolid: Boolean = false
    private var shapeSolidColor: Int = Color.parseColor("#FFFFFF")
    private var shapeLineWidth: Float = default_line_width
    private var shapeLineColor: Int = Color.parseColor("#FFFFFF")
    private var shapeRadius: Float = default_radius

    private val paint: Paint = Paint()
    private var halfLineWidth = 0f

    init {
        initView(context, attrs)
        initPaint()
        halfLineWidth = shapeLineWidth / 2
    }

    private fun initPaint() {
        paint.apply {
            isAntiAlias = true
            strokeWidth = shapeLineWidth
            color = shapeLineColor
            //画笔样式
            style = Paint.Style.STROKE
            //拐角风格
            strokeJoin = Paint.Join.ROUND
            //笔锋样式
            strokeCap = Paint.Cap.ROUND
        }
    }

    @SuppressLint("CustomViewStyleable")
    private fun initView(context: Context, attrs: AttributeSet?) {
        val obtain = context.obtainStyledAttributes(attrs, R.styleable.ShapeView)
        shapeType = obtain.getInt(R.styleable.ShapeView_shape_type, rectangle)
        shapeSolid = obtain.getBoolean(R.styleable.ShapeView_shape_solid, false)
        shapeSolidColor =
            obtain.getColor(R.styleable.ShapeView_shape_solid_color, Color.parseColor("#FFFFFF"))
        shapeLineWidth =
            obtain.getDimension(R.styleable.ShapeView_shape_line_width, default_line_width)
        shapeLineColor =
            obtain.getInt(R.styleable.ShapeView_shape_line_color, Color.parseColor("#FFFFFF"))
        shapeRadius = obtain.getDimension(R.styleable.ShapeView_shape_radius, default_radius)
        obtain.recycle()
    }

    private var viewWidth = 0
    private var viewHeight = 0
    private var halfViewWidth = 0f
    private var halfViewHeight = 0f
    private var rectF: RectF = RectF(0f, 0f, 0f, 0f)
    private var leftRectF: RectF = RectF(0f, 0f, 0f, 0f)
    private var rightRectF: RectF = RectF(0f, 0f, 0f, 0f)
    private var centerRectF: RectF = RectF(0f, 0f, 0f, 0f)

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        viewWidth = w
        viewHeight = h
        halfViewWidth = (viewWidth / 2).toFloat()
        halfViewHeight = (viewHeight / 2).toFloat()

        //圆角矩形
        rectF.apply {
            left = halfLineWidth
            top = halfLineWidth
            right = viewWidth - halfLineWidth
            bottom = viewHeight - halfLineWidth
        }
        //画左边半圆时的矩形
        leftRectF.apply {
            left = halfLineWidth
            top = halfLineWidth
            right = viewHeight - halfLineWidth
            bottom = viewHeight - halfLineWidth
        }
        //画右边圆时的矩形
        rightRectF.apply {
            left = viewWidth - halfLineWidth - viewHeight
            top = halfLineWidth
            right = viewWidth - halfLineWidth
            bottom = viewHeight - halfLineWidth
        }
        //画两边圆时中间矩形
        centerRectF.apply {
            left = halfViewHeight - halfLineWidth
            top = shapeLineWidth
            right = viewWidth - halfViewHeight
            bottom = viewHeight - shapeLineWidth
        }
    }

    override fun onDraw(canvas: Canvas) {
        when (shapeType) {
            rectangle -> {
                drawRectangle(canvas)
            }
            circle -> {
                drawCircle(canvas)
            }
            left_circle -> {
                drawLeftCircle(canvas)
            }
            right_circle -> {
                drawRightCircle(canvas)
            }
            both_circle -> {
                drawBothCircle(canvas)
            }

        }

        super.onDraw(canvas)
    }

    private fun drawRectangle(canvas: Canvas) {
        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
            }
            canvas.drawRoundRect(rectF, shapeRadius, shapeRadius, paint)
        }
        paint.apply {
            color = shapeLineColor
            style = Paint.Style.STROKE
        }
        canvas.drawRoundRect(rectF, shapeRadius, shapeRadius, paint)
    }

    private fun drawCircle(canvas: Canvas) {
        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
            }
            canvas.drawCircle(
                halfViewWidth,
                halfViewWidth,
                halfViewWidth - halfLineWidth,
                paint
            )
        }
        paint.apply {
            color = shapeLineColor
            style = Paint.Style.STROKE
        }
        canvas.drawCircle(
            halfViewWidth,
            halfViewWidth,
            halfViewWidth - halfLineWidth,
            paint
        )
    }

    /**
     * 先用linecolor绘制出界面,再用solidcolor绘制出界面,留出linewidth的宽度
     * @param canvas Canvas
     */
    private fun drawLeftCircle(canvas: Canvas) {

        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
            }
        } else {
            paint.apply {
                style = Paint.Style.FILL
                color = Color.parseColor("#FFFFFF")
            }
        }
        canvas.drawCircle(
            halfViewHeight,
            halfViewHeight,
            halfViewHeight - halfLineWidth,
            paint
        )
        centerRectF.apply {
            left = halfViewHeight
            top = halfLineWidth
            right = viewWidth - halfLineWidth
            bottom = viewHeight - halfLineWidth
        }
        canvas.drawRoundRect(centerRectF, shapeRadius, shapeRadius, paint)

        paint.apply {
            style = Paint.Style.STROKE
            color = shapeLineColor
        }
        canvas.drawArc(leftRectF, 90f, 180f, false, paint)
        canvas.drawRoundRect(centerRectF, shapeRadius, shapeRadius, paint)


        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
                strokeCap = Paint.Cap.BUTT
            }
        } else {
            paint.apply {
                style = Paint.Style.FILL
                color = Color.parseColor("#FFFFFF")
                strokeCap = Paint.Cap.BUTT
            }
        }
        canvas.drawLine(
            halfViewHeight,
            shapeLineWidth,
            halfViewHeight,
            viewHeight - shapeLineWidth,
            paint
        )

    }

    /**
     * 先绘制填充色(整圆+圆角矩形),在绘制边线(圆弧+原件矩形),在绘制一条线,覆盖多出来的那条线
     * @param canvas Canvas
     */
    private fun drawRightCircle(canvas: Canvas) {


        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
            }
        } else {
            paint.apply {
                style = Paint.Style.FILL
                color = Color.parseColor("#FFFFFF")
            }
        }
        canvas.drawCircle(
            viewWidth - halfViewHeight,
            halfViewHeight,
            halfViewHeight - halfLineWidth,
            paint
        )
        centerRectF.apply {
            left = halfLineWidth
            top = halfLineWidth
            right = viewWidth - halfViewHeight - halfLineWidth
            bottom = viewHeight - halfLineWidth
        }
        canvas.drawRoundRect(centerRectF, shapeRadius, shapeRadius, paint)


        paint.apply {
            style = Paint.Style.STROKE
            color = shapeLineColor
        }
        canvas.drawArc(rightRectF, 270f, 180f, true, paint)
        canvas.drawRoundRect(centerRectF, shapeRadius, shapeRadius, paint)

        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
                strokeCap = Paint.Cap.BUTT
            }
        } else {
            paint.apply {
                style = Paint.Style.FILL
                color = Color.parseColor("#FFFFFF")
                strokeCap = Paint.Cap.BUTT
            }
        }
        canvas.drawLine(
            viewWidth - halfViewHeight - halfLineWidth,
            shapeLineWidth,
            viewWidth - halfViewHeight - halfLineWidth,
            viewHeight - shapeLineWidth,
            paint
        )
    }

    /**
     *先绘制填充色(整圆+圆角矩形),在绘制边线(圆弧+原件矩形),在绘制一条线,覆盖多出来的那条线
     * @param canvas Canvas
     */
    private fun drawBothCircle(canvas: Canvas) {
        if (shapeSolid) {
            paint.apply {
                style = Paint.Style.FILL
                color = shapeSolidColor
            }
            canvas.drawArc(leftRectF, 90f, 180f, true, paint)
            canvas.drawArc(rightRectF, 270f, 180f, true, paint)
            canvas.drawRect(centerRectF, paint)
        }

        paint.apply {
            color = shapeLineColor
            style = Paint.Style.STROKE
        }
        canvas.drawArc(leftRectF, 90f, 180f, false, paint)
        canvas.drawArc(rightRectF, 270f, 180f, false, paint)
        canvas.drawLine(
            halfViewHeight - halfLineWidth,
            halfLineWidth,
            viewWidth - halfViewHeight,
            halfLineWidth,
            paint
        )
        canvas.drawLine(
            halfViewHeight - halfLineWidth,
            viewHeight - halfLineWidth,
            viewWidth - halfViewHeight,
            viewHeight - halfLineWidth,
            paint
        )
    }
}
<declare-styleable name="ShapeView">
        <attr name="shape_type" format="enum">
            <enum name="rectangle" value="0" />
            <enum name="circle" value="1" />
            <enum name="left_circle" value="2" />
            <enum name="right_circle" value="3" />
            <enum name="both_circle" value="4" />
        </attr>
        <attr name="shape_solid" format="boolean" />
        <attr name="shape_solid_color" format="color" />
        <attr name="shape_line_width" format="dimension" />
        <attr name="shape_line_color" format="color" />
        <attr name="shape_radius" format="dimension" />
    </declare-styleable>

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:40:21  更:2021-09-24 10:42:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:09:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码