Android超炫图片浏览器代码使用过Android自带的gallery组件的人都知道,gallery实现的效果就是拖动浏览一组图片,相比iphone里也是用于拖动浏览图片的coverflow,显然逊色不少。
实际上,可以通过扩展gallery,通过伪3D变换可以基本实现coverflow的效果。
本文通过源代码解析这一功能的实现。
具体代码作用可参照注释。
最终实现效果如下:要使用gallery,我们必须首先给其指定一个adapter。
在这里,我们实现了一个自定义的ImageAdapter,为图片制作倒影效果。
传入参数为context和程序内drawable中的图片ID数组。
之后调用其中的createReflectedImages()方法分别创造每一个图像的倒影效果,生成对应的ImageView数组,最后在getView()中返回。
/** Copyright (C) 2010 Neil Davies** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** /licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.** This code is base on the Android Gallery widget and was Created* by Neil Davies neild001 'at' gmail dot com to be a Coverflow widget** @author Neil Davies*/public class ImageAdapter extends BaseAdapter {int mGalleryItemBackground;private Context mContext;private Integer[] mImageIds ;private ImageView[] mImages;public ImageAdapter(Context c, int[] ImageIds) {mContext = c;mImageIds = ImageIds;mImages = new ImageView[mImageIds.length];}public boolean createReflectedImages() {// The gap we want between the reflection and the original image final int reflectionGap = 4;int index = 0;for (int imageId : mImageIds) {Bitmap originalImage = BitmapFactory.decodeResource( mContext.getResources(), imageId);int width = originalImage.getWidth();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 flip matrix applied to it.// We only want the bottom half of the imageBitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false);// Create a new bitmap with same width but taller to fit// reflectionBitmap 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 reflectionCanvas canvas = new Canvas(bitmapWithReflection);// Draw in the original imagecanvas.drawBitmap(originalImage, 0, 0, null);// Draw in the gapPaint deafaultPaint = new Paint();canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint);// Draw in the reflectioncanvas.drawBitmap(reflectionImage, 0, height + reflectionGap,null);// Create a shader that is a linear gradient that covers the// reflectionPaint 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 inpaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));// Draw a rectangle using the paint with our linear gradientcanvas.drawRect(0, height, width,bitmapWithReflection.getHeight() + reflectionGap, paint);ImageView imageView = new ImageView(mContext);imageView.setImageBitmap(bitmapWithReflection);imageView.setLayoutParams(new youtParams(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* youtParams(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中并没有实现。