android图片3d旋转
Android Matrix图像变换处理
Android Matrix图像变换处理Canvas类中drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)方法中有个参数类型是Matrix,从字面上理解是矩阵的意思,而实际上它也确实是个3x3的矩阵。
Matrix在Android 中的主要作用是图像变换,如平移、旋转、缩放、扭曲等。
Matrix内部通过维护一个float[9]的数组来构成3x3矩阵的形式,而实际上所有的变换方法说到底就是通过更改数组中某个或某几个位置的数值。
Matrix提供了setV alues()和getValues()方法来操作数组。
显然这两个方法使用起来很不方便,如果只有这样,那Matrix估计就不会有人使用了。
Google 轻易不会辜负我们的信任,Matrix提供了若干简单易用的变换方法和映射方法供开发者使用。
Matrix变换方法1、Translate(平移)、Scale(缩放)、Rotate(旋转)、Skew(扭曲)Matrix提供了Translate(平移)、Scale(缩放)、Rotate(旋转)、Skew(扭曲)四中变换操作,这四种操作实质上是调用了setValues()方法来设置矩阵数组来达到变换效果。
除Translate(平移)外,Scale(缩放)、Rotate(旋转)、Skew(扭曲)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。
Translate操作中在x轴上使用正数进行平移将向右移动图像,而使用负数将向左移动图像。
在y轴上使用正数进行平移将向下移动图像,而使用负数将向上移动图像。
Scale操作中,在x轴上使用正数进行缩放将在中心点的右边缩放图像,而使用负数将在中心点的左边缩放图像。
在y轴上使用正数进行缩放将在中心点的下边缩放图像,而使用负数将在中心点的上边缩放图像。
2、pre、set、postMatrix提供的四种操作,每一种都有pre、set、post三种形式。
麦子学院Android开发教程旋转动画效果实现方法
最近在网上发现一个很实用的例子,关于旋转动画效果的实现方法,转给大家分享下。
Main.java:Java代码1.public class Main extends Activity {2.3. private com.example.view.RoundSpinView mSelfView;4.5. /** Called when the activity is first created. */6. @Override7. public void onCreate(Bundle savedInstanceState) {8. super.onCreate(savedInstanceState);9. setContentView(yout.main);10. mSelfView = (com.example.view.RoundSpinView)findViewById(R.id.mSelfView);11. mSelfView.setmPointX(160);12. mSelfView.setmPointY(150);13. mSelfView.setmRadius(80);14. mSelfView.fixBoxPosition();15. }16.}17.复制代码自定义View,实现旋转动画:RoundSpinView.java:Java代码1.public class RoundSpinView extends View {2.3. private Paint mPaint = new Paint();4. private static final int STONE_COUNT = 4;5. /** 4张图片分布的角度均值 */6. private int mDegreeDelta;7. private float mDown_x, mDown_y;8.9. private int[] mResourceId = { R.drawable.customer, R.drawable.product,10. R.drawable.order, };11.12. public RoundSpinView(Context context, AttributeSet attrs) {13. super(context, attrs);14. mPaint.setColor(Color.RED);15. mPaint.setStrokeWidth(2);16. setupStones();17. computeCoordinates();18. }19.20. /** 初始化每个旋转图片的坐标位置及图片资源 */21. private void setupStones() {22. mStones = new BigStone[STONE_COUNT];23. BigStone stone;24. int angle = 0;25. mDegreeDelta = 360 / STONE_COUNT;26.27. for (int index = 0; index < STONE_COUNT; index++) {28. stone = new BigStone();29. stone.angle = angle;30. stone.bitmap = BitmapFactory.decodeResource(getResources(),31. mResourceId[index]);32. angle += mDegreeDelta;33. mStones[index] = stone;34. }35. }36.37. /** 计算每个旋转图片坐标 */38. private void computeCoordinates() {39. BigStone stone;40. for (int index = 0; index < STONE_COUNT; index++) {41. stone = mStones[index];42. if (stone.angle >= 360) {43. stone.angle -= 360;44. }45. stone.x = mPointX46. + (float) (mRadius * Math.cos(stone.angle * Math.PI /180));47. stone.y = mPointY48. + (float) (mRadius * Math.sin(stone.angle * Math.PI /180));49. }50. }51.52. public RoundSpinView(Context context) {53. super(context);54. }55.56. private BigStone[] mStones;57.58. /** 旋转的中心点 */59. private int mPointX = 0, mPointY = 0;60. /** 旋转半径 */61. private int mRadius = 0;62.63. private int[] mInts = new int[] { 0, 0, 0, 0 };64. /** 标识那个图片应该位于正中间 */65. private int mIn;66.67. public int getmRadius() {68. return mRadius;69. }70.71. public void setmRadius(int mRadius) {72. this.mRadius = mRadius;73. }74.75. public int getmPointX() {76. return mPointX;77. }78.79. public void setmPointX(int mPointX) {80. this.mPointX = mPointX;81. }82.83. public int getmPointY() {84. return mPointY;85. }86.87. public void setmPointY(int mPointY) {88. this.mPointY = mPointY;89. }90.91. /** Sort the elements in one array. */92. public static void sort(int[] data) {93. int len = data.length;94. for (int i = 0; i < len - 1; i++) {95. int temp = 0;96. boolean isExchanged = false;97. for (int j = len - 1; j > i; j--) {98. if (data[j] < data[j - 1]) {99. temp = data[j];100. data[j] = data[j - 1];101. data[j - 1] = temp;102. /** 发生了交换,故将交换标志置为真 */ 103. isExchanged = true;104. }105. }106. /** 本趟排序未发生交换,提前终止算法,提高效率 */ 107. if (!isExchanged) {108. return;109. }110. }111. }112.113. public void fixBoxPosition() {114. for (int i = 0; i < 4; i++) {115. mInts[i] = Math.abs(mStones[i].angle - 90); 116. }117. RoundSpinView.sort(mInts);118. for (int i = 0; i < 4; i++) {119. if (Math.abs(mStones[i].angle - 90) == mInts[0]) { 120. mIn = i;121. break;122. }123. }124. int mO = 0;125. do {126. mStones[mIn].angle = mO * 90 + 90;127. mIn++;128. if (mIn == 4) {129. mIn = 0;130. }131. mO++;132. } while (mO < 4);133. computeCoordinates();134. invalidate();135. }136.137. public void catchClickEvent(float mX, float mY) {138. System.out.println("mDown_x__________" + mDown_x);139. System.out.println("mDown_y__________" + mDown_y);140. for (int i = 0; i < mStones.length; i++) {141. if (mStones[i].angle == 90) {142. mStones[i].bitmap = BitmapFactory.decodeResource( 143. getResources(), R.drawable.icon);144. }145. }146. invalidate();147. }148.149. @Override150. public boolean dispatchTouchEvent(MotionEvent event) {151. switch (event.getAction()) {152. case MotionEvent.ACTION_DOWN:153. mDown_x = event.getX();154. mDown_y = event.getY();155. // catchClickEvent(mDown_x, mDown_y);156. break;157. case MotionEvent.ACTION_MOVE:158. float mDistance_x = event.getX() - mDown_x;159. float mDistance_y = event.getY() - mDown_y;160. computeAngle(mDistance_x, mDistance_y);161. computeCoordinates();162. invalidate();163. break;164. case MotionEvent.ACTION_UP:165. fixBoxPosition();166. break;167. }168. return true;169. }170.171. public void computeAngle(float mX, float mY) {172. int angle = (int) (mX * 0.1);173. if (mX < 0) {174. for (int index = 0; index < STONE_COUNT; index++) { 175. mStones[index].angle = mStones[index].angle - angle; 176. }177. } else if (mX > 0) {178. for (int index = 0; index < STONE_COUNT; index++) { 179. mStones[index].angle = mStones[index].angle - angle; 180. }181. }182. }183.184. /** 计算一次滑动的角度 */185. public int computeCurrentAngle(float x, float y) {186. float distance = (float) Math187. .sqrt(((x - mPointX) * (x - mPointX) + (y - mPointY) 188. * (y - mPointY)));189. int degree = (int) (Math.acos((x - mPointX) / distance) * 180 / Math.PI);190. return degree;191. }192.193. @Override194. public void onDraw(Canvas canvas) {195. canvas.drawPoint(mPointX, mPointY, mPaint);196.197. for (int index = 0; index < STONE_COUNT; index++) {198. if (!mStones[index].isVisible)199. continue;200. drawInCenter(canvas, mStones[index].bitmap, mStones[index].x,201. mStones[index].y);202. // 不想有红线,就注掉下面这句203. // canvas.drawLine(mPointX, mPointY, mStones[index].x, 204. // mStones[index].y, mPaint);205. }206. }207.208. /**209. * 把中心点放到中心处210. *211. * @param canvas212. * @param bitmap213. * @param left214. * @param top215. */216. void drawInCenter(Canvas canvas, Bitmap bitmap, float left, float top) {217. canvas.drawPoint(left, top, mPaint);218. canvas.drawBitmap(bitmap, left - bitmap.getWidth() / 2,219. top - bitmap.getHeight() / 2, null);220. }221.222. class BigStone {223. Bitmap bitmap;224. int angle;225. float x;226. float y;227. boolean isVisible = true;228. }229.}230.复制代码代码有点长,各位可以建个工程运行看下效果.main.xml:Java代码1.<?xml version="1.0" encoding="utf-8"?>2.<RelativeLayoutxmlns:android="/apk/res/android"3. android:layout_width="fill_parent" android:layout_height="fill_parent"4. android:background="@drawable/bg">5. <TextView android:layout_width="fill_parent"6. android:layout_height="wrap_content" android:text="Theanimation is solved." />7. <com.example.view.RoundSpinView8. android:layout_width="320dp" android:layout_height="300dp"android:id="@+id/mSelfView"9. android:layout_alignParentBottom="true" />10.</RelativeLayout>11.复制代码如需了解更多相关知识,请至麦子学院官网查询(/)。
android 渐变透明、伸缩、平移、旋转动画效果
android 渐变透明、伸缩、平移、旋转动画效果import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.view.KeyEvent;import android.view.View;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.view.animation.ScaleAnimation;import android.view.animation.TranslateAnimation;/**•@AlphaAnimation 渐变透明度动画效果•@ScaleAnimation 渐变尺寸伸缩动画效果•@TranslateAnimation 画面转换位置移动动画效果•@RotateAnimation 画面转移旋转动画效果•*/•public class MyViewAnimation extends View {• private Paint paint;• private Bitmap bmp;• private int x = 50;• private Animation mAlphaAnimation;• private Animation mScaleAnimation;• private Animation mTranslateAnimation;• private Animation mRotateAnimation;•public MyViewAnimation(Context context) {super(context);paint = new Paint();paint.setAntiAlias(true);bmp = BitmapFactory.decodeResource(getResources(),R.drawable.icon);this.setFocusable(true);// 只有当该View获得焦点时才会调用onKeyDown方法}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.BLACK);paint.setColor(Color.WHITE);canvas.drawText("Himi", x, 50, paint);// 备注1canvas.drawText("方向键↑ 渐变透明度动画效果", 80,this.getHeight() - 80, paint);canvas.drawText("方向键↓ 渐变尺寸伸缩动画效果", 80,this.getHeight() - 60, paint);canvas.drawText("方向键← 画面转换位置移动动画效果", 80, this.getHeight() - 40, paint);canvas.drawText("方向键→ 画面转移旋转动画效果", 80,this.getHeight() - 20, paint);canvas.drawBitmap(bmp, this.getWidth() / 2- bmp.getWidth() / 2,this.getHeight() / 2- bmp.getHeight() / 2, paint); x += 1;}public boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {// 渐变透明度动画效果mAlphaAnimation = new AlphaAnimation(0.1f, 1.0f);// 第一个参数fromAlpha 为动画开始时候透明度// 第二个参数toAlpha 为动画结束时候透明度// 注意:取值范围[0-1];[完全透明-完全不透明]mAlphaAnimation.setDuration(3000);// //设置时间持续时间为3000 毫秒=3秒this.startAnimation(mAlphaAnimation);} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {// 渐变尺寸伸缩动画效果mScaleAnimation = new ScaleAnimation(0.0f, 2.0f, 1.5f, 1.5f,Animation.RELATIVE_TO_PARENT, 0.5f,Animation.RELATIVE_TO_PARENT, 0.0f);// 第一个参数fromX为动画起始时X坐标上的伸缩尺寸// 第二个参数toX为动画结束时X坐标上的伸缩尺寸// 第三个参数fromY为动画起始时Y坐标上的伸缩尺寸// 第四个参数toY 为动画结束时Y 坐标上的伸缩尺寸// 注意:// 0.0表示收缩到没有// 1.0表示正常无伸缩// 值小于1.0表示收缩// 值大于1.0表示放大// -----我这里1-4参数表明是起始图像大小不变,动画终止的时候图像被放大1.5倍// 第五个参数pivotXType 为动画在X 轴相对于物件位置类型// 第六个参数pivotXValue 为动画相对于物件的X 坐标的开始位置// 第七个参数pivotXType 为动画在Y 轴相对于物件位置类型// 第八个参数pivotYValue 为动画相对于物件的Y 坐标的开始位置// 提示:位置类型有三种,每种效果大家自己尝试哈~这里偷下懒~ // 毕竟亲眼看到效果的区别才记忆深刻~// Animation.ABSOLUTE// 、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENTmScaleAnimation.setDuration(2000);this.startAnimation(mScaleAnimation);} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {// 画面转换位置移动动画效果mTranslateAnimation = new TranslateAnimation(0, 100, 0, 100);// 第一个参数fromXDelta为动画起始时X坐标上的移动位置// 第二个参数toXDelta为动画结束时X坐标上的移动位置// 第三个参数fromYDelta为动画起始时Y坐标上的移动位置// 第四个参数toYDelta 为动画结束时Y 坐标上的移动位置mTranslateAnimation.setDuration(2000);this.startAnimation(mTranslateAnimation);} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {// 画面转移旋转动画效果mRotateAnimation = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);// 第一个参数fromDegrees为动画起始时的旋转角度// 第二个参数toDegrees 为动画旋转到的角度// 第三个参数pivotXType 为动画在X 轴相对于物件位置类型// 第四个参数pivotXValue 为动画相对于物件的X 坐标的开始位置// 第五个参数pivotXType 为动画在Y 轴相对于物件位置类型// 第六个参数pivotYValue 为动画相对于物件的Y 坐标的开始位置mRotateAnimation.setDuration(3000);this.startAnimation(mRotateAnimation);}return super.onKeyDown(keyCode, event);}}</pre>。
Android部分手机拍照后获取的图片被旋转问题的解决方法
Android部分⼿机拍照后获取的图⽚被旋转问题的解决⽅法调⽤Android系统拍照功能后,三星⼿机拍摄后的照⽚被旋转了90度,横着拍给你变成竖的,竖的拍给你变成横的。
其它品牌的⼿机都是正常的,就三星出现这个怪事。
在Android适配上,我原来⼀直以为国内的⼩⽶⼿机够奇葩了,结果还有更奇葩的!你说你没事旋转照⽚⼲啥,实在是猜不透其居⼼何在,纯粹是在给开发者制造⿇烦啊!解决办法是获取到拍照后照⽚被旋转的⾓度,再旋转回去就好了。
具体思路:1、⾸先在调⽤拍照⽅法时,保存拍照后的相⽚原图,得到原图路径,(PhotoBitmapUtils是我⾃⼰写的⼀个⼯具类)String fileName = "";/*** 启动相机拍照*/private void addBitmapShoots() {Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 设置图⽚要保存的根路径+⽂件名fileName = PhotoBitmapUtils.getPhotoFileName(getContext());File file = new File(fileName);if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}}intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));startActivityForResult(intent, OPEN_CAMERA);}2、在获取相机返回的回调⽅法onActivityResult()中,修复被旋转的图⽚并取得修复后的图⽚路径,有了这个路径后就可以展⽰出来了@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);// 获取相机拍照返回if (resultCode == Activity.RESULT_OK && requestCode == OPEN_CAMERA) {// 得到修复后的照⽚路径String filepath = PhotoBitmapUtils.amendRotatePhoto(fileName, getContext());}}PhotoBitmapUtils类:/*** 集合⼀些图⽚⼯具** Created by zhuwentao on 2016-07-22.*/public class PhotoBitmapUtils {/*** 存放拍摄图⽚的⽂件夹*/private static final String FILES_NAME = "/MyPhoto";/*** 获取的时间格式*/public static final String TIME_STYLE = "yyyyMMddHHmmss";/*** 图⽚种类*/public static final String IMAGE_TYPE = ".png";// 防⽌实例化private PhotoBitmapUtils() {}/*** 获取⼿机可存储路径** @param context 上下⽂* @return ⼿机可存储路径*/private static String getPhoneRootPath(Context context) {// 是否有SD卡if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)|| !Environment.isExternalStorageRemovable()) {// 获取SD卡根⽬录return context.getExternalCacheDir().getPath();} else {// 获取apk包下的缓存路径return context.getCacheDir().getPath();}}/*** 使⽤当前系统时间作为上传图⽚的名称** @return 存储的根路径+图⽚名称*/public static String getPhotoFileName(Context context) {File file = new File(getPhoneRootPath(context) + FILES_NAME);// 判断⽂件是否已经存在,不存在则创建if (!file.exists()) {file.mkdirs();}// 设置图⽚⽂件名称SimpleDateFormat format = new SimpleDateFormat(TIME_STYLE, Locale.getDefault()); Date date = new Date(System.currentTimeMillis());String time = format.format(date);String photoName = "/" + time + IMAGE_TYPE;return file + photoName;}/*** 保存Bitmap图⽚在SD卡中* 如果没有SD卡则存在⼿机中** @param mbitmap 需要保存的Bitmap图⽚* @return 保存成功时返回图⽚的路径,失败时返回null*/public static String savePhotoToSD(Bitmap mbitmap, Context context) {FileOutputStream outStream = null;String fileName = getPhotoFileName(context);try {outStream = new FileOutputStream(fileName);// 把数据写⼊⽂件,100表⽰不压缩press(pressFormat.PNG, 100, outStream);return fileName;} catch (Exception e) {e.printStackTrace();return null;} finally {try {if (outStream != null) {// 记得要关闭流!outStream.close();}if (mbitmap != null) {mbitmap.recycle();}} catch (Exception e) {e.printStackTrace();}}}/*** 把原图按1/10的⽐例压缩** @param path 原图的路径* @return 压缩后的图⽚*/public static Bitmap getCompressPhoto(String path) {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = false;options.inSampleSize = 10; // 图⽚的⼤⼩设置为原来的⼗分之⼀Bitmap bmp = BitmapFactory.decodeFile(path, options);options = null;return bmp;}/*** 处理旋转后的图⽚* @param originpath 原图路径* @param context 上下⽂* @return 返回修复完毕后的图⽚路径*/public static String amendRotatePhoto(String originpath, Context context) {// 取得图⽚旋转⾓度int angle = readPictureDegree(originpath);// 把原图压缩后得到Bitmap对象Bitmap bmp = getCompressPhoto(originpath);;// 修复图⽚被旋转的⾓度Bitmap bitmap = rotaingImageView(angle, bmp);// 保存修复后的图⽚并返回保存后的图⽚路径return savePhotoToSD(bitmap, context);}/*** 读取照⽚旋转⾓度** @param path 照⽚路径* @return ⾓度*/public static int readPictureDegree(String path) {int degree = 0;try {ExifInterface exifInterface = new ExifInterface(path);int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree;}/*** 旋转图⽚* @param angle 被旋转⾓度* @param bitmap 图⽚对象* @return 旋转后的图⽚*/public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {Bitmap returnBm = null;// 根据旋转⾓度,⽣成旋转矩阵Matrix matrix = new Matrix();matrix.postRotate(angle);try {// 将原始图⽚按照旋转矩阵进⾏旋转,并得到新的图⽚returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);} catch (OutOfMemoryError e) {}if (returnBm == null) {returnBm = bitmap;}if (bitmap != returnBm) {bitmap.recycle();}return returnBm;}}在调⽤修复图⽚⾓度⽅法的时候需要注意,现在的⼿机像素越来越⼤,拍完后⼀张照⽚有近10M,所以我们需要对图⽚进⾏压缩处理。
Android开发RotateAnimation详解
android中提供了如下4种动画效果:1、AlphaAnimation 透明度动画效果2、ScaleAnimation 缩放动画效果3、TranslateAnimation 位移动画效果4、RotateAnimation 旋转动画效果今天主要讲解RotateAnimation 旋转动画效果的实现方法。
RotateAnimation 参数有:float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue分别是:float fromDegrees:旋转的开始角度。
float toDegrees:旋转的结束角度。
int pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
float pivotXValue:X坐标的伸缩值。
int pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
float pivotYValue:Y坐标的伸缩值。
代码示例:public class MainActivity extends Activity {ImageView image;Button start;Button cancel;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);image = (ImageView) findViewById(R.id.main_img);start = (Button) findViewById(R.id.main_start);cancel = (Button) findViewById(R.id.main_cancel);/** 设置旋转动画 */final RotateAnimation animation =newRotateAnimation(0f,360f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);animation.setDuration(3000);//设置动画持续时间/** 常用方法 *///animation.setRepeatCount(int repeatCount);//设置重复次数//animation.setFillAfter(boolean);//动画执行完后是否停留在执行完的状态//animation.setStartOffset(long startOffset);//执行前的等待时间start.setOnClickListener(new OnClickListener() {public void onClick(View arg0) {image.setAnimation(animation);/** 开始动画 */animation.startNow();}});cancel.setOnClickListener(new OnClickListener() {public void onClick(View v) {/** 结束动画 */animation.cancel();}});}}更多android视频学习教程,请至麦子学院官网查看>>/course/2/。
Android动画机制与使用技巧
Android动画机制与使⽤技巧动画效果⼀直是⼈机交互中⾮常重要的部分,与死板、突兀的显⽰效果不同,动画效果的加⼊,让交互变得更加友好,特别是在提⽰、引导类的场景中,合理地使⽤动画能让⽤户获得更加愉悦的使⽤体验⼀、Android View动画框架Animation框架定义了透明度、旋转、缩放、位移等⼏种常见的动画实现原理:每次绘制View时,ViewGroup中的drawChild函数获取该view的Animation的Transformation值,然后调⽤canvas.concat(transformToApply.getMatrix())通过矩阵运算完成帧动画,如果动画没有完成,就继续调⽤invalidate() 函数,启动下次绘制来驱动动画,从⽽完成整个动画的绘制。
⼆、帧动画帧动画就是⼀张张图⽚不同的切换,形成的动画效果。
⼀般⼿机的开机动画,应⽤的等待动画等都是帧动画,因为只需要⼏张图⽚轮播,极其节省资源,如果真的设计成动画,那么是很耗费资源的事。
在res⽬录下新建⼀个drawable⽂件夹并定义xml⽂件,⼦节点为 animation-list,在这⾥定义要显⽰的图⽚和每张图⽚的显⽰时长。
<animation-list xmlns:android="/apk/res/android"android:oneshot="false"><!-- false表⽰循环播放,true表⽰只播放⼀次 --><item android:drawable="@drawable/g1" android:duration="200" /><item android:drawable="@drawable/g2" android:duration="200" /><item android:drawable="@drawable/g3" android:duration="200" /><item android:drawable="@drawable/g4" android:duration="200" /><item android:drawable="@drawable/g5" android:duration="200" /><item android:drawable="@drawable/g6" android:duration="300" /><item android:drawable="@drawable/g7" android:duration="400" /><!-- 慢动作 --><item android:drawable="@drawable/g8" android:duration="500" /><item android:drawable="@drawable/g9" android:duration="200" /><item android:drawable="@drawable/g10" android:duration="200" /><item android:drawable="@drawable/g11" android:duration="200" /></animation-list>在屏幕上播放帧动画,需要布局⽂件有⼀个ImageView来显⽰动画图⽚public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);ImageView iv = (ImageView) findViewById(R.id.iv);//把动画⽂件设置为imageView的背景iv.setBackgroundResource(R.drawable.frameanimation);AnimationDrawable ad = (AnimationDrawable) iv.getBackground();//播放动画ad.start();}}三、补间动画(视图动画)组件由原始状态向终极状态转变时,为了让过渡更⾃然,⽽⾃动⽣成的动画叫做补间动画。
Android开发—Android gallery图片左右循环旋转
第一步初始化gallery时设置较大的初始化位置1 2 3 Gallery gallery =((Gallery) findViewById(R.id.myGallery1));gallery.setAdapter(new ImageAdapter(this));gallery.setSelection(200);第二步:重写BaseAdapter方法中的getCount时返回一个较大的值:1 2 3 4 5 // 为了使资源循环使用public int getCount(){return Integer.MAX_VALUE;}第三步:重写BaseAdapter时使用用position对集合大小取余的值,如下:1 2 3 4 5 6 7 8 9101112131415161718 /* 取得目前欲显示的图像View,传入数组ID值使之读取与成像*/ public View getView(int position, View convertView, ViewGroup parent) {/* 创建一个ImageView对象*/ImageView i =new ImageView(this.myContext);i.setPadding(10, 10, 10, 10);i.setAlpha(80);// i.setImageResource(this.myImageIds[position]);if(position<0){position =position+myImageIds.length;}i.setImageResource(this.myImageIds[position% myImageIds.length]);i.setScaleType(ImageView.ScaleType.FIT_XY);i.setBackgroundResource(mGalleryItemBackground);/* 设置这个ImageView对象的宽高,单位为dip */i.setLayoutParams(new youtParams(85, 72));return i;}以下是该类的完整代码:1 2 3/* 依据距离中央的位移量利用getScale返回views的大小(0.0f to 1.0f) */ package irdc.ex03_15;4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647 import android.app.Activity;import android.content.Context;import android.content.res.TypedArray;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.Gallery;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import android.widget.AdapterView.OnItemSelectedListener;public class EX03_15 extends Activity{private TextView mT extView01;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(yout.main);Gallery gallery =((Gallery) findViewById(R.id.myGallery1));gallery.setAdapter(new ImageAdapter(this));gallery.setSelection(200);gallery.setOnItemSelectedListener(new OnItemSelectedListener(){public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3){Toast.makeText(EX03_15.this, "当前位置:"+ arg2, Toast.LENGTH_SHORT).show();}public void onNothingSelected(AdapterView<?> arg0){}});}4849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 public class ImageAdapter extends BaseAdapter{/* 类成员myContext为Context父类*/private Context myContext;/*声明GalleryItemBackground*/int mGalleryItemBackground;/* 使用android.R.drawable里的图片作为图库来源,类型为整数数组*/ private int[] myImageIds ={ R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4,R.drawable.a5, R.drawable.a27};/* 构造器只有一个参数,即要存储的Context */public ImageAdapter(Context c){myContext = c;/** 使用在res/values/attrs.xml中的<declare-styleable>定义的Gallery属性.*/TypedArray a = obtainStyledAttributes(R.styleable.Gallery);/* 取得Gallery属性的Index id */mGalleryItemBackground = a.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0);/* 让对象的styleable属性能够反复使用*/a.recycle();}/* 返回所有已定义的图片总数量*/// public int getCount() { return this.myImageIds.length; }// 为了使资源循环使用public int getCount(){return Integer.MAX_VALUE;}/* 利用getItem方法,取得目前容器中图像的数组ID */public Object getItem(int position){return position;}9293949596979899 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122public long getItemId(int position){return position;}/* 取得目前欲显示的图像View,传入数组ID值使之读取与成像*/public View getView(int position, View convertView, ViewGroup parent) {/* 创建一个ImageView对象*/ImageView i =new ImageView(this.myContext);i.setPadding(10, 10, 10, 10);i.setAlpha(80);// i.setImageResource(this.myImageIds[position]);if(position<0){position =position+myImageIds.length;}i.setImageResource(this.myImageIds[position% myImageIds.length]);i.setScaleType(ImageView.ScaleType.FIT_XY);i.setBackgroundResource(mGalleryItemBackground);/* 设置这个ImageView对象的宽高,单位为dip */i.setLayoutParams(new youtParams(85, 72));return i;}/* 依据距离中央的位移量利用getScale返回views的大小(0.0f to 1.0f) */ public float getScale(boolean focused, int offset){return Math.max(0, 1.0f /(float)Math.pow(2, Math.abs(offset)));}}}。
AndroidUI设计系列之ImageView实现ProgressBar旋转效果(1)
AndroidUI设计系列之ImageView实现ProgressBar旋转效果(1)提起ProgressBar,想必⼤家都⽐较熟悉,使⽤起来也是⽐较⽅便,直接在XML⽂件中引⽤,然后添加属性,运⾏就OK了,虽然使⽤ProgressBar很⽅便但是在我们开发的每⼀个应⽤基本上都有⾃⼰的主体风格,如果使⽤了系统⾃带的效果图,给⼈的感觉是和总体风格太不搭配了,看上去很是别扭,我们⾃⼰开发也觉得不爽,于是就想着⾃定义⼀下效果,其实⾃定义ProgressBar的效果也不难,⼤概可分为三步⾛吧:⼀、在anim⽂件夹下使⽤animation-list定义动画集<?xml version="1.0" encoding="UTF-8"?><animation-list android:oneshot="false" xmlns:android="/apk/res/android"><item android:duration="50" android:drawable="@drawable/circle_10001" /><item android:duration="50" android:drawable="@drawable/circle_10002" /><item android:duration="50" android:drawable="@drawable/circle_10003" /><item android:duration="50" android:drawable="@drawable/circle_10004" /><item android:duration="50" android:drawable="@drawable/circle_10005" /><item android:duration="50" android:drawable="@drawable/circle_10006" /><item android:duration="50" android:drawable="@drawable/circle_10007" /></animation-list>⼆、在style.xml⽂件中定义风格<style name="CircleProgressStyle" parent="@android:style/rge"><item name="android:indeterminateDrawable">@anim/anim_progress_circle</item></style>三、在使⽤ProgressBar的xml⽂件中设置其style<ProgressBarandroid:layout_width="50dip"android:layout_height="50dip"style="@style/CircleProgressStyle"/>通过以上步骤,基本上就可以实现⾃⼰想要的效果了,这也是我在开发中⼀直习惯使⽤的⽅式,当然了使⽤其它⽅式同样可以实现这种效果,今天我主要是想讲⼀下使⽤AnimationDrawable 和ImageView结合来实现上述效果,所以以上⽅法就不再详解了(如果⼤家想了解其它的⽅式,留你邮箱,给你回信)。
Android 图片的翻转和旋转
Android 图片的翻转和旋转翻转方法:Java代码:Java代码1Resourcesres=this.getContext().getResources();2img=BitmapFactory.decodeResource(res,R.drawable.slogo);3Matrixmatrix=newMatrix();4matrix.postRotate(90);/*翻转90度*/5intwidth=img.getWidth();6intheight=img.getHeight();7r_img=Bitmap.createBitmap(img,0,0,width,height,matrix,true);8然后可以直接把r_imgdraw到画布上,例如:canvas.drawBitmap(a_img, 10, 10, p);很简单吧~~ 貌似实现很多动画效果也有很多系统函数可用Matrix是一个处理翻转、缩放等图像效果的重要类Matrix.postScale可设置缩放比例,默认为1。
画图时图片的旋转可参考下面的代码:java代码:JA V A代码9publicvoidrun(){10intx0=50;11inty0=50;12intx1=200;13inty1=200;14Canvasg;15Paintpaint=newPaint();16Bitmapimg=Bitmap.createBitmap(x1-x0,y1-y0,Bitmap.Config.ARGB_8888);17g=newCanvas(img);18paint.setColor(Color.BLUE);19g.drawRect(newRectF(0,0,x1-x0,y1-y0),paint);20paint.setColor(Color.RED);21g.drawText("N",(x1-x0)/2,10,paint);22g.drawText("W",0,(y1-y0)/2,paint);23g.drawText("S",(x1-x0)/2,y1-y0,paint);24g.drawText("E",x1-x0-10,(y1-y0)/2,paint);25while(blRun)26{27g=holder.lockCanvas();//获取画布28paint.setColor(Color.RED);29g.drawLine((x0+x1)/2,0,(x0+x1)/2,480,paint);30g.drawLine(0,(y0+y1)/2,320,(y0+y1)/2,paint);31g.save();32g.rotate(180,(x0+x1)/2,(y0+y1)/2);33g.drawBitmap(img,x0,y0,paint);34paint.setColor(Color.BLUE);35g.restore();36g.drawLine(0,0,320,480,paint);37holder.unlockCanvasAndPost(g);//解锁画布,提交画好的图像38System.out.println("run");39}4041}。
Android变形(Transform)之Matrix用法
Android变形(Transform)之Matrix用法引言最近在研究Android的变形,Android的2D变形(包括缩放,扭曲,平移,旋转等)可以通过Matrix来实现,3D变形可以通过Camera来实现。
接下来就将我这俩天研究的东西和大家分享下,先来看看Matrix的用法。
效果图变形以后Matrix矩阵坐标变换矩阵,即一个3*3的矩阵,用来对图形进行坐标变换。
图1.1 A为坐标矩阵,C为原始矩阵,R是A和C矩阵相乘记过,那么可以知道:(矩阵知识,大学没学好的伤不起啊)x' = a*x + b*y + cy' = d*x + b*y + f最后一列很少有资料提到,不过初始值g=h=0,大家可以去改变值试试,变化为3D效果,但是值没看出规律,那么i为缩放比例,初始值为1。
初始化坐标矩阵为{1,0,0, 0,1,0, 0,0,1}上面讲到的是基本的算法,那么具体这个矩阵x行x列的值代表上面呢,不防简单的来看看如果A={1,0,100, 0,1,-100, 0,0,2},那么可以算出来x' = x + 100;y' = y - 100;也即在原始的基础上右移100,上移100,单位为像素。
第三列第三行为2,表示为以前比例的1/2,记住这块容易弄错。
下面给出具体坐标对应变形的属性|scaleX, skewX, translateX||skewY, scaleY, translateY||0 ,0 , scale |实践通过代码来看看具体的用法复制代码代码如下:public class MatrixTransformView extends View {private Matrix mMatrix;private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);private Bitmap mBitmap;public MatrixTransformView(Context context) {super(context);}public MatrixTransformView(Context context, AttributeSet attrs) {super(context, attrs);}public void setDrawable(int resId) {mBitmap = BitmapFactory.decodeResource(getContext().getResources(), resId);}/** 设置矩阵,并重绘*/public void setMatrixValues(float[] array) {if (mMatrix == null) {mMatrix = new Matrix();}mMatrix.reset();mMatrix.setValues(array);invalidate();public void resetMatrix() {if (mMatrix != null) {mMatrix.reset();}invalidate();}@Overrideprotected void onDraw(Canvas canvas) {if (mMatrix != null) {Paint paint = mPaint;canvas.drawBitmap(mBitmap, mMatrix, paint);}super.onDraw(canvas);}}通过Matrix的setValues方法,将3*3的矩阵坐标值进行设置即可。
Android实现图片反转、翻转、旋转、放大和缩小
Android实现图⽚反转、翻转、旋转、放⼤和缩⼩**********************************************************************android 实现图⽚的翻转**********************************************************************Resources res = this.getContext().getResources();img = BitmapFactory.decodeResource(res, R.drawable.aa);Matrix matrix = new Matrix();matrix.postRotate(180); /*翻转180度*/int width = img.getWidth();int height = img.getHeight();img_a = Bitmap.createBitmap(img, 0, 0, width, height, matrix, true);然后可以直接把img_a draw到画布上,canvas.drawBitmap(img_a, 10, 10, p);Matrix 是⼀个处理翻转、缩放等图像效果的重要类,Matrix.postScale 可设置缩放⽐例,默认为1**********************************************************************android 实现图⽚的旋转**********************************************************************public class ex04_22 extends Activity{private ImageView mImageView;private Button btn1,btn2;private TextView mTextView;private AbsoluteLayout layout1;private int ScaleTimes=1,ScaleAngle=1;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.main);mImageView=(ImageView)findViewById(R.id.myImageView);final Bitmap bmp=BitmapFactory.decodeResource(this.getResources(),R.drawable.ex04_22_1);final int widthOrig=bmp.getWidth();final int heightOrig=bmp.getHeight();mImageView.setImageBitmap(bmp);btn1=(Button)findViewById(R.id.myButton1);btn1.setOnClickListener(new OnClickListener(){public void onClick(View v){ScaleAngle--;if(ScaleAngle<-60){ScaleAngle=-60;}int newWidth=widthOrig*ScaleTimes;int newHeight=heightOrig*ScaleTimes;float scaleWidth=((float)newWidth)/widthOrig;float scaleHeight=((float)newHeight)/heightOrig;Matrix matrix=new Matrix();matrix.postScale(scaleWidth, scaleHeight);matrix.setRotate(5*ScaleAngle);Bitmap resizeBitmap=Bitmap.createBitmap(bmp, 0, 0, widthOrig, heightOrig, matrix, true);BitmapDrawable myNewBitmapDrawable=new BitmapDrawable(resizeBitmap);mImageView.setImageDrawable(myNewBitmapDrawable);}});btn2=(Button)findViewById(R.id.myButton2);btn2.setOnClickListener(new OnClickListener(){public void onClick(View v){ScaleAngle++;if(ScaleAngle>60){ScaleAngle=60;}int newWidth=widthOrig*ScaleTimes;int newHeight=heightOrig*ScaleTimes;float scaleWidth=((float)newWidth)/widthOrig;float scaleHeight=((float)newHeight)/heightOrig;Matrix matrix=new Matrix();matrix.postScale(scaleWidth, scaleHeight);matrix.setRotate(5*ScaleAngle);Bitmap resizeBitmap=Bitmap.createBitmap(bmp, 0, 0, widthOrig, heightOrig, matrix, true);BitmapDrawable myNewBitmapDrawable=new BitmapDrawable(resizeBitmap);mImageView.setImageDrawable(myNewBitmapDrawable);}});}**********************************************************************实现画⾯淡⼊淡出效果可以⽤:setAlpha(alpha);alpha从255,逐渐递减!**********************************************************************如何实现屏幕的滚动效果,这⾥有两个关键点,⼀个是实现OnGestureListener,以便在触摸事件发⽣的时候,被回调。
Android中imageView图片放大缩小及旋转功能示例代码
Android中imageView图⽚放⼤缩⼩及旋转功能⽰例代码⼀、简介⼆、⽅法1)设置图⽚放⼤缩⼩效果第⼀步:将<ImageView>标签中的android:scaleType设置为"fitCenter"android:scaleType="fitCenter"第⼆步:获取屏幕的宽度DisplayMetrics dm=new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);dm.widthPixels第三步:设置seekBar的最⼤progree值为屏幕宽度sb_one.setMax(dm.widthPixels);第四步:设置imageview的布局参数,也就是宽和⾼,也就是画布的宽⾼int width=progress;int height=progress*3/4;iv_pic.setLayoutParams(new youtParams(width, height));2)设置图⽚旋转⽅法第⼀步:给matrix设置⾓度,⽤于新的bitmapprivate Matrix matrix;matrix.setRotate((int)(progress*3.60));第⼆步:获取bitmap资源BitmapDrawable bitmapDrawable=(BitmapDrawable)(getResources().getDrawable(R.drawable.image1));Bitmap bitmap=bitmapDrawable.getBitmap();第三步:重建bitmap⽤于显⽰Bitmap newBitmap=bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,false);第四步:给imageview设置新的bitmapiv_pic.setImageBitmap(newBitmap);三、代码实例效果图:设置⼤⼩和设置旋转的效果图代码:fry.Activity02package fry;import com.example.iamgeViewDemo1.R; import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Matrix;import android.graphics.drawable.BitmapDrawable; import android.os.Bundle;import android.util.DisplayMetrics;import youtParams;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;public class Activity02 extends Activity implements OnSeekBarChangeListener{private ImageView iv_pic;private SeekBar sb_one;private SeekBar sb_two;private Matrix matrix;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsetTitle("imageView实现图⽚缩放和旋转");super.onCreate(savedInstanceState);setContentView(yout.activity02);iv_pic=(ImageView) findViewById(R.id.iv_pic);sb_one=(SeekBar) findViewById(R.id.sb_one);sb_two=(SeekBar) findViewById(R.id.sb_two);//设置SeekBar的progress值改变监听事件sb_one.setOnSeekBarChangeListener(this);sb_two.setOnSeekBarChangeListener(this);matrix=new Matrix();// 1)设置图⽚放⼤缩⼩效果//// 第⼀步:将<ImageView>标签中的android:scaleType设置为"fitCenter"//// 第⼆步:获取屏幕的宽度//// 第三步:设置seekBar的最⼤progree值为屏幕宽度//// 第四步:设置imageview的布局参数,也就是宽和⾼,也就是画布的宽⾼//设置图⽚放⼤缩⼩效果//第⼀步:获取屏幕的宽度DisplayMetrics dm=new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);//第⼆步:设置seekBar的最⼤progree值为屏幕宽度sb_one.setMax(dm.widthPixels);}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stubswitch (seekBar.getId()) {case R.id.sb_one://放⼤或缩⼩int width=progress;int height=progress*3/4;//第三步:设置imageview的布局参数,也就是宽和⾼,也就是画布的宽⾼iv_pic.setLayoutParams(new youtParams(width, height));break;case R.id.sb_two://旋转//设置旋转度数//设置图⽚旋转⽅法//第⼀步:给matrix设置⾓度,⽤于新的bitmapmatrix.setRotate((int)(progress*3.60));//第⼆步:获取bitmap资源BitmapDrawable bitmapDrawable=(BitmapDrawable)(getResources().getDrawable(R.drawable.image1));Bitmap bitmap=bitmapDrawable.getBitmap();//第三步:重建bitmap⽤于显⽰Bitmap newBitmap=bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,false); //第四步:给imageview设置新的bitmapiv_pic.setImageBitmap(newBitmap);break;default:break;}}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}}activity02.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ImageViewandroid:id="@+id/iv_pic"android:layout_width="match_parent"android:layout_height="300dip"android:background="@android:color/black"android:scaleType="fitCenter"android:src="@drawable/image1"/><!-- 设置图⽚的显⽰⽅式:把图⽚按⽐例扩⼤/缩⼩到view的宽度,居中显⽰ --><SeekBarandroid:id="@+id/sb_one"android:layout_width="match_parent"android:layout_height="wrap_content"android:progress="100"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="拖动来缩放图⽚"/><SeekBarandroid:id="@+id/sb_two"android:layout_width="match_parent"android:layout_height="wrap_content"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="拖动来旋转图⽚"/></LinearLayout>四、收获1、设置图像居中显⽰android:scaleType="fitCenter"总结以上所述是⼩编给⼤家介绍的Android中imageView图⽚放⼤缩⼩及旋转功能⽰例代码,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。
如何进行Android应用的屏幕旋转和分屏测试
如何进行Android应用的屏幕旋转和分屏测试屏幕旋转和分屏是现代Android应用中常见的功能,为了确保应用在各种屏幕方向和分屏模式下都能正常运行,开发人员需要进行全面的屏幕旋转和分屏测试。
本文将介绍如何进行Android应用的屏幕旋转和分屏测试,以确保应用在各种场景下都能提供优秀的用户体验。
一、屏幕旋转测试屏幕旋转是指用户将设备从竖屏模式旋转为横屏模式,或者从横屏模式旋转为竖屏模式。
在屏幕旋转过程中,应用的布局和UI必须能够适应新的屏幕方向,并保持数据的一致性。
为了进行屏幕旋转测试,可以按照以下步骤进行:1. 打开Android项目,并找到需要进行屏幕旋转测试的Activity。
2. 点击Android Studio的“Run”按钮,在模拟器或真机上运行应用。
3. 在应用中进行操作,确保应用的UI和数据都能正确响应屏幕的旋转。
4. 使用模拟器或真机的旋转功能,将设备从竖屏模式旋转为横屏模式,或者从横屏模式旋转为竖屏模式。
5. 检查应用在旋转后是否能正确适应新的屏幕方向,以及数据是否保持一致。
6. 反复测试应用在不同屏幕方向下的各种操作,确保应用在任何情况下都能正常工作。
二、分屏测试分屏是指在一个屏幕上同时显示两个应用,用户可以同时使用两个应用进行操作。
为了进行分屏测试,可以按照以下步骤进行:1. 打开Android项目,并找到需要进行分屏测试的Activity。
2. 点击Android Studio的“Run”按钮,在模拟器或真机上运行应用。
3. 在应用中进行操作,确保应用的UI和数据都能正常工作。
4. 使用模拟器或真机的分屏功能,将设备分屏显示应用。
5. 检查应用在分屏模式下是否能正确显示,并且能与其他应用同时运行而不影响功能。
6. 反复测试应用在分屏模式下的各种操作,确保应用在分屏模式下也能提供优秀的用户体验。
三、其他注意事项除了屏幕旋转和分屏测试,还有一些其他注意事项需要开发人员考虑:1. 适配不同屏幕尺寸:在进行屏幕旋转和分屏测试时,还需要确保应用能适配不同屏幕尺寸,以确保在各种设备上都能正常显示。
Android 自定义View消除锯齿实现图片旋转,添加边框及文字说明
先看看图片的效果,左边是原图,右边是旋转之后的图;之所以把这个写出来是因为在一个项目中需要用到这样的效果,我试过用FrameLayout 布局如上的画面,然后旋转FrameLayout,随之而来也就存在了一些问题——锯齿!在网上搜索之后,有两种方法,一是利用Paint,二是利用Canvas;(1)、paint.setAntiAlias(true);paint.setFlags(Paint.ANTI_ALIAS_FLAG);(2)、DrawFilter pfdf = new PaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);canvas.setDrawFilter(pfdf);而如果利用paint,或者canvas,需要从哪获取paint/canvas,这也是一个问题;在实现的过程中,尝试过自定义FrameLayout下面的单个View{ImageView,TextView},但都以失败告终,失败的主要问题在于右图下边的文字描述无法和相片边框相对齐,而且用Matrix旋转背景之后背景大小改变,位置也不在最下边,所以就采用了单独实现一个View的方法,主要原因还是因为自身对Canvas绘图及Paint画笔不是很熟悉,所以导致的效率不高;public class RotateTextImageView extends View {PaintFlagsDrawFilter pfdf;Paint paint;Matrix matrix;Bitmap bitmap;int index = -1;private int oriHeight;private int oriWidth;private int newHeight;private int newWidth;private int angle = 5;protected Path path = new Path();private float[] f = new float[8];private int shawHeight = 20;private int borderSize = 8;Bitmap oriBitmap;private String text = "";public RotateTextImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);initCanvasInfo();}public RotateTextImageView(Context context, AttributeSet attrs) { super(context, attrs);initCanvasInfo();}public RotateTextImageView(Context context) {super(context);initCanvasInfo();}/*** 初始化Paint*/protected void initCanvasInfo() {pfdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG);paint = new Paint();paint.setAntiAlias(true);matrix = new Matrix();matrix.setRotate(5);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);paint.reset();// 消除锯齿paint.setAntiAlias(true);paint.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.setDrawFilter(pfdf);canvas.drawBitmap(bitmap, 0, 0, paint);newHeight = bitmap.getHeight();newWidth = bitmap.getWidth();calculatePoints();// 添加阴影path.reset();path.moveTo(f[0], f[1]);path.lineTo(f[2], f[3]);path.lineTo(f[4], f[5]);path.lineTo(f[6], f[7]);path.close();paint.setStyle(Paint.Style.FILL_AND_STROKE);paint.setColor(Color.parseColor("#96ffffff"));canvas.drawPath(path, paint);// 添加字符if (text != null && !text.equals("")) {path.reset();paint.setTextSize(18);float width = paint.measureText(text);path.moveTo((f[0] + f[2]) / 2, (f[1] + f[3]) / 2);path.lineTo((f[4] + f[6]) / 2, (f[5] + f[7]) / 2);paint.setColor(Color.parseColor("#2b2b2b"));canvas.drawTextOnPath(text, path, (oriWidth - width) / 2, 3, paint);}layout(0, 0, newWidth, newHeight);}/*** 计算坐标值*/private void calculatePoints() {double a = angle * Math.PI / 180;BigDecimal height = new BigDecimal(oriHeight);BigDecimal width = new BigDecimal(oriWidth);BigDecimal cos = new BigDecimal(Math.cos(a));BigDecimal tan = new BigDecimal(Math.tan(a));f[0] = 0;f[1] = height.multiply(cos).floatValue();f[2] = tan.multiply(new BigDecimal(shawHeight)).floatValue();f[3] = (new BigDecimal(f[1])).subtract(new BigDecimal(shawHeight)) .floatValue();f[4] = width.multiply(cos).add(new BigDecimal(f[2])).floatValue();f[5] = new BigDecimal(newHeight - shawHeight).floatValue();f[6] = width.multiply(cos).floatValue();f[7] = new BigDecimal(newHeight).floatValue();}/*** 设置图片** @param bmp*/public void setBitmap(Bitmap bmp) {oriBitmap = bmp;matrix.reset();matrix.setRotate(angle);Bitmap bitmapF = addFrame(bmp);oriHeight = bitmapF.getHeight();oriWidth = bitmapF.getWidth();bitmap = Bitmap.createBitmap(bitmapF, 0, 0, bitmapF.getWidth(),bitmapF.getHeight(), matrix, true);postInvalidate();}/*** 旋转角度** @param angle*/public void setAngle(int angle) {this.angle = angle;setBitmap(oriBitmap);}/*** 设置底部阴影高度** @param shawHeight*/public void setShawHeight(int shawHeight) {this.shawHeight = shawHeight;postInvalidate();}/*** 生成添加了白色边缘的图** @param bmp* @return*/protected Bitmap addFrame(Bitmap bmp) {Bitmap bmpWithBorder = Bitmap.createBitmap(bmp.getWidth() + borderSize* 2, bmp.getHeight() + borderSize * 2, bmp.getConfig());Canvas canvas = new Canvas(bmpWithBorder);canvas.drawColor(Color.WHITE);canvas.drawBitmap(bmp, borderSize, borderSize, null);return bmpWithBorder;}/*** 设置字符串** @param text*/public void setText(String text) {this.text = text;postInvalidate();}/*** 获取字体高度*/protected int getFontHeight() {FontMetrics fm = paint.getFontMetrics();return (int) Math.ceil(fm.descent - fm.top) + 2;}}代码解释:其实没有什么难的东西,只是一些数学运算,代码中每一个方法都有对应的功能注释。
转起来吧!自拍自制3D旋转照片
一
干 净 的 桌 面 (背 景 ) 然 后 将 相 机 ,
在 合 适 的 位 置 放 好 (这个 位 置 确定 后 就 不 要再 改动 ) , 接 着 选取 微 矩模 式 进 行 拍摄 即可 ( 如
图O ) 2 0
然是得 不偿 失的 。
内 核 直 接 散 热 法 的概 念 就 是 移 除 CP U金 属 上盖 , 直 接将 散 热 安 装在 CP 内核 之上 。 没有 了金属 上 盖 的 U 阻 档 .CP 内核 产 生 的温 度 可 以 更 容 易被 带 走 。CP U U 内核 温度 的 降低也 能 提升 超频 空 间 ,让超 频高 手 可 以做
快! !快! i 快
总 而言 之 采 用 Wof ae核 心 的 系列 产 品注 定 是 为 l l d DI 生 的。在 笔 者的 超频 操 作 中 ,酷 睿 2双 核 E 5 0 Y而 80
出更 加疯 狂 的事。 在本 次 超频 的过程 中,笔者 也 的确破 轻 易 突 破 4 H G z主 频 大 关 , 相 信 其 他 的 酷 睿 2双 核 坏 了几 颗 E 5 0处理器一 移 除 了它们的上 盖。 80 E 5 0也 能 做 到 这 一 点 。 主 频 稍 低 的 E 4 0和 E 3 0 80 80 80 首先 将 CP U上 盖 朝上 固定 好 ,并 用 妥善 的 方 法保 处理 器也会 是 一把超频 好手 ,但别 忘 了,由于主 频更低 , S 护好 CP U下 部 ,避 免 不必 要的 划伤 和损 坏 。随 后对 金 因此 它们 的倍 频上 限更低 ,这也 意味 着 F B的提升 幅度
属 上 盖进 行加 热 ,使 用 于 固定 上 盖 的环氧 树脂 软化 。接 下 来 用全新 的 剃刀 片小心 割 开 已经软 化 的环氧树 脂 ,成 功 卸下 上盖 。但遗憾 的是 ,上盖虽然 拆 了下来 ,但 CP U 需 要 更 大。 笔者 认 为 ,只 要 主 板 、 内存 和 CPU散 热器 等 关键 设 备 选择 得 当 ,把 CP U超 到 令你 满 意 的 状 态绝
Xara 3D中“多面旋转效果”的操作练习
Xara 3D中“多面旋转效果”的操作练习操作目的:制作出旋转并图片切换的3D效果图片。
操作准备:3D软件、若干张图片,根据希望作品旋转的页数决定准备图片的张数。
操作步骤:1、打开3D软件,点击“文字选项”,删除原来的文字内容,输入一个标题“我敬爱的叔叔阿姨们”(根据图片内容定主题);2、在字体库中选择选择“Wingdings2”(Wingdings 是一个符号字体系列,它将许多字母渲染成各式各样的符号),这时候刚刚输入的文字变成了方框,不要着急接着朝下进行;因为输入的标题的第一个页面中要展示的内容,所以光标在边框的最后闪烁的时候,点击“插入分页符”按钮;3、当在第一行输入了分页符后,光标自动切换到下一行,这时候在字体的“更多”选项栏中鼠标双击选择一个实心圆,然后再点击一下“插入分页栏”;(根据希望展现的图片多少,重复操作本操作。
)4、选中第一行标题,在字体库中选择自己想要的标题字体,将标题的字大小设置为40%;(把标题字的大小设置的目的是让下面的实心圆字符显得更大点)然后点击“确定”。
5、对图片进行基础设置:①在图案选项中选择“文字”;②在阴影选项中“取消阴影”;③在文字挤压选项中将“厚度”设置为1;④利用键盘的“上下左右光标区”调整标题的角度在“正中央”;(当图片处于正面状态的时候,右下角三个数字均为零;)⑤打开灯光,调整灯光的照射角度,让图片显示的光鲜一些;(设置的时候,可以点击“播放”,在旋转的同时调整灯光)当我们预览了播放效果之后,就知道接下来应该对“实心圆”进行操作;需要注意的是:当前看到的圆既不是“按钮”也不是“图形”它是我们在“Wingdings2”字体中选择的一个字符。
当前我们设置的字符页面是6个,第一个是标题页,其他都是“实心圆”页面。
6、选择“显示光标”按钮,然后用键盘左右光标移动的方式,将光标定位在第一个页面“标题页面”;然后在菜单栏的“编辑”中点击“选择页”,①先对标题进行字体的再设置;②在材质选项中点击“载入材质”给标题添加点色彩效果;③在文字斜边效果中选择一个合适效果。
【IT专家】解决android有的手机拍照后上传图片被旋转的问题
解决android有的手机拍照后上传图片被旋转的问题2012/11/22 0 需求:做仿新浪发微博的项目,能够上传图片还有两外一个项目用到手机拍摄图片,这两个都需要把图片上传到服务器 遇到问题:有的手机拍摄的图片旋转90度,有的图片旋转了180度,有的手机是正常的,服务器要求的是正的,这样问题就来了,不能用户发个照片在微博上看到的是被旋转了的啊,另外一个项目里旋转了的图片直接匹配出现问题,这个更严重。
解决:开始的时候在网上没有找到很好的解决办法,谷歌百度的搜了一通,想到第一种解决方式,当手机拍照结束,在返回结果处理里面立即跳转到一个新的页面,在新的页面里让用户自己手动去旋转图片,然后点击确定。
就可以上传到服务器正着的图片了;第二种解决方式,这是在论坛里发现的一个方法,可以获取图片的属性,读取图片的旋转角度。
第一种方式代码: 在onActivityResult里面处理跳转 Intent intent = new Intent(SendMicoBlog.this, RotaingActivity.class);MyApp myApp = (MyApp)getApplication();myApp.setName(bitmap);//修改之后的名称myApp.setPhoto(isPhoto);startActivityForResult(intent, 1);在RotaingActivity里面就可以作相应的旋转处理了 //获取bitmapMyApp myApp = (MyApp)getApplication();bitmap = myApp.getName();System.out.println( RotaingActivity w = + bitmap.getWidth() + H = + bitmap.getHeight());myBitmap = bitmap;myWidth = bitmap.getWidth();myHeight = bitmap.getHeight();// 创建操作图片用的matrix对象matrix = new Matrix();Drawable drawable = ImageDispose.bitmapToDrawable(bitmap);imageView.setBackgroundDrawable(drawable );btnCancel.setOnClickListener(new OnClickListener() {@Overridepublic void。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
看到很多人在问如何实现三维的翻转效果,所以今天在这里简单的给大家分析一下,其实在APIDemo中就有这样一个例子,那么我们就以其为例来学习Android中的翻转动画效果的实现,首先看一下运行效果如下图所示。
Android中并没有提供直接做3D翻转的动画,所以关于3D翻转的动画效果需要我们自己实现,那么我们首先来分析一下Animation 和Transformation。
Animation动画的主要接口,其中主要定义了动画的一些属性比如开始时间,持续时间,是否重复播放等等。
而Transformation中则包含一个矩阵和alpha值,矩阵是用来做平移,旋转和缩放动画的,而alpha值是用来做alpha动画的,要实现3D旋转动画我们需要继承自Animation类来实现,我们需要重载getTransformation和applyTransformation,在getTransformation中Animation会根据动画的属性来产生一系列的差值点,然后将这些差值点传给applyTransformation,这个函数将根据这些点来生成不同的Transformation。
下面是具体实现:1.public class Rotate3dAnimation extends Animation {2.//开始角度3. private final float mFromDegrees;4.//结束角度5. private final float mToDegrees;6.//中心点7. private final float mCenterX;8. private final float mCenterY;9. private final float mDepthZ;10.//是否需要扭曲11. private final boolean mReverse;12.//摄像头13. private Camera mCamera;14. public Rotate3dAnimation(float fromDegrees, float toDegrees,15. float centerX, float centerY, float depthZ, boolean reverse) {16. mFromDegrees = fromDegrees;17. mToDegrees = toDegrees;18. mCenterX = centerX;19. mCenterY = centerY;20. mDepthZ = depthZ;21. mReverse = reverse;22. }23.24. @Override25. public void initialize(int width, int height, int parentWidth, int parentHeight) {26. super.initialize(width, height, parentWidth, parentHeight);27. mCamera = new Camera();28. }29.//生成Transformation30. @Override31. protected void applyTransformation(float interpolatedTime, Transformation t) {32. final float fromDegrees = mFromDegrees;33.//生成中间角度34. float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);35.36. final float centerX = mCenterX;37. final float centerY = mCenterY;38. final Camera camera = mCamera;39.40. final Matrix matrix = t.getMatrix();41.42. camera.save();43. if (mReverse) {44. camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);45. } else {46. camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));47. }48. camera.rotateY(degrees);49.//取得变换后的矩阵50. camera.getMatrix(matrix);51. camera.restore();52.53. matrix.preTranslate(-centerX, -centerY);54. matrix.postTranslate(centerX, centerY);55. }56.}其中包括了旋转的开始和结束角度,中心点、是否扭曲、和一个Camera,这里我们主要分析applyTransformation函数,其中第一个参数就是通过getTransformation函数传递的差指点,然后我们根据这个差值通过线性差值算法计算出一个中间角度degrees,Camera 类是用来实现绕Y轴旋转后透视投影的,因此我们首先通过t.getMatrix()取得当前的矩阵,然后通过camera.translate来对矩阵进行平移变换操作,camera.rotateY进行旋转。
这样我们就可以很轻松的实现3D旋转效果了,该例子的原意是通过一个列表来供用户选择要实现翻转的图像,所以我们分析至少需要定义两个控件:ListView和ImageView(要翻转的图像),主界面的xml布局定义如下所示。
1.<FrameLayout xmlns:android="/apk/res/android"2. android:id="@+id/container"3. android:layout_width="match_parent"4. android:layout_height="match_parent">5.6. <ListView7. android:id="@android:id/list"8. android:persistentDrawingCache="animation|scrolling"9. android:layout_width="match_parent"10. android:layout_height="match_parent"11. android:layoutAnimation="@anim/layout_bottom_to_top_slide" />12.13. <ImageView14. android:id="@+id/picture"15. android:scaleType="fitCenter"16. android:layout_width="match_parent"17. android:layout_height="match_parent"18. android:visibility="gone" />19.20.</FrameLayout>然后准备好需要的资源,在onCreate函数中准备好ListView和ImageView,因为要旋转所以我们需要保存视图的缓存信息,通过setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);可以设置该功能,当我们选择列表中的图像资源后在onItemClick中将选择的资源Id对应的图像设置到ImageView中,然后通过applyRotation来启动一个动画,前面有了Rotate3dAnimation的实现,我们要完成3D翻转动画就很简单,直接构建一个Rotate3dAnimation对象,设置其属性(包括动画监听),这里将动画的监听设置为DisplayNextView,可以用来显示下一个视图,在其中的动画结束监听(onAnimationEnd)中,通过一个县城SwapViews来交换两个画面,交换过程则是设置ImageView和ListView 的显示相关属性,并构建一个Rotate3dAnimation对象,对另一个界面进行旋转即可,然后启动动画,整个转换过程实际上就是将第一个界面从0度转好90度,然后就爱你过第二个界面从90度转到0度,这样就形成了一个翻转动画,完整代码如下,我们也加入了一些必要的注解,大家也可以参考APIDemo中的Transition3d例子。
1.public class Transition3d extends Activity implements2. AdapterView.OnItemClickListener, View.OnClickListener {3.//照片列表4. private ListView mPhotosList;5. private ViewGroup mContainer;6. private ImageView mImageView;7.8.// 照片的名字,用于显示在list中9. private static final String[] PHOTOS_NAMES = new String[] {10. "Lyon",11. "Livermore",12. "Tahoe Pier",13. "Lake Tahoe",14. "Grand Canyon",15. "Bodie"16. };17.18.// 资源id19. private static final int[] PHOTOS_RESOURCES = new int[] {20. R.drawable.photo1,21. R.drawable.photo2,22. R.drawable.photo3,23. R.drawable.photo4,24. R.drawable.photo5,25. R.drawable.photo626. };27.28. @Override29. protected void onCreate(Bundle savedInstanceState) {30. super.onCreate(savedInstanceState);31.32. setContentView(yout.animations_main_screen);33.34. mPhotosList = (ListView) findViewById(android.R.id.list);35. mImageView = (ImageView) findViewById(R.id.picture);36. mContainer = (ViewGroup) findViewById(R.id.container);37.38.// 准备ListView39. final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,40. yout.simple_list_item_1, PHOTOS_NAMES);41.42. mPhotosList.setAdapter(adapter);43. mPhotosList.setOnItemClickListener(this);44.45.// 准备ImageView46. mImageView.setClickable(true);47. mImageView.setFocusable(true);48. mImageView.setOnClickListener(this);49.50.//设置需要保存缓存51. mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);52. }53.54./**55. * Setup a new 3D rotation on the container view.56. *57. * @param position the item that was clicked to show a picture, or -1to show the list58. * @param start the start angle at which the rotation must begin59. * @param end the end angle of the rotation60. */61. private void applyRotation(int position, float start, float end) {62.// 计算中心点63. final float centerX = mContainer.getWidth() / 2.0f;64. final float centerY = mContainer.getHeight() / 2.0f;65.66.// Create a new 3D rotation with the supplied parameter67.// The animation listener is used to trigger the next animation68. final Rotate3dAnimation rotation =69. new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);70. rotation.setDuration(500);71. rotation.setFillAfter(true);72. rotation.setInterpolator(new AccelerateInterpolator());73.//设置监听74. rotation.setAnimationListener(new DisplayNextView(position));75.76. mContainer.startAnimation(rotation);77. }78.79. public void onItemClick(AdapterView parent, View v, int position, longid) {80.// 设置ImageView81. mImageView.setImageResource(PHOTOS_RESOURCES[position]);82. applyRotation(position, 0, 90);83. }84.//点击图像时,返回listview85. public void onClick(View v) {86. applyRotation(-1, 180, 90);87. }88.89./**90. * This class listens for the end of the first half of the animation.91. * It then posts a new action that effectively swaps the views when the container92. * is rotated 90 degrees and thus invisible.93. */94. private final class DisplayNextView implements Animation.AnimationListener {95. private final int mPosition;96.97. private DisplayNextView(int position) {98. mPosition = position;99. }100.101. public void onAnimationStart(Animation animation) {102. }103.//动画结束104. public void onAnimationEnd(Animation animation) {105. mContainer.post(new SwapViews(mPosition));106. }107.108. public void onAnimationRepeat(Animation animation) {109. }110. }111.112./**113. * This class is responsible for swapping the views and start the second114. * half of the animation.115. */116. private final class SwapViews implements Runnable {117. private final int mPosition;118.119. public SwapViews(int position) {120. mPosition = position;121. }122.123. public void run() {124. final float centerX = mContainer.getWidth() / 2.0f; 125. final float centerY = mContainer.getHeight() / 2.0f; 126. Rotate3dAnimation rotation;127.128. if (mPosition > -1) {129.//显示ImageView130. mPhotosList.setVisibility(View.GONE);131. mImageView.setVisibility(View.VISIBLE);132. mImageView.requestFocus();133.134. rotation = new Rotate3dAnimation(90, 180, centerX, c enterY, 310.0f, false);135. } else {136.//返回listview137. mImageView.setVisibility(View.GONE);138. mPhotosList.setVisibility(View.VISIBLE);139. mPhotosList.requestFocus();140.141. rotation = new Rotate3dAnimation(90, 0, centerX, cen terY, 310.0f, false);142. }143.144. rotation.setDuration(500);145. rotation.setFillAfter(true);146. rotation.setInterpolator(new DecelerateInterpolator()); 147.//开始动画148. mContainer.startAnimation(rotation); 149. }150. }151.152.}。