Android Gallery画廊 兼容4.0以上版本
来源:互联网 发布:java实现微信发送消息 编辑:程序博客网 时间:2024/05/07 12:25
最近在做Gallery画廊效果时,搜索大量资料,发现很多博主都是2012年写的文章。对于现在的sdk版本,发现拿过来都没有用,效果变形:
非常遗憾,中间的图变形了,或者说没有把转角恢复。
查阅了大量资料后,发现,
4.0以下的版本,调用的是下面的方法:
@Override protected boolean getChildStaticTransformation(View child, Transformation t) { mMatrix = t.getMatrix(); if (android.os.Build.VERSION.SDK_INT > 15) { return false; } else { <span style="white-space:pre"></span>//操作代码 }}
4.0以上版本,调用的是下面的方法:
/** * 核心方法 * @param canvas * @param child * @param drawingTime * @return */ @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { boolean ret; //Android SDK 4.1 if (android.os.Build.VERSION.SDK_INT > 15) { //操作代码 } else { ret = super.drawChild(canvas, child, drawingTime); } return ret; }
修改后兼容4.0以上版本得完整代码:
package com.znke.tv3_test.widgets;import android.content.Context;import android.graphics.Camera;import android.graphics.Canvas;import android.graphics.Matrix;import android.util.AttributeSet;import android.view.View;import android.view.animation.Transformation;import android.widget.Gallery;/** * 兼容4.0以上版本 */@SuppressWarnings("deprecation")public class CommonGallery extends Gallery { private Camera mCamera;//相机类 private int mGalleryCenterX;//gallery容器的中心点位置 private Matrix mMatrix; private int mMaxRotationAngle = 60;//最大转动角度 private boolean isNeedScrollY = true;//是否需要y轴角度旋转 private float xOffset = 80.0f; private float yOffset = 70.0f; private float zOffset = 50.0f; /** * 设置特定的参数 * @param xOffset x轴偏移量 * @param yOffset y轴偏移量 * @param zOffset z轴偏移量 * @param isNeedScrollY 是否需要两侧的图片旋转 * @param mMaxRotationAngle 两侧图片旋转的最大角度 */ public void setGalleryData(float xOffset,float yOffset,float zOffset,boolean isNeedScrollY,int mMaxRotationAngle){ setxOffset(xOffset); setyOffset(yOffset); setzOffset(zOffset); setNeedScrollY(isNeedScrollY); setmMaxRotationAngle(mMaxRotationAngle); } public void setmMaxRotationAngle(int mMaxRotationAngle) { this.mMaxRotationAngle = mMaxRotationAngle; } public void setNeedScrollY(boolean needScrollY) { isNeedScrollY = needScrollY; } public void setxOffset(float xOffset) { this.xOffset = xOffset; } public void setyOffset(float yOffset) { this.yOffset = yOffset; } public void setzOffset(float zOffset) { this.zOffset = zOffset; } public CommonGallery(Context context) { this(context, null, 0); } public CommonGallery(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CommonGallery(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } private void init(Context context, AttributeSet attrs) { //支持转换 ,执行getChildStaticTransformation方法 this.setStaticTransformationsEnabled(true); this.setChildrenDrawingOrderEnabled(true); mCamera = new Camera(); } @Override protected int getChildDrawingOrder(int childCount, int i) { // Current selected index. int selectedIndex = getSelectedItemPosition() - getFirstVisiblePosition(); if (selectedIndex < 0) { return i; } if (i < selectedIndex) { return i; } else if (i >= selectedIndex) { return childCount - 1 - i + selectedIndex; } else { return i; } } protected void onSizeChanged(int w, int h, int oldw, int oldh) { mGalleryCenterX = getGalleryCenterX(); super.onSizeChanged(w, h, oldw, oldh); } //获取父控件中心点 X 的位置 protected int getGalleryCenterX() { // + 比 >> 优先级高, x>>1等于x/2,效率高 return ((getWidth() - getPaddingLeft() - getPaddingRight()) >> 1) + getPaddingLeft(); } //获取 child 中心点 X 的位置 protected int getChildCenterX(View child) { // + 比 >> 优先级高 return (child.getWidth() >> 1) + child.getLeft(); } //计算 child 偏离 父控件中心的 offset 值, -1 <= offset <= 1 protected float calculateOffsetOfCenter(View view) { final int pCenter = getGalleryCenterX(); final int cCenter = getChildCenterX(view); float offset = (cCenter - pCenter) / (pCenter * 1.0f); //下面两步操作处理,把offset拉回到[-1,1]之间,防止越界 offset = Math.min(offset, 1.0f);//当超出1时,取1 offset = Math.max(offset, -1.0f);//当小于-1时,取-1 return offset; } /** * 计算该view对应的角度 * * @param child * @return */ private int calculateAngle(View child) { int rotateAngle = 0; //获取child的中心点 int childCenterX = getChildCenterX(child); //如果当前child不在中心点,计算出对应的偏移的角度 if (childCenterX != mGalleryCenterX) { // 两个中心点距离 int distance = mGalleryCenterX - childCenterX; float percent = distance * 1.0f / child.getWidth(); rotateAngle = (int) (percent * mMaxRotationAngle);// 得到旋转的角度 // 因为distance有可能大于图片的宽度,所以得到角度有可能大于最大的角度 if (Math.abs(rotateAngle) > mMaxRotationAngle) { rotateAngle = rotateAngle > 0 ? mMaxRotationAngle : -mMaxRotationAngle; } } return rotateAngle; } /** * 核心方法 * @param canvas * @param child * @param drawingTime * @return */ @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { boolean ret; //Android SDK 4.1 if (android.os.Build.VERSION.SDK_INT > 15) { //计算child与中心点的偏移量 final float offset = calculateOffsetOfCenter(child); transformImageBitmap(child,offset); child.setAlpha(1 - Math.abs(offset)); final int saveCount = canvas.save(); canvas.concat(mMatrix); ret = super.drawChild(canvas, child, drawingTime); canvas.restoreToCount(saveCount); } else { ret = super.drawChild(canvas, child, drawingTime); } return ret; } @Override protected boolean getChildStaticTransformation(View child, Transformation t) { mMatrix = t.getMatrix(); if (android.os.Build.VERSION.SDK_INT > 15) { return false; } else { /** * 兼容老版本,VERSION <= 15 才执行 */ //设置变化之前,要把上面的一个动画清除 t.clear(); //设置变化的效果为矩阵类型 t.setTransformationType(Transformation.TYPE_MATRIX); //计算child与中心点的偏移量 final float offset = calculateOffsetOfCenter(child); transformImageBitmap(child,offset); //设置 alpha 变换 t.setAlpha(1 - Math.abs(offset)); return true; } } /** * 图像变换 * @param child * @param offset */ private void transformImageBitmap(View child,float offset){ //获取child的宽高的一半 final int halfWidth = getChildCenterX(child); final int halfHeight = child.getMeasuredHeight() >> 1; mCamera.save(); if(isNeedScrollY){ //是否需要角度旋转 if (halfWidth == mGalleryCenterX) { //正中间的childView mCamera.rotateY(0); } else { //两侧的childView int rotateAngle = calculateAngle(child); mCamera.rotateY(rotateAngle); } } // 平移 X、Y、Z 轴已达到立体效果 mCamera.translate(-offset * xOffset, yOffset, Math.abs(offset) * zOffset); //也可设置旋转效果 mCamera.getMatrix(mMatrix); //以 child 的中心点变换 mMatrix.preTranslate(-halfWidth, -halfHeight); mMatrix.postTranslate(halfWidth, halfHeight); mCamera.restore(); }}
需要说明的是:
1、有的需求对两侧图片的要求是不需要转角,
2、有的对中间图片的大小有要求
3、有的对旁边图片的距离和层叠效果有要求
其实无非就是修改最大转角、是否需要转角、x轴偏移、y轴偏移、z轴偏移等5个参数的修改,故我提供方法:
/** * 设置特定的参数 * @param xOffset x轴偏移量 * @param yOffset y轴偏移量 * @param zOffset z轴偏移量 * @param isNeedScrollY 是否需要两侧的图片旋转 * @param mMaxRotationAngle 两侧图片旋转的最大角度 */ public void setGalleryData(float xOffset,float yOffset,float zOffset,boolean isNeedScrollY,int mMaxRotationAngle){ setxOffset(xOffset); setyOffset(yOffset); setzOffset(zOffset); setNeedScrollY(isNeedScrollY); setmMaxRotationAngle(mMaxRotationAngle); }
其他的逻辑代码都是通用的,根据你自己的需求,只需要设置好这5个参数就可以了。
5 0
- Android Gallery画廊 兼容4.0以上版本
- android 画廊 gallery
- Android--Gallery,画廊
- Android---画廊(Gallery)
- Android gallery画廊
- Android中的画廊(Gallery)
- Android Gallery画廊
- Android控件之Gallery(画廊)
- Android基础--Gallery画廊控件
- android gallery实例(画廊效果)
- android gallery 画廊控件示例
- android学习---Gallery画廊视图
- android之路Gallery 画廊
- Gallery画廊
- Gallery画廊
- Gallery画廊
- 9. android Gallery(画廊)以及BaseAdapter
- 9. android Gallery(画廊)以及BaseAdapter .
- Python 之 if __name__ == '__main__'
- 近期在做一个电商类app,listvise联动让我废了好多力。
- linux内核之块设备四---deadline调度算法
- Visual Studio 使用正则表达式检查代码规范
- LVS+keepalived+nginx+tomcat部署实现
- Android Gallery画廊 兼容4.0以上版本
- hibernate的一对一映射-主键映射-单向-mysql数据库
- 在Ubuntu上安装zsh
- <context:component-scan>使用说明
- HashCode和equal
- [HDU 5741] Helter Skelter (二分)
- 通道的更多类型
- 历届图灵奖 (Turing award)得奖名单
- spring bean id和bean name的区别