网站开发范本,域名费用和网站服务器费用是同样的吗,电商网站怎样做优化才最合理,简约wordpress主题如果需要做一个自定义的波浪效果的进度条#xff0c;裁剪图片#xff0c;对ImageView的图片进行裁剪#xff0c;比如下面2张图#xff0c;如何实现#xff1f; 先看下面的效果#xff0c;看到其实只需要对第一张高亮的图片进行处理即可#xff0c;灰色状态的作为背景图。…
如果需要做一个自定义的波浪效果的进度条裁剪图片对ImageView的图片进行裁剪比如下面2张图如何实现 先看下面的效果看到其实只需要对第一张高亮的图片进行处理即可灰色状态的作为背景图。 1、实现原理
这里首先想到的是自定义View在Android中,使用二阶贝塞尔曲线可以实现我们想要的效果关键的API就是Path的rQuadTo()方法。 path.reset()path.moveTo(startX, startY)path.quadTo(currentX, currentY, endX, endY)canvas.drawPath(path, curvePaint)startX和startYendX和endY为两个固定点currentX和currentY就是控制点通过改变控制点的位置来改变二阶贝塞尔曲线的形状。 a点和b点就是固定点c点是控制点我们可以改变c点的位置来改变曲线的形状。 在Android中使用cubicTo来实现三阶贝塞尔。上面的需求方案使用二阶即可实现三阶的可以自行了解。 2、事例分析
首先可以通过自定义一个贝赛尔曲线来了解一下
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;public class BezierCurveView extends View {private Paint paint;private Path path;public BezierCurveView(Context context) {super(context);init();}public BezierCurveView(Context context, AttributeSet attrs) {super(context, attrs);init();}public BezierCurveView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {paint new Paint();paint.setColor(Color.BLUE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(5f);path new Path();}Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int height getHeight();int width getWidth();float dx width / 4f;float dy height / 4f;path.reset();path.moveTo(0, height / 2f); // 起点path.rQuadTo(dx, -dy, 2 * dx, 0f); // 控制点、终点path.rQuadTo(dx, dy, 2 * dx, 0f); // 控制点、终点path.rQuadTo(dx, -dy, 2 * dx, 0f); // 控制点、终点path.rQuadTo(dx, dy, 2 * dx, 0f); // 控制点、终点path.lineTo(width, height);path.lineTo(0f, height);path.close();canvas.drawPath(path, paint);}
}
要使用这个自定义View你需要在布局文件中引用一下
com.example.myapp.BezierCurveViewandroid:layout_widthmatch_parentandroid:layout_height200dp /
看下效果 3、使用贝塞尔裁剪ImageView
1自定义ImageView
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.util.AttributeSet;import androidx.annotation.Nullable;/*** 图片裁剪为贝赛尔曲线边缘ImageView*/
public class BezierImageView extends androidx.appcompat.widget.AppCompatImageView {private static final String TAG ArcImageView;public BezierImageView (Context context) {this(context, null);}public BezierImageView (Context context, Nullable AttributeSet attrs) {this(context, attrs, 0);}public BezierImageView (Context context, Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);path new Path();}private final Path path;/*** 进度值0~100默认100*/private int progress 100;public void setProgress(int progress) {this.progress progress;postInvalidate();}Overrideprotected void onDraw(Canvas canvas) {final int width getWidth();final int height getHeight();float dx width / 4f;float dy height / 8f;float yOffset (100 - progress) / 100f * height;float[] p1 {0f, yOffset};float[] p2 {dx, -dy};float[] p3 {2 * dx, 0f};float[] p4 {dx, dy};float[] p5 {2 * dx, 0f};float[] p6 {dx, -dy};float[] p7 {2 * dx, 0f};float[] p8 {dx, dy};float[] p9 {2 * dx, 0f};path.reset();path.moveTo(p1[0], p1[1]);path.rQuadTo(p2[0], p2[1], p3[0], p3[1]);path.rQuadTo(p4[0], p4[1], p5[0], p5[1]);path.rQuadTo(p6[0], p6[1], p7[0], p7[1]);path.rQuadTo(p8[0], p8[1], p9[0], p9[1]);path.lineTo(width, height);path.lineTo(0f, height);path.close();canvas.clipPath(path);super.onDraw(canvas);}
}
2如何使用 com.....BezierImageView android:idid/bgandroid:layout_width200dpandroid:layout_height200dpandroid:layout_centerInParenttrueandroid:scaleTypefitCenterandroid:srcdrawable/bg_cover /
bg.setProgress(50);
直接调用setProgress()方法传入要裁剪的百分比即可。
效果如下所示 4、使用sin()正弦函数实现波浪/曲线效果
基于3中直接修改onDraw()中的关键代码即可
Overrideprotected void onDraw(Canvas canvas) {final int width getWidth();final int height getHeight();// 变量描述可自己调整// offset:Y轴偏移量// yHeight可控制Y轴高度(值越小百分比显示越大)// countF控制波数(越大波数越少)// xOffset可控制波长幅度值越大幅度越大,越小越平缓float offset 0.1f, yHeight 1.0f, countF 60.0f, xOffset 0.04f;// 方案1path.moveTo(0, height);for (int i 0; i width; i) {path.lineTo(i, (float) (height * ((yHeight - offset) Math.sin(i / countF Math.PI) * xOffset)));}path.lineTo(width, height);path.lineTo(0f, height);path.close();canvas.clipPath(path);super.onDraw(canvas);}
使用sin()函数结合lineTo()方法同样可以实现波浪曲线效果