需要图片集和源码请点赞关注收藏后评论区留言~~~
一、贝塞尔曲线的原理
贝塞尔曲线是一种用于二维图形的数学曲线。贝塞尔曲线由节点和线段构成,其中节点是可拖动的支点,而线段彷佛有弹性的牛皮筋。它除了起点和终点之外,不再描绘中间的折现,而是构建一段运输小球的控制线,控制线本身在移动,然后小球随着在控制线上滑动,小球从起点运动到终点的轨迹便形成了贝塞尔曲线。贝塞尔曲线又可以分为以下三类
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>
创作不易 觉得有帮助请点赞关注收藏~~~