需要图片集和源码请点赞关注收藏后评论区留言~~~
一、贝塞尔曲线的原理
贝塞尔曲线是一种用于二维图形的数学曲线。贝塞尔曲线由节点和线段构成,其中节点是可拖动的支点,而线段彷佛有弹性的牛皮筋。它除了起点和终点之外,不再描绘中间的折现,而是构建一段运输小球的控制线,控制线本身在移动,然后小球随着在控制线上滑动,小球从起点运动到终点的轨迹便形成了贝塞尔曲线。贝塞尔曲线又可以分为以下三类
1:一次贝塞尔曲线
此时曲线只是一条两点之间的线段
2:二次贝塞尔去信啊
此时除了起点和终点,曲线还存在一个控制点
3:三次贝塞尔曲线
此时除了起点和终点 曲线还存在两个控制点
贝塞尔曲线拥有优美的平滑特性,使得它广泛应用于计算机绘图,Android也自带了与之相关的操作方法 效果如下
实现三次贝塞尔曲线的效果如下
贝塞尔曲线
代码如下
Java类
package com.example.ebook;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.ImageDecoder;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
@RequiresApi(api = Build.VERSION_CODES.P)
public class BezierCurveActivity extends AppCompatActivity {
private ImageView iv_curve; // 声明一个图像视图对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bezier_curve);
iv_curve = findViewById(R.id.iv_curve);
initCurveSpinner(); // 初始化曲线类型下拉框
}
private String[] mCurveArray = {"一次贝塞尔曲线", "二次贝塞尔曲线", "三次贝塞尔曲线" };
private int[] mDrawableArray = {R.drawable.bezier_first_order, R.drawable.bezier_second_order, R.drawable.bezier_third_order };
// 初始化曲线类型下拉框
private void initCurveSpinner() {
ArrayAdapter<String> curveAdapter = new ArrayAdapter<>(this,
R.layout.item_select, mCurveArray);
Spinner sp_curve = findViewById(R.id.sp_curve);
sp_curve.setPrompt("请选择曲线类型");
sp_curve.setAdapter(curveAdapter);
sp_curve.setOnItemSelectedListener(new CurveSelectedListener());
sp_curve.setSelection(0);
}
private class CurveSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
showBezierCurve(arg2); // 显示贝塞尔曲线的演示动图
}
public void onNothingSelected(AdapterView<?> arg0) {}
}
// 显示贝塞尔曲线的演示动图
private void showBezierCurve(int order) {
int drawableId = mDrawableArray[order];
try {
// 利用Android 9.0新增的ImageDecoder读取图片
ImageDecoder.Source source = ImageDecoder.createSource(getResources(), drawableId);
// 从数据源解码得到图形信息
Drawable drawable = ImageDecoder.decodeDrawable(source);
iv_curve.setImageDrawable(drawable); // 设置图像视图的图形对象
if (drawable instanceof Animatable) { // 如果是动画图形,则开始播放动画
((Animatable) iv_curve.getDrawable()).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:gravity="center"
android:text="请选择曲线类型"
android:textColor="@color/black"
android:textSize="17sp" />
<Spinner
android:id="@+id/sp_curve"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:spinnerMode="dialog" />
</LinearLayout>
<ImageView
android:id="@+id/iv_curve"
android:layout_width="match_parent"
android:layout_height="150dp" />
</LinearLayout>
二、利用贝塞尔曲线实现波浪起伏动画
贝塞尔曲线表面上只是一条静止的曲线,不过通过持续改变曲线的起点位置就能实现曲线的波动特效,比如有人拿着一根绳子,上下反复抖动绳子,这根绳子便会波动展开 实现步骤如下
1:重写自定义视图的onDraw方法 根据起点 终点位置勾勒出一段波浪曲线
2:初始化一个属性动画 随着时间推移逐渐挪动起点的坐标位置
3:提供开始播放动画和停止播放动画两个方法
效果如下
波浪动画
代码如下
Java类
package com.example.ebook;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import com.example.ebook.widget.WaveView;
public class BezierWaveActivity extends AppCompatActivity {
private Button btn_start;
private WaveView wv_wave; // 声明一个波浪视图对象
private boolean isPlaying = false; // 是否正在播放动画
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bezier_wave);
wv_wave = findViewById(R.id.wv_wave);
btn_start = findViewById(R.id.btn_start);
btn_start.setOnClickListener(v -> {
if (!isPlaying) {
wv_wave.startAnim(); // 开始播放波浪动画
} else {
wv_wave.stopAnim(); // 停止播放波浪动画
}
isPlaying = !isPlaying;
btn_start.setText(isPlaying?"停止播放动画":"开始播放动画");
});
}
}
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始播放动画"
android:textColor="@color/black"
android:textSize="17sp" />
<com.example.ebook.widget.WaveView
android:id="@+id/wv_wave"
android:layout_width="match_parent"
android:layout_height="120dp" />
</LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~