
自定义view绘制不规则圆角 渐变颜色 左右上角图标
CircularCornerColorGradientFragment类:
package com.example.androidkotlindemo2.circular
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PaintFlagsDrawFilter
import android.graphics.Path
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.core.graphics.toRectF
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.androidkotlindemo2.R
import com.example.androidkotlindemo2.databinding.CircularCornerColorGradientMainBinding
import com.example.androidkotlindemo2.utils.LogUtils
/**
* Author : wn
* Email : maoning20080809@163.com
* Date : 2024/9/7 11:29
* Description : 不规则圆角-颜色渐变
*/
class CircularCornerColorGradientFragment : Fragment(), View.OnClickListener{
private lateinit var binding : CircularCornerColorGradientMainBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = CircularCornerColorGradientMainBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.circularCornerColorGradientBtn4.setOnClickListener(this)
}
override fun onClick(v: View?) {
v?:return
if (v.id == R.id.circular_corner_color_gradient_btn4){
processRecyclerView()
}
}
private fun processRecyclerView(){
var width = getScreenWidth(requireActivity()) / 3
var list = mutableListOf<GradientBean>()
list.add(GradientDataUtils.getGradientData1(width))
list.add(GradientDataUtils.getGradientData2(width))
list.add(GradientDataUtils.getGradientData3(width))
var adapter = GradientAdapter(list)
binding.gradientRecyclerView?.let {
it.layoutManager = GridLayoutManager(requireActivity(), 3)
it.adapter = adapter
}
}
fun getScreenWidth(context: Context): Int {
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
return metrics.widthPixels
}
}
GradientAdapter类:
package com.example.androidkotlindemo2.circular
import android.widget.LinearLayout
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.example.androidkotlindemo2.MyApp
import com.example.androidkotlindemo2.R
import com.example.androidkotlindemo2.utils.LogUtils
/**
* Author : wn
* Email : maoning20080809@163.com
* Date : 2024/9/15 16:33
* Description : 不规则圆角-颜色渐变
*/
class GradientAdapter(list : MutableList<GradientBean>) : BaseQuickAdapter<GradientBean, BaseViewHolder>(layoutResId = R.layout.gradient_item, data = list){
override fun convert(holder: BaseViewHolder, item: GradientBean) {
LogUtils.d("AAA", "position : ${holder.layoutPosition}, ${item.leftUrl}")
var circularCornerColorGradientView = CircularCornerColorGradientView(MyApp.myApp)
circularCornerColorGradientView.setLeftUrl(item.leftUrl)
circularCornerColorGradientView.setRightUrl(item.rightUrl)
circularCornerColorGradientView.setBitmapScale(item.bitmapScale)
circularCornerColorGradientView.setStartColor(item.startColor)
circularCornerColorGradientView.setEndColor(item.endColor)
circularCornerColorGradientView.setGradientWidth(item.gradientWidth)
circularCornerColorGradientView.setGradientHeight(item.gradientHeight)
var itemLayout = holder.getView<LinearLayout>(R.id.gradient_item_layout)
itemLayout.addView(circularCornerColorGradientView)
}
}
CircularCornerColorGradientView类:
package com.example.androidkotlindemo2.circular
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PaintFlagsDrawFilter
import android.graphics.Path
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import androidx.annotation.Nullable
import androidx.core.graphics.toRectF
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.example.androidkotlindemo2.R
import com.example.androidkotlindemo2.utils.LogUtils
/**
* Author : wn
* Email : maoning20080809@163.com
* Date : 2024/9/7 11:54
* Description : 自定义颜色渐变+圆角+斜度view
*/
class CircularCornerColorGradientView : View {
constructor(context: Context) : this(context, null)
constructor(context: Context, attributeSet: AttributeSet?) :this(context, attributeSet, 0)
constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr){
}
private var paint = Paint()
/**
* 左上角图片
*/
private var leftBitmap : Bitmap? = null
/**
* 右上角图片
*/
private var rightBitmap : Bitmap? = null
/**
* 左上角图片地址
*/
private var leftUrl = ""
/**
* 右上角图片地址
*/
private var rightUrl = ""
/**
* 开始渐变颜色
*/
private var startColor = "#B303DAC5"
/**
* 结束渐变颜色
*/
private var endColor = "#B3FFFAFA"
/**
* 显示不规则图形宽度
*/
private var gradientWidth = resources.getDimensionPixelSize(R.dimen.dp_100)
/**
* 显示不规则图形高度
*/
private var gradientHeight = resources.getDimensionPixelSize(R.dimen.dp_50)
/**
* 左、右上角图片缩放比例
*/
private var scale = 0.5f
/**
* 左上角图片左边距
*/
private var leftBitmapLeftDistance = resources.getDimension(R.dimen.dp_10)
/**
* 左上角图片上边距
*/
private var leftBitmapTopDistance = resources.getDimension(R.dimen.dp_10)
/**
* 右上角图片右边距
*/
private var rightBitmapRightDistance = resources.getDimension(R.dimen.dp_10)
/**
* 右上角图片上边距
*/
private var rightBitmapTopDistance = resources.getDimension(R.dimen.dp_24)
/**
* 设置圆角的半径
*/
private val cornerRadius = resources.getDimensionPixelSize(R.dimen.dp_20)
fun setLeftUrl(leftUrl : String){
this.leftUrl = leftUrl
}
fun setRightUrl(rightUrl : String){
this.rightUrl = rightUrl
}
fun setStartColor(startColor : String){
this.startColor = startColor
}
fun setEndColor(endColor : String){
this.endColor = endColor
}
fun setBitmapScale(scale : Float){
this.scale = scale
}
/**
* 左上角图片左边距
*/
fun setLeftBitmapLeftDistance(leftBitmapLeftDistance : Float){
this.leftBitmapLeftDistance = leftBitmapLeftDistance
}
/**
* 左上角图片上边距
*/
fun setLeftBitmapTopDistance(leftBitmapTopDistance : Float){
this.leftBitmapTopDistance = leftBitmapTopDistance
}
/**
* 显示不规则图形宽度
*/
fun setGradientWidth(gradientWidth : Int){
this.gradientWidth = gradientWidth
}
/**
* 显示不规则图形高度
*/
fun setGradientHeight(gradientHeight : Int){
this.gradientHeight = gradientHeight
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//设置自定义view的宽度、高度
setMeasuredDimension(gradientWidth, gradientHeight)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvasBitmap(canvas)
//加载、绘制左上角图片
if(leftBitmap == null){
loadLeftBitmap()
} else {
leftBitmap?.let {
canvas.drawBitmap(it, leftBitmapLeftDistance, leftBitmapTopDistance, paint)
}
}
//加载、绘制右上角图片
if(rightBitmap == null){
loadRightBitmap()
} else {
rightBitmap?.let {
var rightDistance = (gradientWidth - it.width - rightBitmapRightDistance).toFloat()
canvas.drawBitmap(it, rightDistance, rightBitmapTopDistance, paint)
}
}
}
/**
* 等比压缩图片
*/
private fun zoomBitmap(bitmap: Bitmap) : Bitmap{
var width = bitmap.width.toFloat()
var height = bitmap.height.toFloat()
var resultWidth = (width * scale).toInt()
var resultHeight = (height * scale).toInt()
var resultBitmap = Bitmap.createScaledBitmap(bitmap, resultWidth, resultHeight, false)
return resultBitmap
}
/**
* 绘制渐变斜度-圆角
*/
private fun canvasBitmap(canvas: Canvas){
var originalBitmap = getOriginalBitmap()
LogUtils.i("AAA", "canvasBitmap : ${originalBitmap.width} , ${originalBitmap.height} , ${leftUrl} , ${rightUrl}")
var roundedCornerBitmap = getRoundedCornerBitmap3(originalBitmap, cornerRadius)
canvas.drawBitmap(roundedCornerBitmap, 0f, 0f, paint)
}
private fun getOriginalBitmap() : Bitmap{
val colors = intArrayOf(
Color.parseColor(startColor),
Color.parseColor(endColor)
)
//颜色渐变
val gradientDrawable = GradientDrawable()
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
gradientDrawable.orientation = GradientDrawable.Orientation.TOP_BOTTOM
gradientDrawable.colors = colors
// 创建一个等大小的空Bitmap
var bitmap = Bitmap.createBitmap(gradientWidth, gradientHeight, Bitmap.Config.ARGB_8888);
var canvas = Canvas(bitmap);
// 绘制Drawable到Bitmap
gradientDrawable.setBounds(0, 0, gradientWidth, gradientHeight);
gradientDrawable.draw(canvas);
return bitmap
}
/**
* 使用lineTo绘制圆角
*/
private fun createRoundedCornerPath3(rect: RectF, cornerRadius: Float): Path {
val path = Path()
path.moveTo(rect.left + cornerRadius, rect.top) // 起点在左上角
path.lineTo(rect.right - cornerRadius, rect.top+ cornerRadius*1) // 直线到右上角
// 使用quadTo方法添加圆角
path.quadTo(rect.right, rect.top+ cornerRadius*1, rect.right, rect.top + cornerRadius*2)
path.lineTo(rect.right, rect.bottom - cornerRadius)
path.quadTo(rect.right, rect.bottom, rect.right - cornerRadius, rect.bottom)
path.lineTo(rect.left + cornerRadius, rect.bottom)
path.quadTo(rect.left, rect.bottom, rect.left, rect.bottom - cornerRadius)
path.lineTo(rect.left, rect.top + cornerRadius)
path.quadTo(rect.left, rect.top, rect.left + cornerRadius, rect.top)
path.close()
return path
}
private fun getRoundedCornerBitmap3(bitmap: Bitmap, cornerRadius: Int): Bitmap {
val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
//canvas 设置抗锯齿
canvas.drawFilter = PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG)
val paint = Paint()
val rect = Rect(0, 0, bitmap.width, bitmap.height)
//是用来防止边缘的锯齿,
paint.isAntiAlias = true
//函数是用来对位图进行滤波处理
paint.isFilterBitmap = true
var path = createRoundedCornerPath3(rect.toRectF(), cornerRadius.toFloat())
canvas.drawPath(path, paint)
paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.SRC_IN))
canvas.drawBitmap(bitmap, rect, rect, paint)
return output
}
/**
* 获取左上角图片
*/
private fun loadLeftBitmap(){
if(TextUtils.isEmpty(leftUrl)){
return
}
Glide.with(context)
.asBitmap()
.load(leftUrl)
.into(object : SimpleTarget<Bitmap?>() {
override fun onResourceReady(
resource: Bitmap,
@Nullable transition: Transition<in Bitmap?>?
) {
leftBitmap = zoomBitmap(resource)
invalidate()
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
})
}
/**
* 获取右上角图片
*/
private fun loadRightBitmap(){
if(TextUtils.isEmpty(rightUrl)){
return
}
Glide.with(context)
.asBitmap()
.load(rightUrl)
.into(object : SimpleTarget<Bitmap?>() {
override fun onResourceReady(
resource: Bitmap,
@Nullable transition: Transition<in Bitmap?>?
) {
rightBitmap = zoomBitmap(resource)
invalidate()
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
})
}
}
GradientDataUtils类:
package com.example.androidkotlindemo2.circular
/**
* Author : wn
* Email : maoning20080809@163.com
* Date : 2024/9/15 16:58
* Description :
*/
object GradientDataUtils {
fun getGradientData1(width : Int) : GradientBean{
var gradientBean = GradientBean()
gradientBean.leftUrl = "https://img.duoziwang.com/2016/09/02/16135043775.jpg"
gradientBean.rightUrl = "https://img.woyaogexing.com/2016/03/18/c4df209cad1840bb%21200x200.jpg"
gradientBean.bitmapScale = 0.3f
gradientBean.startColor = "#B303DAC5"
gradientBean.endColor = "#B3FFFAFA"
gradientBean.gradientWidth = width
gradientBean.gradientHeight = (width * 0.6).toInt()
return gradientBean
}
fun getGradientData2(width : Int) : GradientBean{
var gradientBean = GradientBean()
gradientBean.leftUrl = "http://img.duoziwang.com/2016/11/21/13565441404.jpg"
gradientBean.rightUrl = "http://img.duoziwang.com/2016/11/29/220134634.jpg"
gradientBean.bitmapScale = 0.3f
gradientBean.startColor = "#B3BB86FC"
gradientBean.endColor = "#B3FFDEAD"
gradientBean.gradientWidth = width
gradientBean.gradientHeight = (width * 0.6).toInt()
return gradientBean
}
fun getGradientData3(width : Int) : GradientBean{
var gradientBean = GradientBean()
gradientBean.leftUrl = "https://tupian.qqw21.com/article/UploadPic/2018-3/20183817105179447.jpg"
gradientBean.rightUrl = "http://img.duoziwang.com/2021/01/1618554889818120.jpg"
gradientBean.bitmapScale = 0.3f
gradientBean.startColor = "#B3FF6347"
gradientBean.endColor = "#B3FFD700"
gradientBean.gradientWidth = width
gradientBean.gradientHeight = (width * 0.6).toInt()
return gradientBean
}
}
circular_corner_color_gradient_main布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/red"
android:textSize="30sp"
android:text="不正规圆角-颜色渐变"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/circular_corner_color_gradient_btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:text="渐变+圆角+图标 RecyclerView"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:textSize="30sp"
android:textColor="@color/purple_200"
android:text="RecyclerView列表"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/gradient_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
gradient_item布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/gradient_item_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>

607

被折叠的 条评论
为什么被折叠?



