Android编程滑动效果之倒影效果实现方法(附demo源码下载)
本文实例讲述了android编程滑动效果之倒影效果实现方法。分享给大家供大家参考,具体如下:
前面介绍了使用《android编程实现3d滑动旋转效果的方法》,现在介绍图片倒影实现,先看效果图
这里主要通过自定义gallery和imageadapter(继承自baseadapter)实现
1、倒影绘制
imageadapter继承自baseadapter,详细实现可见前面关于android gallery的用法。这里重点介绍倒影原理及实现
倒影原理:
倒影效果是主要由原图+间距+倒影三部分组成,高度大约为原图的3/2(原图为1、倒影为1/2)
原图,就是我们看到了最开始的图片
间距,是原图与倒影之间的间隙,如:reflectiongap = 4;
倒影,是原图下半部分1/2高度,通过矩阵变换matrix.prescale(1, -1); 获取倒立图片,然后再加上线性遮罩和阴影实现
倒影实现:
/** 反射倒影 */ 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); this.setstatictransformationsenabled(true); } public mygallery(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); this.setstatictransformationsenabled(true); } 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); } @override 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]); } @override public void onnothingselected(adapterview<?> parent) { } }); gallery.setonitemclicklistener(new onitemclicklistener() { // 设置点击事件监听 @override 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,来显示图片集合
<?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_height="wrap_content" android:layout_below="@id/tvtitle" android:layout_margintop="10dip" /> </relativelayout>
完整实例代码点击此处本站下载。
更多关于android相关内容感兴趣的读者可查看本站专题:《android开发动画技巧汇总》、《android开发入门与进阶教程》及《android控件用法总结》。
希望本文所述对大家android程序设计有所帮助。
上一篇: Python 字符串大小写转换的简单实例
下一篇: 如何获取到浏览器 url 中的参数?
推荐阅读
-
Android编程滑动效果之倒影效果实现方法(附demo源码下载)
-
Android编程实现仿美团或淘宝的多级分类菜单效果示例【附demo源码下载】
-
Android编程基于自定义view实现公章效果示例【附源码下载】
-
Android编程实现简易弹幕效果示例【附demo源码下载】
-
Android编程实现仿QQ发表说说,上传照片及弹出框效果【附demo源码下载】
-
Android编程实现仿易信精美弹出框效果【附demo源码下载】
-
Android编程实现仿美团或淘宝的多级分类菜单效果示例【附demo源码下载】
-
Android编程实现手绘及保存为图片的方法(附demo源码下载)
-
Android编程实现仿优酷旋转菜单效果(附demo源码)
-
Android编程实现手绘及保存为图片的方法(附demo源码下载)