服务器之家

服务器之家 > 正文

Android 使用Gallery实现3D相册(附效果图+Demo源码)

时间:2021-02-04 14:29     来源/作者:Android开发网

今天因为要做一个设置开机画面的功能,主要是让用户可以设置自己的开机画面,应用层需要做让用户选择开机画面图片的功能。所以需要做一个简单的图片浏览选择程序。最后选用gallery作为基本控件。加入了一些炫一点的元素,做成3d滑动效果。下面是demo例子截图:

Android 使用Gallery实现3D相册(附效果图+Demo源码)Android 使用Gallery实现3D相册(附效果图+Demo源码)

这个效果网上已经很多人做出来了,只是这次需要用到,所以自己也实践了一下(这里例子我也是根据网上一些资料编写)。特意找了几张美女图片给大家养养眼,o(∩_∩)o哈!下面针对一些关键代码进行简要说明,需要做这方面东西的朋友可以看看。这篇文章是实用性文章,理论分析不多。

1、重载gallery类
因为需要加入倒影和3d切换的效果,因此我们需要重载gallery类,其中有两个方法我们需要重写,一个是onsizechanged(),另外一个是getchildstatictransformation()。下面我们看看onsizechanged()需要做的事情。

复制代码 代码如下:


    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;
            }
       //根据偏移角度对图片进行处理,看上去有3d的效果。
            transformimagebitmap((imageview) child, trans, rotationangle);
        }

        return true;
    }


上面就是重载gallery的时候,需要注意处理的事情,其实主要就是做图形变化,效果图里面的图片斜着显示就是这里处理的结果,目的就是让人看上去有立体感。

 

2、编写adapter适配器
我们使用很多控件都涉及适配器,就是用来绑定数据源和目标控件的一个中间件。这里我们需要重载baseadapter作为我们gallery的适配器。主要是处理源图像,加入倒影,生成新的数据源图片。

复制代码 代码如下:


public boolean createreflectedforadapter()
    {
        final int reflectiongap = 4;
        final int height = 200;
        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();
            float scale = height / (float)height;

            matrix smatrix = new matrix();
            smatrix.postscale(scale, scale);
            bitmap minibitmap = bitmap.createbitmap(originalimage, 0, 0,
                    originalimage.getwidth(), originalimage.getheight(), smatrix, true);

            //是否原图片数据,节省内存
            originalimage.recycle();

 

            int mwidth = minibitmap.getwidth();
            int mheight = minibitmap.getheight();
            matrix matrix = new matrix();
            // 图片矩阵变换(从低部向顶部的倒影)
            matrix.prescale(1, -1);           
            // 截取原图下半部分
            bitmap reflectionimage = bitmap.createbitmap(minibitmap, 0, mheight/2, mwidth, mheight/2, matrix, false);
            // 创建倒影图片(高度为原图3/2)
            bitmap bitmapwithreflection = bitmap.createbitmap(mwidth, (mheight + mheight / 2), config.argb_8888);   
            // 绘制倒影图(原图 + 间距 + 倒影)
            canvas canvas = new canvas(bitmapwithreflection);   
            // 绘制原图
            canvas.drawbitmap(minibitmap, 0, 0, null);       
            paint paint = new paint();
            // 绘制原图与倒影的间距
            canvas.drawrect(0, mheight, mwidth, mheight + reflectiongap, paint);
            // 绘制倒影图
            canvas.drawbitmap(reflectionimage, 0, mheight + reflectiongap, null);   

            paint = new paint();
            // 线性渐变效果
            lineargradient shader = new lineargradient(0, minibitmap.getheight(), 0, bitmapwithreflection.getheight()
                    + reflectiongap, 0x70ffffff, 0x00ffffff, tilemode.clamp);
            paint.setshader(shader);   
            // 倒影遮罩效果
            paint.setxfermode(new porterduffxfermode(mode.dst_in));       
            // 绘制倒影的阴影效果
            canvas.drawrect(0, mheight, mwidth, bitmapwithreflection.getheight() + reflectiongap, paint);       
            imageview imageview = new imageview(mcontext);
        // 设置倒影图片
            imageview.setimagebitmap(bitmapwithreflection);       
            imageview.setlayoutparams(new galleryview.layoutparams((int)(width * scale),
                    (int)(mheight * 3 / 2.0 + reflectiongap)));
            imageview.setscaletype(scaletype.matrix);
            mimages[index++] = imageview;
        }
        return true;
    }

 

上面其实就是一个图片处理过程,主要做的事情就是生成倒影,效果图里面底下是有倒影的。就是利用上面算法生成。我们在适配器添加图片的时候,会把适配器原生图片进行处理,加入倒影的效果。这个我们在图片初始化的时候就可以调用处理,具体代码可以查看demo里面的代码关系。

具体图片滑动的过程,gallery会帮我们处理好,我们要做的事情其实就是提供添加了特效的图片数据源,以及处理3d显示的变化效果,最后都会提供view作为显示图像给gallery用来显示。

今天主要是说说如何实现gallery的3d显示切换,demo的代码很多是基于网上一些现成效果,感谢这些分享成果的开发者。下面是demo的下载,不清楚的可以把demo下载下来,运行看看效果然后分析一下代码。代码不多,也不是很复杂。

gallery3d例子代码:点击下载

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部