我的Android进阶之旅------>Android通过使用Matrix旋转图片来模拟碟片加载过程

简介:      今天实现了一个模拟碟片加载过程的小demo,在此展示一下。由于在公司,不好截取动态图片,因此就在这截取两张静态图片看看效果先。 下面简单的将代码列出来。

    


今天实现了一个模拟碟片加载过程的小demo,在此展示一下。由于在公司,不好截取动态图片,因此就在这截取两张静态图片看看效果先。

下面简单的将代码列出来。

setp1、准备两张用于旋转的图片,如下:loading_disc.png是第一张图片,loading_light.png是第二张图片。

      (1)                  (2)



step2、自定义一个View,用来控制这两个图片的旋转。com.oyp.loadingdisk.LoadingDiscView.java

package com.oyp.loadingdisk;

import java.io.InputStream;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.view.View;
/**
 * 自定义的View,用来显示加载的图片
 * @author ouyangpeng 
 * @link http://blog.csdn.net/ouyang_peng
 * 
 * <p>在画图的时候,图片如果旋转或缩放之后,总是会出现那些华丽的锯齿。<br>
 * 方法一:给Paint加上抗锯齿标志。然后将Paint对象作为参数传给canvas的绘制方法。<br>
 * 如:mypaint.setAntiAlias(true);<p>
 * 方法二:给Canvas加上抗锯齿标志。有些地方不能用paint的,就直接给canvas加抗锯齿,更方便。<br>
 * 如:
 * mSetfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);<br>
 * canvas.setDrawFilter(mSetfil);
 */
public class LoadingDiscView extends View {
		private RefreshHandle refreshHandle;
		private Context context;
		/** 用于旋转的bitmap*/
		private Bitmap m_bmp_disc = null;
		private Matrix m_matrix_disc = new Matrix();
		/** 用于展现高亮背景的bitmap*/
		private Bitmap m_bmp_light = null;
		private Matrix m_matrix_light = new Matrix();
		/**Paint滤波器*/
		private PaintFlagsDrawFilter mSetfil = null;
		/**声明一个画笔*/
		private Paint mypaint = null;
		/**图像缩放比例*/
		private float m_scale =1.0f;
		/**图像旋转的速度*/
		private float m_disc_rot_speed = 0;
		/**图像旋转的状态*/
		private int m_state_play = 1;
		/**图像旋转的最大速度*/
		private float m_disc_max = 20f;

		public void setRefreshHandle(RefreshHandle refreshHandle) {
			this.refreshHandle = refreshHandle;
		}

		public LoadingDiscView(Context context) {
			super(context);
			this.context = context;
			mSetfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);//设置画布绘图无锯齿
			initBitmap();
		}

		public boolean initBitmap() {
			mypaint = new Paint();
			//给Paint加上抗锯齿标志
			mypaint.setAntiAlias(true);//画笔的抗锯齿(用于线条等)

			Resources res = context.getResources();
			InputStream is = res.openRawResource(R.drawable.loading_disc);
			m_bmp_disc = BitmapFactory.decodeStream(is);
			matrixPostTranslate(m_matrix_disc,m_bmp_disc);

			is = res.openRawResource(R.drawable.loading_light);
			m_bmp_light = BitmapFactory.decodeStream(is);
			matrixPostTranslate(m_matrix_light,m_bmp_light);
			return true;
		}
		/**
		 * 旋转图像
		 * @param matrix 控制旋转的矩阵
		 * @param bitmap 要旋转的图像
		 */
		private void matrixPostTranslate(Matrix matrix,Bitmap bitmap) {
			int tmp_width = bitmap.getWidth();
			int tmp_height = bitmap.getHeight();
			matrix.postTranslate(-tmp_width / 2, -tmp_height / 2); //设置平移位置
			matrix.postScale(m_scale, m_scale);  //设置缩放比例
			matrix.postTranslate(123 * m_scale, 146 * m_scale);
		}

		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			//给Canvas加上抗锯齿标志
			canvas.setDrawFilter(mSetfil);//图片线条(通用)的抗锯齿
			canvas.drawBitmap(m_bmp_disc, m_matrix_disc, mypaint);
			canvas.drawBitmap(m_bmp_light, m_matrix_light, mypaint);
		}

		public void update() {
			if (m_disc_rot_speed > 0.01 || m_state_play == 1){
				if (m_state_play == 1 && m_disc_rot_speed<m_disc_max){
					m_disc_rot_speed += (m_disc_max+0.5f-m_disc_rot_speed)/30;
				}
				else if (m_disc_rot_speed>0.1){
					m_disc_rot_speed -= (m_disc_rot_speed)/40;
				}
				m_matrix_disc .postRotate(m_disc_rot_speed, 123*m_scale, 146*m_scale);
				invalidate();
			}
		}
		
		public void onPause(){
			refreshHandle.stop();
		}
		public void onResume(){
			refreshHandle.run();
		}
		
	}


step3、写一个Handler用来控制图片的旋转   com.oyp.loadingdisk.RefreshHandle.java

package com.oyp.loadingdisk;

import android.os.Handler;
import android.os.Message;
/**
 * 用来发送消息和处理消息的
 * @author ouyangpeng
 * @link http://blog.csdn.net/ouyang_peng
 */
public class RefreshHandle extends Handler {
	LoadingDiscView loadingDiscView;

	public RefreshHandle(LoadingDiscView loadingDiscView) {
		this.loadingDiscView = loadingDiscView;
		loadingDiscView.setRefreshHandle(this);
	}

	public void run() {
		loadingDiscView.update();
		removeCallbacksAndMessages(null);
		sendEmptyMessageDelayed(0, 65);
	}

	public void stop() {
		removeCallbacksAndMessages(null);
	}

	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case 0:
			run();
			break;
		}
	}
}

step4、应用布局文件    res/layout/loading.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#382517"
    tools:context=".MainActivity" 
    >

   <RelativeLayout
        android:id="@+id/loading_disc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/loading_disc"   
        android:paddingLeft="100dp"
        >
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="380dip" >

        <TextView
            android:id="@+id/loading_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:singleLine="true"
            android:textColor="#FFFFFF"
            android:text="读碟中,请稍后 . . ."
            android:textSize="20sp" />
    </RelativeLayout>
</RelativeLayout>

step5、写一个Activity用来装载布局文件,并展示    com.oyp.loadingdisk.LoadingActivity.java

package com.oyp.loadingdisk;

import android.app.Activity;
import android.os.Bundle;
import android.widget.RelativeLayout;
/**
 * @author ouyangpeng 
 * @link http://blog.csdn.net/ouyang_peng
 */
public class LoadingActivity extends Activity {
	private RelativeLayout motionView;
	private LoadingDiscView disc_motion;
	private RefreshHandle refreshHandle;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.loading);
		disc_motion = new LoadingDiscView(this);
		refreshHandle = new RefreshHandle(disc_motion);
		motionView = (RelativeLayout) findViewById(R.id.loading_disc);
		motionView.addView(disc_motion);
		refreshHandle.sendEmptyMessage(0);
	}
	@Override
	protected void onResume() {
		super.onResume();
		disc_motion.onResume();
	}
}

当然,这里只是模拟碟片加载过程,实际上可以对代码进行处理,使碟片加载过程完毕后,启动相应的界面来展示碟片中的视频、图像、音乐资源等,但是这里不便写出来。


关于源代码,您可以通过   https://github.com/ouyangpeng/LoadingDisk 来免费察看和下载代码


====================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址http://blog.csdn.net/ouyang_peng

===================================================================================



相关文章
|
5月前
|
Java Android开发
Android面试题经典之Glide取消加载以及线程池优化
Glide通过生命周期管理在`onStop`时暂停请求,`onDestroy`时取消请求,减少资源浪费。在`EngineJob`和`DecodeJob`中使用`cancel`方法标记任务并中断数据获取。当网络请求被取消时,`HttpUrlFetcher`的`cancel`方法设置标志,之后的数据获取会返回`null`,中断加载流程。Glide还使用定制的线程池,如AnimationExecutor、diskCacheExecutor、sourceExecutor和newUnlimitedSourceExecutor,其中某些禁止网络访问,并根据CPU核心数动态调整线程数。
148 2
|
2月前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
3月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
68 20
Android经典面试题之图片Bitmap怎么做优化
|
4月前
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
|
4月前
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
246 4
|
4月前
|
存储 缓存 Java
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
47 0
|
4月前
|
Java Android开发 Kotlin
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
38 0
|
4月前
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
78 0
|
6月前
|
XML API 开发工具
Android Bitmap 加载与像素操作
Android Bitmap 加载与像素操作
50 2
|
6月前
|
JSON 编解码 Apache
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
64 1