图片轮换效果实现

 图片轮换效果实现

    昨天晚上写的博客没有了,只好今天重新写一遍,重新学习下吧,首先,看下效果图:

     先看下主类代码:

 

[java]  view plain copy

  1. public class GalleryDemoActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         requestWindowFeature(Window.FEATURE_NO_TITLE);       
  7.         setContentView(R.layout.main);  
  8.           
  9.         Integer[] images = { R.drawable.image01,   
  10.                              R.drawable.image02,   
  11.                              R.drawable.image03,   
  12.                              R.drawable.image04,   
  13.                              R.drawable.image05};  
  14.           
  15.         ImageAdapter adapter = new ImageAdapter(this, images);  
  16.         adapter.createReflectedImages();//创建倒影效果  
  17.         GalleryFlow galleryFlow = (GalleryFlow) this.findViewById(R.id.gallery);  
  18.         galleryFlow.setFadingEdgeLength(0);  
  19.         galleryFlow.setSpacing(10); //图片之间的间距  
  20.         galleryFlow.setAdapter(adapter);  
  21.           
  22.         galleryFlow.setOnItemClickListener(new OnItemClickListener() {  
  23.             public void onItemClick(AdapterView<?> parent, View view,  
  24.                     int position, long id) {  
  25.                 Toast.makeText(getApplicationContext(), String.valueOf(position), Toast.LENGTH_SHORT).show();  
  26.             }  
  27.               
  28.         });  
  29.         galleryFlow.setSelection(4);  
  30.     }  


比较简单,先来看下倒影效果是如何实现的,在ImageAdapter类里找到createReflectedImages()这个方法:

 

 

[java]  view plain copy

  1. /** 
  2.      * 创建倒影效果 
  3.      * @return 
  4.      */  
  5.     public boolean createReflectedImages() {  
  6.      //倒影图和原图之间的距离  
  7.      final int reflectionGap = 4;  
  8.      int index = 0;  
  9.      for (int imageId : mImageIds) {  
  10.           //返回原图解码之后的bitmap对象  
  11.           Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), imageId);  
  12.           int width = originalImage.getWidth();  
  13.           int height = originalImage.getHeight();  
  14.           //创建矩阵对象  
  15.           Matrix matrix = new Matrix();  
  16.             
  17.           //指定一个角度以0,0为坐标进行旋转  
  18.           // matrix.setRotate(30);  
  19.             
  20.           //指定矩阵(x轴不变,y轴相反)  
  21.           matrix.preScale(1, -1);  
  22.             
  23.           //将矩阵应用到该原图之中,返回一个宽度不变,高度为原图1/2的倒影位图  
  24.           Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,  
  25.             height/2, width, height/2, matrix, false);  
  26.             
  27.           //创建一个宽度不变,高度为原图+倒影图高度的位图  
  28.           Bitmap bitmapWithReflection = Bitmap.createBitmap(width,  
  29.             (height + height / 2), Config.ARGB_8888);  
  30.             
  31.           //将上面创建的位图初始化到画布  
  32.           Canvas canvas = new Canvas(bitmapWithReflection);  
  33.           canvas.drawBitmap(originalImage, 0, 0, null);  
  34.             
  35.           Paint deafaultPaint = new Paint();   
  36.           deafaultPaint.setAntiAlias(false);  
  37.     //    canvas.drawRect(0, height, width, height + reflectionGap,deafaultPaint);  
  38.           canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);  
  39.           Paint paint = new Paint();  
  40.           paint.setAntiAlias(false);  
  41.              
  42.           /** 
  43.            * 参数一:为渐变起初点坐标x位置, 
  44.            * 参数二:为y轴位置, 
  45.            * 参数三和四:分辨对应渐变终点, 
  46.            * 最后参数为平铺方式, 
  47.            * 这里设置为镜像Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变 
  48.            */  
  49.           LinearGradient shader = new LinearGradient(0,originalImage.getHeight(), 0,  
  50.                   bitmapWithReflection.getHeight() + reflectionGap,0x70ffffff, 0x00ffffff, TileMode.MIRROR);  
  51.           //设置阴影  
  52.           paint.setShader(shader);  
  53.           paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN));  
  54.           //用已经定义好的画笔构建一个矩形阴影渐变效果  
  55.           canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()+ reflectionGap, paint);  
  56.             
  57.           //创建一个ImageView用来显示已经画好的bitmapWithReflection  
  58.           ImageView imageView = new ImageView(mContext);  
  59.           imageView.setImageBitmap(bitmapWithReflection);  
  60.           //设置imageView大小 ,也就是最终显示的图片大小  
  61.           imageView.setLayoutParams(new GalleryFlow.LayoutParams(200, 300));  
  62.           //imageView.setScaleType(ScaleType.MATRIX);  
  63.           mImages[index++] = imageView;  
  64.      }  
  65.      return true;  
  66.     }  


先获取倒影,然后把倒影和原照片合成一张图片。里面使用到了bitmap的静态方法createBitmap(),看下官方文档:

 

 

[plain]  view plain copy

  1. public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)  
  2.   
  3. Since: API Level 1  
  4. Returns an immutable bitmap from subset of the source bitmap, transformed by the optional matrix. It is initialized with the same density as the original bitmap.  
  5. Parameters  
  6.   
  7. source  The bitmap we are subsetting  
  8. x   The x coordinate of the first pixel in source  
  9. y   The y coordinate of the first pixel in source  
  10. width   The number of pixels in each row  
  11. height  The number of rows  
  12. m   Optional matrix to be applied to the pixels  
  13. filter  true if the source should be filtered. Only applies if the matrix contains more than just translation.  
  14. Returns  
  15.   
  16. A bitmap that represents the specified subset of source  
  17. Throws  
  18.   
  19. IllegalArgumentException    if the x, y, width, height values are outside of the dimensions of the source bitmap.  


  参数x、y就是开始复制的起点坐标,就是从原图的那个坐标点开始复制,width设置复制的宽度,height设置高度。

 

因为代码中注释较详细,这里不再多说。

    下面这段代码是设置渐变效果:

 

[java]  view plain copy

  1. /** 
  2.        * 参数一:为渐变起初点坐标x位置, 
  3.        * 参数二:为y轴位置, 
  4.        * 参数三和四:分辨对应渐变终点, 
  5.        * 最后参数为平铺方式, 
  6.        * 这里设置为镜像Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变 
  7.        */  
  8.       LinearGradient shader = new LinearGradient(0,originalImage.getHeight(), 0,  
  9.               bitmapWithReflection.getHeight() + reflectionGap,0x70ffffff, 0x00ffffff, TileMode.MIRROR);  

    看完倒影,再来看一下偏转,在main.xml文件中:

 

 

[html]  view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical"  
  6.     >  
  7.     <nsouth.jonas.android.GalleryFlow   
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent"  
  10.         android:gravity="center_vertical"  
  11.         android:id="@+id/gallery"  
  12.     />  
  13. </LinearLayout>  


只有一个自定义的GalleryFlow,来看下它的代码:

 

 

[java]  view plain copy

  1. public class GalleryFlow extends Gallery{  
  2.     private Camera mCamera = new Camera();//相机类  
  3.     private int mMaxRotationAngle = 60;//最大转动角度  
  4.     private int mMaxZoom = -280;最大缩放值  
  5.     private int mCoveflowCenter;//半径值  
  6.   
  7.     public GalleryFlow(Context context) {  
  8.         super(context);  
  9.         //支持转换 ,执行getChildStaticTransformation方法  
  10.         this.setStaticTransformationsEnabled(true);  
  11.     }  
  12.       
  13.     public GalleryFlow(Context context, AttributeSet attrs) {  
  14.         super(context, attrs);  
  15.         this.setStaticTransformationsEnabled(true);  
  16.     }  
  17.       
  18.     public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {  
  19.         super(context, attrs, defStyle);  
  20.         this.setStaticTransformationsEnabled(true);  
  21.     }  
  22.       
  23.     /** 
  24.      * 获取旋转最大角度 
  25.      * @return 
  26.      */  
  27.     public int getMaxRotationAngle() {  
  28.         return mMaxRotationAngle;  
  29.     }  
  30.       
  31.     /** 
  32.      * 设置旋转最大角度 
  33.      * @param maxRotationAngle 
  34.      */  
  35.     public void setMaxRotationAngle(int maxRotationAngle) {  
  36.         mMaxRotationAngle = maxRotationAngle;  
  37.     }  
  38.       
  39.     /** 
  40.      * 获取最大缩放值 
  41.      * @return 
  42.      */  
  43.     public int getMaxZoom() {  
  44.         return mMaxZoom;  
  45.     }  
  46.       
  47.     /** 
  48.      * 设置最大缩放值 
  49.      * @param maxZoom 
  50.      */  
  51.     public void setMaxZoom(int maxZoom) {  
  52.         mMaxZoom = maxZoom;  
  53.     }  
  54.       
  55.     /** 
  56.      * 获取半径值 
  57.      * @return 
  58.      */  
  59.     private int getCenterOfCoverflow() {  
  60.         return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2  
  61.                         + getPaddingLeft();  
  62.     }  
  63.       
  64.     /** 
  65.      * @param view 
  66.      * @return 
  67.      */  
  68.     private static int getCenterOfView(View view) {  
  69.         return view.getLeft() + view.getWidth() / 2;  
  70.     }     
  71.       
  72.    //控制gallery中每个图片的旋转(重写的gallery中方法)  
  73.     protected boolean getChildStaticTransformation(View child, Transformation t) {    
  74.         //取得当前子view的半径值  
  75.         final int childCenter = getCenterOfView(child);         
  76.         final int childWidth = child.getWidth();  
  77.         //旋转角度  
  78.         int rotationAngle = 0;  
  79.         //重置转换状态  
  80.         t.clear();  
  81.         //设置转换类型  
  82.         t.setTransformationType(Transformation.TYPE_MATRIX);  
  83.         //如果图片位于中心位置不需要进行旋转  
  84.         if (childCenter == mCoveflowCenter) {  
  85.             transformImageBitmap((ImageView) child, t, 0);  
  86.         } else {  
  87.             //根据图片在gallery中的位置来计算图片的旋转角度  
  88.             rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);  
  89.             System.out.println("rotationAngle:" +rotationAngle);  
  90.             //如果旋转角度绝对值大于最大旋转角度返回(-mMaxRotationAngle或mMaxRotationAngle;)  
  91.             if (Math.abs(rotationAngle) > mMaxRotationAngle) {  
  92.                 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;  
  93.             }  
  94.             transformImageBitmap((ImageView) child, t, rotationAngle);  
  95.         }  
  96.         return true;  
  97.     }  
  98.       
  99.     /** 
  100.      *  
  101.      */  
  102.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  103.         mCoveflowCenter = getCenterOfCoverflow();  
  104.         super.onSizeChanged(w, h, oldw, oldh);  
  105.     }  
  106.       
  107.       
  108.     private void transformImageBitmap(ImageView child, Transformation t,  
  109.                     int rotationAngle) {  
  110.         //对效果进行保存  
  111.         mCamera.save();  
  112.         final Matrix imageMatrix = t.getMatrix();  
  113.         //图片高度  
  114.         final int imageHeight = child.getLayoutParams().height;  
  115.         //图片宽度  
  116.         final int imageWidth = child.getLayoutParams().width;  
  117.           
  118.         //返回旋转角度的绝对值  
  119.         final int rotation = Math.abs(rotationAngle);  
  120.           
  121.         // 在Z轴上正向移动camera的视角,实际效果为放大图片。  
  122.         // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。  
  123.         mCamera.translate(0.0f, 0.0f, 100.0f);  
  124.         // As the angle of the view gets less, zoom in  
  125.         if (rotation < mMaxRotationAngle) {  
  126.             float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));  
  127.             mCamera.translate(0.0f, 0.0f, zoomAmount);  
  128.         }  
  129.         // 在Y轴上旋转,对应图片竖向向里翻转。  
  130.         // 如果在X轴上旋转,则对应图片横向向里翻转。  
  131.         mCamera.rotateY(rotationAngle);  
  132.         mCamera.getMatrix(imageMatrix);  
  133.         imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));  
  134.         imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));  
  135.         mCamera.restore();  
  136.     }  
  137. }  


主要的方法就是:

 

 

[java]  view plain copy

  1. //控制gallery中每个图片的旋转(重写的gallery中方法)  
  2.     protected boolean getChildStaticTransformation(View child, Transformation t) {    
  3.         //取得当前子view的半径值  
  4.         final int childCenter = getCenterOfView(child);         
  5.         final int childWidth = child.getWidth();  
  6.         //旋转角度  
  7.         int rotationAngle = 0;  
  8.         //重置转换状态  
  9.         t.clear();  
  10.         //设置转换类型  
  11.         t.setTransformationType(Transformation.TYPE_MATRIX);  
  12.         //如果图片位于中心位置不需要进行旋转  
  13.         if (childCenter == mCoveflowCenter) {  
  14.             transformImageBitmap((ImageView) child, t, 0);  
  15.         } else {  
  16.             //根据图片在gallery中的位置来计算图片的旋转角度  
  17.             rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);  
  18.             System.out.println("rotationAngle:" +rotationAngle);  
  19.             //如果旋转角度绝对值大于最大旋转角度返回(-mMaxRotationAngle或mMaxRotationAngle;)  
  20.             if (Math.abs(rotationAngle) > mMaxRotationAngle) {  
  21.                 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;  
  22.             }  
  23.             transformImageBitmap((ImageView) child, t, rotationAngle);  
  24.         }  
  25.         return true;  
  26.     }  


先根据图片所处的位置计算出需要旋转的角度,然后进行旋转:

 

 

[java]  view plain copy

  1. //根据图片在gallery中的位置来计算图片的旋转角度  
  2.          rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);  
  3.          System.out.println("rotationAngle:" +rotationAngle);  
  4.          //如果旋转角度绝对值大于最大旋转角度返回(-mMaxRotationAngle或mMaxRotationAngle;)  
  5.          if (Math.abs(rotationAngle) > mMaxRotationAngle) {  
  6.              rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;  
  7.          }  
  8.          transformImageBitmap((ImageView) child, t, rotationAngle);  


主要功能实现是在transformImageBitmap()这个方法:

 

 

[java]  view plain copy

  1. private void transformImageBitmap(ImageView child, Transformation t,  
  2.                     int rotationAngle) {  
  3.         //对效果进行保存  
  4.         mCamera.save();  
  5.         final Matrix imageMatrix = t.getMatrix();  
  6.         //图片高度  
  7.         final int imageHeight = child.getLayoutParams().height;  
  8.         //图片宽度  
  9.         final int imageWidth = child.getLayoutParams().width;  
  10.           
  11.         //返回旋转角度的绝对值  
  12.         final int rotation = Math.abs(rotationAngle);  
  13.           
  14.         // 在Z轴上正向移动camera的视角,实际效果为放大图片。  
  15.         // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。  
  16.         mCamera.translate(0.0f, 0.0f, 100.0f);  
  17.         // As the angle of the view gets less, zoom in  
  18.         if (rotation < mMaxRotationAngle) {  
  19.             float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));  
  20.             mCamera.translate(0.0f, 0.0f, zoomAmount);  
  21.         }  
  22.         // 在Y轴上旋转,对应图片竖向向里翻转。  
  23.         // 如果在X轴上旋转,则对应图片横向向里翻转。  
  24.         mCamera.rotateY(rotationAngle);  
  25.         mCamera.getMatrix(imageMatrix);  
  26.         imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));  
  27.         imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));  
  28.         mCamera.restore();  
  29.     }  


主要进行翻转操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:在HTML中实现背景图片轮换可以通过以下步骤来完成。首先,设置一个div来展示图片,并设置div的大小作为展示范围。然后,将需要轮换图片存储到一个数组中,这样可以更方便地进行遍历来实现图片的播放。最后,可以通过改变背景的链接来切换图片地址,不需要使用JavaScript添加动画效果,这样更加简单。\[1\] 引用\[2\]:在HTML的<head>标签中,可以设置<meta>标签来指定字符集、浏览器兼容性和视口大小等信息。同时,可以设置<title>标签来定义文档的标题。\[2\] 引用\[3\]:在HTML的<style>标签中,可以设置CSS样式来定义图片的宽度和边框等属性。通过设置img元素的样式,可以控制图片的显示效果。\[3\] 综上所述,要实现HTML背景图片轮换,可以使用数组来存储图片地址,并通过改变背景的链接来切换图片。同时,可以使用CSS样式来定义图片的显示效果。 #### 引用[.reference_title] - *1* [简单的HTML网页图片轮播自动切换](https://blog.csdn.net/qq_51727668/article/details/120692167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [HTML背景切换](https://blog.csdn.net/m0_51785393/article/details/125554554)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值