天天看点

Android 滑动效果进阶篇(六)—— 倒影效果

http://blog.csdn.net/sunboy_2050/article/details/7483169

上篇介绍了使用animation实现3d动画旋转翻页效果,现在介绍图片倒影实现,先看效果图

Android 滑动效果进阶篇(六)—— 倒影效果

本示例主要通过自定义gallery和imageadapter(继承自baseadapter)实现

1、倒影绘制

imageadapter继承自baseadapter,详细实现可见 android 滑动效果入门篇(二)—— gallery 这里重点介绍倒影原理及实现

倒影原理:

倒影效果是主要由原图+间距+倒影三部分组成,高度大约为原图的3/2(原图为1、倒影为1/2)

原图,就是我们看到了最开始的图片

间距,是原图与倒影之间的间隙,如:reflectiongap = 4;

倒影,是原图下半部分1/2高度,通过矩阵变换matrix.prescale(1, -1); 获取倒立图片,然后再加上线性遮罩和阴影实现

倒影实现:

[java] view

plaincopyprint?

/** 反射倒影 */  

public boolean createreflectedimages() {  

    final int reflectiongap = 4;  

    int index = 0;  

    for (map<string, object> map : list) {  

        integer id = (integer) map.get("image");  

        bitmap originalimage = bitmapfactory.decoderesource(mcontext.getresources(), id);   // 获取原始图片  

        int width = originalimage.getwidth();  

        int height = originalimage.getheight();  

        matrix matrix = new matrix();  

        matrix.prescale(1, -1);         // 图片矩阵变换(从低部向顶部的倒影)  

        bitmap reflectionimage = bitmap.createbitmap(originalimage, 0, height/2, width, height/2, matrix, false);   // 截取原图下半部分  

        bitmap bitmapwithreflection = bitmap.createbitmap(width, (height + height / 2), config.argb_8888);          // 创建倒影图片(高度为原图3/2)  

        canvas canvas = new canvas(bitmapwithreflection);   // 绘制倒影图(原图 + 间距 + 倒影)  

        canvas.drawbitmap(originalimage, 0, 0, null);       // 绘制原图  

        paint paint = new paint();  

        canvas.drawrect(0, height, width, height + reflectiongap, paint);       // 绘制原图与倒影的间距  

        canvas.drawbitmap(reflectionimage, 0, height + reflectiongap, null);    // 绘制倒影图  

        paint = new paint();  

        lineargradient shader = new lineargradient(0, originalimage.getheight(), 0, bitmapwithreflection.getheight() + reflectiongap, 0x70ffffff, 0x00ffffff, tilemode.clamp);  

        paint.setshader(shader);    // 线性渐变效果  

        paint.setxfermode(new porterduffxfermode(mode.dst_in));     // 倒影遮罩效果  

        canvas.drawrect(0, height, width, bitmapwithreflection.getheight() + reflectiongap, paint);     // 绘制倒影的阴影效果  

        imageview imageview = new imageview(mcontext);  

        imageview.setimagebitmap(bitmapwithreflection);     // 设置倒影图片  

        imageview.setlayoutparams(new mygallery.layoutparams(180, 240));  

        imageview.setscaletype(scaletype.matrix);  

        mimages[index++] = imageview;  

    }  

    return true;  

}  

2、mygallery

自定义gallery来实现倒影图片的浏览与选择

public class mygallery extends gallery {  

    private camera mcamera = new camera();  

    private int mmaxrotationangle = 60;     // 最大旋转角度 60  

    private int mmaxzoom = -120;  

    private int mcoveflowcenter;  

    public mygallery(context context) {  

        super(context);  

        this.setstatictransformationsenabled(true);  

    public mygallery(context context, attributeset attrs) {  

        super(context, attrs);  

    public mygallery(context context, attributeset attrs, int defstyle) {  

        super(context, attrs, defstyle);  

    public int getmaxrotationangle() {  

        return mmaxrotationangle;  

    public void setmaxrotationangle(int maxrotationangle) {  

        mmaxrotationangle = maxrotationangle;  

    public int getmaxzoom() {  

        return mmaxzoom;  

    public void setmaxzoom(int maxzoom) {  

        mmaxzoom = maxzoom;  

    /** 获取gallery的中心x */  

    private int getcenterofcoverflow() {  

        return (getwidth() - getpaddingleft() - getpaddingright()) / 2 + getpaddingleft();  

    /** 获取view的中心x */  

    private static int getcenterofview(view view) {  

        return view.getleft() + view.getwidth() / 2;  

    @override  

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

        mcoveflowcenter = getcenterofcoverflow();  

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

    protected boolean getchildstatictransformation(view child, transformation trans) {  

        final int childcenter = getcenterofview(child);  

        final int childwidth = child.getwidth();  

        int rotationangle = 0;  

        trans.clear();  

        trans.settransformationtype(transformation.type_both);      // alpha 和 matrix 都变换  

        if (childcenter == mcoveflowcenter) {   // 正中间的childview  

            transformimagebitmap((imageview) child, trans, 0);    

        } else {        // 两侧的childview  

            rotationangle = (int) ( ( (float) (mcoveflowcenter - childcenter) / childwidth ) * mmaxrotationangle );  

            if (math.abs(rotationangle) > mmaxrotationangle) {  

                rotationangle = (rotationangle < 0) ? -mmaxrotationangle : mmaxrotationangle;  

            }  

            transformimagebitmap((imageview) child, trans, rotationangle);  

        }  

        return true;  

    private void transformimagebitmap(imageview child, transformation trans, int rotationangle) {  

        mcamera.save();  

        final matrix imagematrix = trans.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);  

        mcamera.rotatey(rotationangle);     // rotationangle 为正,沿y轴向内旋转; 为负,沿y轴向外旋转  

        mcamera.getmatrix(imagematrix);  

        imagematrix.pretranslate(-(imagewidth / 2), -(imageheight / 2));  

        imagematrix.posttranslate((imagewidth / 2), (imageheight / 2));  

        mcamera.restore();  

3、activity

activity中,主要实现自定义gallery的图片填充imageadapter、mygallery选择事件监听、点击事件监听

private void initres(){  

    tvtitle = (textview) findviewbyid(r.id.tvtitle);  

    gallery = (mygallery) findviewbyid(r.id.mygallery);     // 获取自定义的mygallery控件  

    adapter = new imageadapter(this);     

    adapter.createreflectedimages();    // 创建倒影效果  

    gallery.setadapter(adapter);  

    gallery.setonitemselectedlistener(new onitemselectedlistener() {    // 设置选择事件监听  

        @override  

        public void onitemselected(adapterview<?> parent, view view, int position, long id) {  

            tvtitle.settext(adapter.titles[position]);  

        public void onnothingselected(adapterview<?> parent) {  

    });  

    gallery.setonitemclicklistener(new onitemclicklistener() {          // 设置点击事件监听  

        public void onitemclick(adapterview<?> parent, view view, int position, long id) {  

            toast.maketext(main.this, "img " + (position+1) + " selected", toast.length_short).show();  

main.xml布局文件中,通过实现自定义的mygallery,来显示图片集合

[html] view

<?xml version="1.0" encoding="utf-8"?>  

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_width="fill_parent"  

    android:layout_height="fill_parent"  

    android:orientation="vertical" >  

    <textview  

        android:id="@+id/tvtitle"  

        android:layout_width="wrap_content"  

        android:layout_height="wrap_content"  

        android:layout_centerhorizontal="true"  

        android:textsize="16sp" />  

    <com.homer.reflect.mygallery  

        android:id="@+id/mygallery"  

        android:layout_width="fill_parent"  

        android:layout_below="@id/tvtitle"  

        android:layout_margintop="10dip" />  

</relativelayout>  

源码下载

参考推荐:

android实现图片的倒影效果

android中图片倒影、圆角效果重绘

继续阅读