Android 画顶部带锯齿的长方形

本文介绍如何使用Android自定义View实现顶部带有锯齿的长方形布局,避免使用多套图片资源带来的体积增大问题。通过重写View并利用moveTo、lineTo及addArc等方法绘制出所需的图形。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      最近项目中需要一个长方形顶部带锯齿的需求,如果用切图片的话要切好几套图,增加apk的大小,而且android手机尺寸众多,屏幕一大就容易把图片拉伸,图片失真也不好,于是就手动画一个,先看一下动图。

转载注明出处:http://blog.youkuaiyun.com/longfei123abc
或者我的短域名:http://www.xuetenglong.xyz

这里写图片描述

接下来就是怎么重写view,在写之前先来认识一下几个方法moveTo(float x, float y) , lineTo(float x, float y) ,addArc(RectF oval, float startAngle, float sweepAngle),为什么要说,因为下面要用,

/**
     * Set the beginning of the next contour to the point (x,y).
     *
     * @param x The x-coordinate of the start of a new contour
     * @param y The y-coordinate of the start of a new contour
     */
    public void moveTo(float x, float y) {
        native_moveTo(mNativePath, x, y);
    }

源码的大致意思就是:画下一图形的起始点。没有绘制,看不到效果。
其实我的英语水平很low,不过简单一点的还是能看懂,希望没有误导大家,哈哈。

/**
     * Add a line from the last point to the specified point (x,y).
     * If no moveTo() call has been made for this contour, the first point is
     * automatically set to (0,0).
     *
     * @param x The x-coordinate of the end of a line
     * @param y The y-coordinate of the end of a line
     */
    public void lineTo(float x, float y) {
        isSimplePath = false;
        native_lineTo(mNativePath, x, y);
    }

大致意思是:从最后一个点到指定的点画一条线,如果没有设置moveTo(),画的起始点就是(0,0)。这个是有绘制的,可以看见。

/**
     * Add the specified arc to the path as a new contour.
     *
     * @param oval The bounds of oval defining the shape and size of the arc
     * @param startAngle Starting angle (in degrees) where the arc begins
     * @param sweepAngle Sweep angle (in degrees) measured clockwise
     */
    public void addArc(RectF oval, float startAngle, float sweepAngle) {
        addArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle);
    }

大致意思:给path添加一个指定的弧


要画的图形如下:

这里写图片描述

下面我的思路,网上各种作图软件麻烦,于是就自己手动画了一张图,字丑勿怪,如图:

这里写图片描述

把锯齿分割中半圆和顶部的长方形,这样for循环就可以横向画锯齿了,

全部代码

public class SawtoothView extends View {
    private int size = 36;
    private int width = 20;
    private Paint paint = new Paint();

    public SawtoothView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint.setColor(getResources().getColor(R.color.colorAccent));
        //消除锯齿
        paint.setAntiAlias(true);
        paint.setStrokeWidth(0);
        paint.clearShadowLayer();
        //设置镂空(方便查看效果)
        paint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int halfHeight = getHeight() >> 1;// 相当于num除以2 此处装逼请忽略
        for (int i = 0; i <= getWidth(); i += size) {
            int j = i/size;
            Path path = new Path();
            path.moveTo(j*(size+width), halfHeight);
            path.addArc(new RectF(j*(size+width), (getHeight() - 20) / 2, j*(size+width)+size, (getHeight() + 20) / 2), 0, 180);
            path.moveTo((j+1)*size+j*width, halfHeight);
            path.lineTo((j+1)*(width+size), halfHeight);
            path.lineTo((j+1)*(width+size), 0);
            path.lineTo(j*(width+size), 0);
            path.lineTo(j*(width+size), halfHeight);
            canvas.drawPath(path, paint);
        }

    }
}

效果图看下:
这里写图片描述

最后附上demo地址:https://github.com/xuetenglong/SawtoothView

如果在 Android `RecyclerView` 中使用默认的动效果时出现锯齿,可以尝试以下解决方案: 1. 设置 `RecyclerView` 的 `clipToPadding` 属性为 `false`。 ```xml <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" /> ``` 2. 在 `RecyclerView` 中使用 `ItemDecoration`。 ```kotlin class ItemDecoration : RecyclerView.ItemDecoration() { override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { outRect.set(0, 0, 0, 1) // 设置底部分割线,数值可以根据自己的需求调整 } override fun onDraw( canvas: Canvas, parent: RecyclerView, state: RecyclerView.State ) { super.onDraw(canvas, parent, state) val childCount = parent.childCount for (i in 0 until childCount) { val child = parent.getChildAt(i) val params = child.layoutParams as RecyclerView.LayoutParams val left = child.left + params.leftMargin val right = child.right + params.rightMargin val top = child.bottom + params.bottomMargin val bottom = top + 1 // 设置底部分割线,数值可以根据自己的需求调整 canvas.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), paint) } } private val paint = Paint().apply { color = Color.parseColor("#e5e5e5") // 分割线颜色 style = Paint.Style.FILL } } ``` 3. 使用第三方库 `RecyclerView Animators`。 ```gradle dependencies { implementation 'jp.wasabeef:recyclerview-animators:4.0.2' } ``` ```kotlin val animator = SlideInUpAnimator(OvershootInterpolator(1f)) recyclerView.itemAnimator = animator ``` 希望以上解决方案可以帮助到你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值