Android开发之自定义view进行旋转动画
生活随笔
收集整理的這篇文章主要介紹了
Android开发之自定义view进行旋转动画
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
老套路先上圖:
整個view非常簡單,我自定義view里面都有詳細的注釋說明
先看自定義view部分代碼:
package cn.xiayiye5.customizestudy.view;import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast;import androidx.annotation.Nullable; import androidx.annotation.RequiresApi;import cn.xiayiye5.customizestudy.R;/*** @author : xiayiye5* @date : 2021/3/18 15:50* 類描述 :自定義view - 畫圓基礎練習*/ public class BasicView extends View {private int measuredWidth;private int measuredHeight;private Paint paint;private float paintWidth;private int paintColor;private int paintStroke;private Paint textPaint;private final float textWidth;private final int textColor;private final float textSize;@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public BasicView(Context context) {this(context, null);}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public BasicView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public BasicView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public BasicView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BasicView);paintWidth = typedArray.getDimension(R.styleable.BasicView_paint_width, 10);paintColor = typedArray.getColor(R.styleable.BasicView_paint_color, Color.GREEN);paintStroke = typedArray.getInt(R.styleable.BasicView_paint_stroke, 1);//獲取文字顏色,寬度,大小等textWidth = typedArray.getDimension(R.styleable.BasicView_text_width, 10);textColor = typedArray.getColor(R.styleable.BasicView_text_color, Color.GREEN);textSize = typedArray.getDimension(R.styleable.BasicView_text_size, 20);typedArray.recycle();initView();}private void initView() {//文字用到的畫筆textPaint = new Paint();//圓用到的畫筆paint = new Paint();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//設置中間文字顏色大小寬度等textPaint.setTextSize(textSize);textPaint.setStrokeWidth(textWidth);textPaint.setColor(textColor);//設置畫筆圓的大小顏色寬度等paint.setColor(paintColor);paint.setTextSize(14f);paint.setStrokeWidth(paintWidth);if (paintStroke == StrokeModel.STROKE_ZERO) {paint.setStyle(Paint.Style.FILL);} else if (paintStroke == StrokeModel.STROKE_ONE) {paint.setStyle(Paint.Style.STROKE);} else if (paintStroke == StrokeModel.STROKE_TWO) {paint.setStyle(Paint.Style.FILL_AND_STROKE);} else {throw new NumberFormatException("The value is only 0(BasicView.StrokeModel.STROKE_ZERO) or 1(BasicView.StrokeModel.STROKE_ONE) or 2(BasicView.StrokeModel.STROKE_TWO)");}float length = textPaint.measureText("揚宏豕慧");float fontHeight = getFontHeight(textPaint);//寫文字在坐標中心居中canvas.drawText("揚宏豕慧", (measuredWidth - length) / 2f, (measuredHeight + fontHeight / 2f) / 2f, textPaint);canvas.drawCircle(measuredWidth / 2f, measuredHeight / 2f, (measuredWidth - paintWidth) / 2f, paint);//畫圓的橫線canvas.drawLine(0, measuredHeight / 2f, measuredWidth, measuredHeight / 2f, paint);//畫圓的豎線canvas.drawLine(measuredWidth / 2f, 0, measuredHeight / 2f, measuredHeight, paint);}/*** @return 返回指定的文字高度*/public float getFontHeight(Paint paint) {Paint.FontMetrics fm = paint.getFontMetrics();//文字基準線的下部距離-文字基準線的上部距離 = 文字高度return fm.descent - fm.ascent;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int height = 0;int width = 0;width = setViewMode(widthMeasureSpec, width);height = setViewMode(heightMeasureSpec, height);//獲取測量模式后設置下即可setMeasuredDimension(width, height);measuredWidth = getMeasuredWidth();measuredHeight = getMeasuredHeight();Log.e("打印寬高", measuredWidth + "-" + measuredHeight);}/*** 獲取測量模式的方法** @param measureSpec 測量模式* @param viewSize view的大小* @return 返回 view經(jīng)過測量后的大小*/private int setViewMode(int measureSpec, int viewSize) {int viewMode = MeasureSpec.getMode(measureSpec);int size = MeasureSpec.getSize(measureSpec);if (viewMode == MeasureSpec.AT_MOST) {// wrap_content模式 測量規(guī)格模式:子級可以任意大到指定的大小。viewSize = getMeasuredWidth() / 3;} else if (viewMode == MeasureSpec.EXACTLY) {// 已經(jīng)設置了具體大小,類似10dp 和match_parent 測量規(guī)格模式:父級已確定子級的確切大小。不管孩子想要多大,都要給他這些限制。viewSize = size;} else if (viewMode == MeasureSpec.UNSPECIFIED) {//設置多大就多大可以無限大 度量規(guī)范模式:父級未對子級施加任何約束。它可以是它想要的任何尺寸。viewSize = size;}return viewSize;}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {//獲取view在當前屏幕的坐標float rawX = event.getRawX();float rawY = event.getRawY();//獲取view在自身的坐標float x = event.getX();float y = event.getY();Log.e("打印屏幕坐標", rawX + "," + rawY);Log.e("打印view坐標y", x + "," + y);if (x > 0 && y > 0) {//證明點擊了此viewToast.makeText(getContext(), "點擊了此布局(" + x + "," + y + ")", Toast.LENGTH_LONG).show();clickViewListener.clicked(this);}}return true;}public static class StrokeModel {private StrokeModel() {}public static final int STROKE_ZERO = 0;public static final int STROKE_ONE = 1;public static final int STROKE_TWO = 2;}public interface ClickViewListener {/*** 點擊了哪個view** @param view 具體的view*/void clicked(View view);}ClickViewListener clickViewListener;public void setClickViewListener(ClickViewListener clickViewListener) {this.clickViewListener = clickViewListener;}/*** 設置畫筆圓的寬度** @param paintWidth 寬度*/public void setPaintWidth(float paintWidth) {this.paintWidth = paintWidth;requestLayout();}/*** 設置畫筆圓的顏色** @param paintColor 顏色*/public void setPaintColor(int paintColor) {this.paintColor = paintColor;invalidate();}/*** 設置畫筆圓的模式** @param paintStroke 模式*/public void setPaintStroke(int paintStroke) {this.paintStroke = paintStroke;requestLayout();} }再看layout布局代碼
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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"><cn.xiayiye5.customizestudy.view.BasicViewandroid:id="@+id/bv_view"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:paint_color="@color/purple_500"app:paint_stroke="stroke"app:paint_width="1dp"app:text_color="@color/purple_200"app:text_size="16sp"app:text_width="10dp" /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="changeColor"android:text="改變顏色"app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>再看activity頁面代碼
package cn.xiayiye5.customizestudy.ui.activity;import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.view.animation.LinearInterpolator; import android.widget.Toast;import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity;import java.util.Random;import cn.xiayiye5.customizestudy.R; import cn.xiayiye5.customizestudy.view.BasicView; import cn.xiayiye5.customizestudy.view.BasicView.StrokeModel;/*** @author : xiayiye5* @date : 2021/3/19 11:36* 類描述 :*/ public class BasicActivity extends AppCompatActivity {int num = 0;BasicView bvView;private ObjectAnimator rotation;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_basic);bvView = findViewById(R.id.bv_view);bvView.setClickViewListener(view -> Toast.makeText(BasicActivity.this, "點擊了此布局", Toast.LENGTH_LONG).show());}public void changeColor(View view) {if (num % StrokeModel.STROKE_TWO == 0) {//開始執(zhí)行動畫startAnim();Toast.makeText(this, "彩虹紅燈開啟", Toast.LENGTH_SHORT).show();handler.sendEmptyMessageDelayed(0, 500);} else {Toast.makeText(this, "彩虹紅燈關閉", Toast.LENGTH_SHORT).show();handler.removeCallbacksAndMessages(null);//關閉動畫rotation.end();}num++;}/*** 開始動畫的方法*/private void startAnim() {ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(bvView, "alpha", 0.0f, 1.0f);ObjectAnimator scaleX = ObjectAnimator.ofFloat(bvView, "scaleX", 0.0f, 1.0f);ObjectAnimator scaleY = ObjectAnimator.ofFloat(bvView, "scaleY", 0.0f, 1.0f);rotation = ObjectAnimator.ofFloat(bvView, "rotation", 0.0f, 1080f);rotation.setRepeatCount(100);//旋轉不停頓rotation.setInterpolator(new LinearInterpolator());//重復次數(shù)rotation.setDuration(1000);rotation.start(); // AnimatorSet set = new AnimatorSet(); // set.playTogether(alphaAnim, scaleX, scaleY); // set.setDuration(3000); // set.start();}private final Handler handler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);Log.e("打印", "發(fā)送消息");bvView.setPaintColor(Color.rgb(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255)));bvView.setPaintStroke(StrokeModel.STROKE_ONE);bvView.setPaintWidth(new Random().nextInt(30));//繼續(xù)發(fā)送形成循環(huán)模式sendEmptyMessageDelayed(0, 500);}};@Overrideprotected void onPause() {super.onPause();handler.removeCallbacksAndMessages(null);}@Overrideprotected void onResume() {super.onResume();if (num > 0) {//繼續(xù)發(fā)送形成循環(huán)模式handler.sendEmptyMessageDelayed(0, 500);}}@Overrideprotected void onDestroy() {super.onDestroy();handler.removeCallbacksAndMessages(null);} }在看下attrs.xml屬性文件
<?xml version="1.0" encoding="utf-8"?> <resources><declare-styleable name="BasicView"><!--畫筆顏色--><attr name="paint_color" format="color" /><!--畫筆寬度--><attr name="paint_width" format="dimension" /><!--畫筆形狀--><attr name="paint_stroke" format="enum"><enum name="fill" value="0" /><enum name="stroke" value="1" /><enum name="fill_and_stroke" value="2" /></attr><!--文字顏色--><attr name="text_color" format="color" /><!--文字大小--><attr name="text_size" format="dimension" /><!--文字寬度--><attr name="text_width" format="dimension" /></declare-styleable> </resources>整個理偶成非常簡單說下具體步驟:
先通過attires文件自定義屬性=>然后繪制view將自定義屬性通過layout文件與attrs的自定義屬性對應設置相應的屬性值即可。其它就是API相關的東西了。
感謝博主提供動畫結束方法:博主直達
關于view的測量模式可以查看Google官方文檔的說明:Google官方文檔說明
總結
以上是生活随笔為你收集整理的Android开发之自定义view进行旋转动画的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 暗黑三国风!《卧龙:苍天陨落》正式上线:
- 下一篇: Minisforum 新款 HX80G