IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 三种实现ImageView以自身中心为原点旋转的方法 -> 正文阅读

[移动开发]三种实现ImageView以自身中心为原点旋转的方法

总结三种实现ImageView以自身中心为原点旋转的方法

在这里插入图片描述
资源链接:加载等待–阿里云盘

三个layout文件用到的控件都是一样的,所以这里就只贴出一个

main_activty.xml

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img_loading"
        android:layout_width="160dp"
        android:layout_height="160dp"
        android:src="@mipmap/loading_01"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="开启"
        app:layout_constraintEnd_toEndOf="@+id/img_loading"
        app:layout_constraintStart_toStartOf="@+id/img_loading"
        app:layout_constraintTop_toBottomOf="@+id/img_loading" />

    <Button
        android:id="@+id/btn_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="关闭"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="@+id/btn_start"
        app:layout_constraintStart_toStartOf="@+id/btn_start"
        app:layout_constraintTop_toBottomOf="@+id/btn_start" />
</androidx.constraintlayout.widget.ConstraintLayout>

方法一:通过动画的方式来实现(最简单的一种)

如果想进一步了解动画相关知识,建议点击下方连接跳转到官网学习
动画简介 | Android 开发者 | Android Developers

java代码
注意:此方法只有一张图片,是在布局文件中插入到IamgeView中的

public class Test01Activity extends AppCompatActivity {

    private static final String TAG = "Test01Activity";
    private ImageView mImgLoading;
    private Button mBtnStart;
    private Button mBtnStop;

    private Animation mRotate;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test01);
        initView();

        // 初始化旋转动画对象
        // fromDegrees:起始角度的度数,toDegrees:结束角度度数,正数表示顺时针,负数表示逆时针
        // pivotX:旋转中心的X坐标,pivotXValue:50%表示在object的中心
        // pivotY:与pivotX同理
        mRotate = new RotateAnimation(
                0f,
                360f,
                Animation.RELATIVE_TO_SELF,
                0.5f,
                Animation.RELATIVE_TO_SELF,
                0.5f);
        // 初始话插值器并设置线性插值器,变化率,并不是运行速度。一个插补动画,可以将动画效果设置为加速、减速、反复、反弹等
        //linearInterpolator为匀速
        mRotate.setInterpolator(new LinearInterpolator());
        // 设置动画从fromDegrees转动到toDegrees花费的时间,毫秒。可以用来计算速度
        mRotate.setDuration(2000);
        // 设置重复的次数(旋转圈数),Animation.INFINITE = -1,无限循环
        mRotate.setRepeatCount(Animation.INFINITE);

        mBtnStart.setOnClickListener(v -> {
            mImgLoading.setAnimation(mRotate);
            // 注意这里,在设置完动画一定要start动画才会执行
            mImgLoading.startAnimation(mRotate);
        });
        mBtnStop.setOnClickListener(v -> {
            mImgLoading.clearAnimation();
        });
    }

    private void initView() {
        mImgLoading = findViewById(R.id.img_loading);
        mBtnStart = findViewById(R.id.btn_start);
        mBtnStop = findViewById(R.id.btn_close);
    }
}

也可以通过ObjectAnimator属性动画来实现

private ObjectAnimator mAnimator;

// Object target:目标对象,
// String propertyName:指定要改变对象的什么属性,这个属性名要求在对应对象中必须有对应的public的PsetPropertyName的方法。如上面的rotation就要求ImageView中必须有setRotation方法才行。
// float... values:一系列这个属性将会到达的值
mAnimator = ObjectAnimator.ofFloat(mImgLoading,"rotation",0f,360f);
// 设置一次动画的时间
mAnimator.setDuration(2000);
// 设置插值器,用来控制变化率
mAnimator.setInterpolator(new LinearInterpolator());
// 设置重复的次数,无限
mAnimator.setRepeatCount(ObjectAnimator.INFINITE);
mAnimator.start();

// 在合适的位置调用 mAnimator.pause()方法进行暂停操作

方法二:Timer+Handler

java代码

public class Test02Activity extends AppCompatActivity {

    private ImageView mImgLoading;
    private Button mBtnStart;
    private Button mBtnStop;
    // 初始化存放图片的数组
    private int[] mImgS = new int[] {
            R.mipmap.loading_01,R.mipmap.loading_02,R.mipmap.loading_03,R.mipmap.loading_04,R.mipmap.loading_05,
            R.mipmap.loading_06,R.mipmap.loading_07,R.mipmap.loading_08,R.mipmap.loading_09,R.mipmap.loading_10,
            R.mipmap.loading_11,R.mipmap.loading_12
    };
    private int mImgStart = 0;

    private Handler mHandler;
    private Timer mTimer;
    private TimerTask mTimerTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test02);
        initView();
        mHandler = new Handler(Looper.myLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if (msg.what == 333) {
                    mImgLoading.setImageResource(mImgS[mImgStart++ % 12]);
                }
            }
        };

        mBtnStart.setOnClickListener(v -> {
            // https://blog.csdn.net/wuqingsen1/article/details/84875785
            // 倒计时的操作博客
            mTimer = new Timer();
            mTimerTask = new TimerTask() {
                // 周期执行一个任务
                @Override
                public void run() {
                    mHandler.sendEmptyMessage(333);
                }
            };
            // delay:表示多长时间后开始执行(延时)
            // period:执行的周期,这里就是表示,200毫秒为一周期执行
            mTimer.schedule(mTimerTask,0,200);

            /**
             * schedule的几种参数及用法:
             * 1、表示在指定的时间执行一次
             * schedule(timerTask,time);
             * 2、firstTime为Date类型,表示从firstTime时刻开始,每隔period毫秒执行一次
             * schedule(task,firstTime,period)
             * 3、延时delay毫秒数后开始执行一次
             * schedule(timeTask,delay)
             * 4、从现在延时delay毫秒后,每个period毫秒执行一次
             * schedule(timeTask,delay,period)
             */
        });

        mBtnStop.setOnClickListener(v -> {
            // 正确的停止方法是判空
            if (mTimerTask != null) {
                mTimerTask.cancel();
                mTimerTask = null;
            }
            if (mTimer != null) {
                mTimer.cancel();
                mTimer = null;
            }
        });
    }

    private void initView() {
        mImgLoading = findViewById(R.id.img_loading);
        mBtnStart = findViewById(R.id.btn_start);
        mBtnStop= findViewById(R.id.btn_stop);
    }
}

方法三:Handler + Thread的的方法(不推荐)

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private ImageView mImgLoading;
    private Button mBtnStart,mBtnStop;

    // 用于判断当前为转动还是停止
    private Boolean isPause = false;
    // 用于标识转动到第几个
    private int flag = 1;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initThread();
        initHandler();

        mBtnStart.setOnClickListener(v -> {
            isPause = true;
        });
        mBtnStop.setOnClickListener(v -> {
            isPause = false;
        });
    }

    private void initThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 一直进行判断,循环的开启与关闭通过isPause来控制
                while (true) {
                    if (isPause) {
                        // 获得message对象
                        Message msg = Message.obtain();
                        // 将flag赋值给msg.what
                        msg.what = flag;
                        // 将待带有flag的消息发出
                        mHandler.sendMessage(msg);
                        // 因为我们有6张图片,所以当flag为6时,循环为第一张图片
                        if (flag == 6) {
                            flag = 1;
                        }
                        flag++;
                    }

                    // 延时操作
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
            // 开启线程
        }).start();
    }

    private void initHandler() {
        mHandler = new Handler(Looper.myLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                // 在这里获取消息的值,也就是初始化线程中我们通过msg.what传入的值
                // 我们的延时在这里达到了每隔50毫秒就发送过来一条msg.what == flag++的消息
                switch (msg.what) {
                    // 顺序设置图片,达到图片转动的效果
                    case 1:
                        mImgLoading.setImageResource(R.mipmap.loading_01);
                        break;
                    case 2:
                        mImgLoading.setImageResource(R.mipmap.loading_02);
                        break;
                    case 3:
                        mImgLoading.setImageResource(R.mipmap.loading_03);
                        break;
                    case 4:
                        mImgLoading.setImageResource(R.mipmap.loading_04);
                        break;
                    case 5:
                        mImgLoading.setImageResource(R.mipmap.loading_05);
                        break;
                    case 6:
                        mImgLoading.setImageResource(R.mipmap.loading_06);
                        break;
                    default:
                        Log.d(TAG,"default is load");

                }
            }
        };
    }

    private void initView() {
        mImgLoading = findViewById(R.id.img_loading);
        mBtnStart = findViewById(R.id.btn_start);
        mBtnStop= findViewById(R.id.btn_stop);
    }
}


方法三为从别人的博客学来的,找不到原文链接了,如有冒犯,烦请私信我。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-23 10:58:30  更:2022-04-23 10:59:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:48:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码