展会信息港展会大全

android通过扩展gallery实现coverflow的效果 图片浏览器代码
来源:互联网   发布日期:2015-10-03 10:43:49   浏览:1814次  

导读:int height = originalImage getHeight(); This will not scale but will flip on the Y axisMatrix matrix = new Matrix();matrix preScale(1, -1); Create a Bitmap with the fl ...

int height = originalImage.getHeight();

// This will not scale but will flip on the Y axis

Matrix matrix = new Matrix();

matrix.preScale(1, -1);

// Create a Bitmap with the flip matrix applied to it.

// We only want the bottom half of the image

Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,

height / 2, width, height / 2, matrix, false);

// Create a new bitmap with same width but taller to fit

// reflection

Bitmap bitmapWithReflection = Bitmap.createBitmap(width,

(height + height / 2), Config.ARGB_8888);

// Create a new Canvas with the bitmap that's big enough for

// the image plus gap plus reflection

Canvas canvas = new Canvas(bitmapWithReflection);

// Draw in the original image

canvas.drawBitmap(originalImage, 0, 0, null);

// Draw in the gap

Paint deafaultPaint = new Paint();

canvas.drawRect(0, height, width, height + reflectionGap,

deafaultPaint);

// Draw in the reflection

canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,

null);

// Create a shader that is a linear gradient that covers the

// reflection

Paint paint = new Paint();

LinearGradient shader = new LinearGradient(0,

originalImage.getHeight(), 0,

bitmapWithReflection.getHeight() + reflectionGap,

0x70ffffff, 0x00ffffff, TileMode.CLAMP);

// Set the paint to use this shader (linear gradient)

paint.setShader(shader);

// Set the Transfer mode to be porter duff and destination in

paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

// Draw a rectangle using the paint with our linear gradient

canvas.drawRect(0, height, width,

bitmapWithReflection.getHeight() + reflectionGap, paint);

ImageView imageView = new ImageView(mContext);

imageView.setImageBitmap(bitmapWithReflection);

imageView

.setLayoutParams(new GalleryFlow.LayoutParams(160, 240));

// imageView.setScaleType(ScaleType.MATRIX);

mImages[index++] = imageView;

}

return true;

}

public int getCount() {

return mImageIds.length;

}

public Object getItem(int position) {

return position;

}

public long getItemId(int position) {

return position;

}

public View getView(int position, View convertView, ViewGroup parent) {

// Use this code if you want to load from resources

/*

* ImageView i = new ImageView(mContext);

* i.setImageResource(mImageIds[position]); i.setLayoutParams(new

* CoverFlow.LayoutParams(350,350));

* i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

*

* //Make sure we set anti-aliasing otherwise we get jaggies

* BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();

* drawable.setAntiAlias(true); return i;

*/

return mImages[position];

}

/**

* Returns the size (0.0f to 1.0f) of the views depending on the

* 'offset' to the center.

/

public float getScale(boolean focused, int offset) {

/ Formula: 1 / (2 ^ offset) */

return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));

}

}

}复制代码

仅仅实现了图片的倒影效果还不够,因为在coverflow中图片切换是有旋转和缩放效果的,而自带的gallery中并没有实现。因此,我们扩展自带的 gallery,实现自己的galleryflow。在原gallery类中,提供了一个方法 getChildStaticTransformation()以实现对图片的变换。我们通过覆写这个方法并在其中调用自定义的 transformImageBitmap( 每个图片与gallery中心的距离 )方法,,即可实现每个图片做相应的旋转和缩放。其中使用了 camera和matrix用于视图变换。具体可参考代码注释。

public class GalleryFlow extends Gallery {

/**

* Graphics Camera used for transforming the matrix of ImageViews

*/

private Camera mCamera = new Camera();

/**

* The maximum angle the Child ImageView will be rotated by

*/

private int mMaxRotationAngle = 60;

/**

* The maximum zoom on the centre Child

*/

private int mMaxZoom = -120;

/**

* The Centre of the Coverflow

*/

private int mCoveflowCenter;

public GalleryFlow(Context context) {

super(context);

this.setStaticTransformationsEnabled(true);

}

public GalleryFlow(Context context, AttributeSet attrs) {

super(context, attrs);

this.setStaticTransformationsEnabled(true);

}

public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

this.setStaticTransformationsEnabled(true);

}

/**

* Get the max rotational angle of the image

*

* @return the mMaxRotationAngle

*/

public int getMaxRotationAngle() {

return mMaxRotationAngle;

}

/**

* Set the max rotational angle of each image

*

* @param maxRotationAngle

*the mMaxRotationAngle to set

*/

public void setMaxRotationAngle(int maxRotationAngle) {

mMaxRotationAngle = maxRotationAngle;

}

/**

* Get the Max zoom of the centre image

*

* @return the mMaxZoom

*/

public int getMaxZoom() {

return mMaxZoom;

}

/**

* Set the max zoom of the centre image

*

* @param maxZoom

*the mMaxZoom to set

*/

public void setMaxZoom(int maxZoom) {

mMaxZoom = maxZoom;

}

/**

* Get the Centre of the Coverflow

*

* @return The centre of this Coverflow.

*/

private int getCenterOfCoverflow() {

return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2

+ getPaddingLeft();

}

/**

* Get the Centre of the View

*

* @return The centre of the given view.

*/

private static int getCenterOfView(View view) {

return view.getLeft() + view.getWidth() / 2;

}

/**

* {@inheritDoc}

*

* @see #setStaticTransformationsEnabled(boolean)

*/

protected boolean getChildStaticTransformation(View child, Transformation t) {

final int childCenter = getCenterOfView(child);

final int childWidth = child.getWidth();

int rotationAngle = 0;

t.clear();

t.setTransformationType(Transformation.TYPE_MATRIX);

if (childCenter == mCoveflowCenter) {

transformImageBitmap((ImageView) child, t, 0);

} else {

rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);

if (Math.abs(rotationAngle) > mMaxRotationAngle) {

rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle

: mMaxRotationAngle;

}

transformImageBitmap((ImageView) child, t, rotationAngle);

}

return true;

}

/**

* This is called during layout when the size of this view has changed. If

* you were just added to the view hierarchy, you're called with the old

* values of 0.

*

* @param w

*Current width of this view.

* @param h

*Current height of this view.

* @param oldw

*Old width of this view.

* @param oldh

*Old height of this view.

*/

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

mCoveflowCenter = getCenterOfCoverflow();

super.onSizeChanged(w, h, oldw, oldh);

}

/**

* Transform the Image Bitmap by the Angle passed

*

* @param imageView

*ImageView the ImageView whose bitmap we want to rotate

* @param t

*transformation

* @param rotationAngle

*the Angle by which to rotate the Bitmap

*/

private void transformImageBitmap(ImageView child, Transformation t,

int rotationAngle) {

mCamera.save();

final Matrix imageMatrix = t.getMatrix();

final int imageHeight = child.getLayoutParams().height;

final int imageWidth = child.getLayoutParams().width;

final int rotation = Math.abs(rotationAngle);

// 在Z轴上正向移动camera的视角,实际效果为放大图片。

// 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。

mCamera.translate(0.0f, 0.0f, 100.0f);

// As the angle of the view gets less, zoom in

if (rotation < mMaxRotationAngle) {

float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));

mCamera.translate(0.0f, 0.0f, zoomAmount);

}

// 在Y轴上旋转,对应图片竖向向里翻转。

// 如果在X轴上旋转,则对应图片横向向里翻转。

mCamera.rotateY(rotationAngle);

mCamera.getMatrix(imageMatrix);

imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));

imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));

mCamera.restore();

}

}复制代码

代码到这里就结束了。有兴趣的话可以自行调整里面的参数来实现更多更炫的效果。

下面是调用的示例:

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.layout_gallery);

Integer[] images = { R.drawable.img0001, R.drawable.img0030,

R.drawable.img0100, R.drawable.img0130, R.drawable.img0200,

R.drawable.img0230, R.drawable.img0300, R.drawable.img0330,

R.drawable.img0354 };

ImageAdapter adapter = new ImageAdapter(this, images);

adapter.createReflectedImages();

GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.gallery_flow);

galleryFlow.setAdapter(adapter);

}复制代码

PS1:

可以看出来这样实现的gallery锯齿问题比较严重。可以在createReflectedImages()使用以下代码:

BitmapDrawable bd = new BitmapDrawable(bitmapWithReflection);

bd.setAntiAlias(true);

...复制代码然后用iv.setImageDrawable(bd);

代替iv.setImageBitmap(bitmapWithReflection);

即可基本消除锯齿。

PS2:

ImageAdapter 有待确定的MemoryLeak问题,貌似的Bitmap的decode方法会造成ML,使用ImageAdapter时多次旋转屏幕后会出现OOM。目前可以通过将使用完毕的bimap调用recycle()方法和设置null并及时调用system.gc()得到一些改善,但是问题并不明显。

庆祝精华和推荐,增加3个PS~

赞助本站

人工智能实验室

相关热词: 图片浏览器 android

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港