本文实例讲述了android编程滑动效果之倒影效果实现方法。分享给大家供大家参考,具体如下:
前面介绍了使用《android编程实现3d滑动旋转效果的方法》,现在介绍图片倒影实现,先看效果图
这里主要通过自定义gallery和imageadapter(继承自baseadapter)实现
1、倒影绘制
imageadapter继承自baseadapter,详细实现可见前面关于android gallery的用法。这里重点介绍倒影原理及实现
倒影原理:
倒影效果是主要由原图+间距+倒影三部分组成,高度大约为原图的3/2(原图为1、倒影为1/2)
原图,就是我们看到了最开始的图片
间距,是原图与倒影之间的间隙,如:reflectiongap = 4;
倒影,是原图下半部分1/2高度,通过矩阵变换matrix.prescale(1, -1); 获取倒立图片,然后再加上线性遮罩和阴影实现
倒影实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/** 反射倒影 */
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来实现倒影图片的浏览与选择
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
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选择事件监听、点击事件监听
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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,来显示图片集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?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程序设计有所帮助。