您的位置:首页 > 移动开发 > Android开发

Android实现CoverFlow效果

2012-07-30 20:59 866 查看
先上一张效果图:



上代码,看了代码什么都明白


CoverFlow从Gallery继承过来

viewsource

print?

001
package
com.coverflow;
002
003
import
android.content.Context;
004
import
android.graphics.Camera;
005
import
android.graphics.Matrix;
006
import
android.util.AttributeSet;
007
import
android.view.View;
008
import
android.view.animation.Transformation;
009
import
android.widget.Gallery;
010
import
android.widget.ImageView;
011
012
public
class
CoverFlow
extends
Gallery{
013
014
private
CameramCamera=
new
Camera();
015
private
int
mMaxRotationAngle=
50
;
016
private
int
mMaxZoom=-
380
;
017
private
int
mCoveflowCenter;
018
private
boolean
mAlphaMode=
true
;
019
private
boolean
mCircleMode=
false
;
020
021
public
CoverFlow(Contextcontext){
022
super
(context);
023
this
.setStaticTransformationsEnabled(
true
);
024
}
025
026
public
CoverFlow(Contextcontext,AttributeSetattrs){
027
super
(context,attrs);
028
this
.setStaticTransformationsEnabled(
true
);
029
}
030
031
public
CoverFlow(Contextcontext,AttributeSetattrs,
int
defStyle){
032
super
(context,attrs,defStyle);
033
this
.setStaticTransformationsEnabled(
true
);
034
}
035
036
public
int
getMaxRotationAngle(){
037
return
mMaxRotationAngle;
038
}
039
040
public
void
setMaxRotationAngle(
int
maxRotationAngle){
041
mMaxRotationAngle=maxRotationAngle;
042
}
043
044
public
boolean
getCircleMode(){
045
return
mCircleMode;
046
}
047
048
public
void
setCircleMode(
boolean
isCircle){
049
mCircleMode=isCircle;
050
}
051
052
public
boolean
getAlphaMode(){
053
return
mAlphaMode;
054
}
055
056
public
void
setAlphaMode(
boolean
isAlpha){
057
mAlphaMode=isAlpha;
058
}
059
060
public
int
getMaxZoom(){
061
return
mMaxZoom;
062
}
063
064
public
void
setMaxZoom(
int
maxZoom){
065
mMaxZoom=maxZoom;
066
}
067
068
private
int
getCenterOfCoverflow(){
069
return
(getWidth()-getPaddingLeft()-getPaddingRight())/
2
070
+getPaddingLeft();
071
}
072
073
private
static
int
getCenterOfView(Viewview){
074
return
view.getLeft()+view.getWidth()/
2
;
075
}
076
077
protected
boolean
getChildStaticTransformation(Viewchild,Transformationt){
078
final
int
childCenter=getCenterOfView(child);
079
final
int
childWidth=child.getWidth();
080
int
rotationAngle=
0
;
081
t.clear();
082
t.setTransformationType(Transformation.TYPE_MATRIX);
083
if
(childCenter==mCoveflowCenter){
084
transformImageBitmap((ImageView)child,t,
0
);
085
}
else
{
086
rotationAngle=(
int
)(((
float
)(mCoveflowCenter-childCenter)/childWidth)*mMaxRotationAngle);
087
if
(Math.abs(rotationAngle)>mMaxRotationAngle){
088
rotationAngle=(rotationAngle<
0
)?-mMaxRotationAngle
089
:mMaxRotationAngle;
090
}
091
transformImageBitmap((ImageView)child,t,rotationAngle);
092
}
093
return
true
;
094
}
095
096
/**
097
*这就是所谓的在大小的布局时,这一观点已经发生了改变。如果你只是添加到视图层次,有人叫你旧的观念价值观为0。
098
*
099
*@paramw
100
*Currentwidthofthisview.
101
*@paramh
102
*Currentheightofthisview.
103
*@paramoldw
104
*Oldwidthofthisview.
105
*@paramoldh
106
*Oldheightofthisview.
107
*/
108
protected
void
onSizeChanged(
int
w,
int
h,
int
oldw,
int
oldh){
109
mCoveflowCenter=getCenterOfCoverflow();
110
super
.onSizeChanged(w,h,oldw,oldh);
111
}
112
113
/**
114
*把图像位图的角度通过
115
*
116
*@paramimageView
117
*ImageViewtheImageViewwhosebitmapwewanttorotate
118
*@paramt
119
*transformation
120
*@paramrotationAngle
121
*theAnglebywhichtorotatetheBitmap
122
*/
123
private
void
transformImageBitmap(ImageViewchild,Transformationt,
124
int
rotationAngle){
125
mCamera.save();
126
final
MatriximageMatrix=t.getMatrix();
127
final
int
imageHeight=child.getLayoutParams().height;
128
final
int
imageWidth=child.getLayoutParams().width;
129
final
int
rotation=Math.abs(rotationAngle);
130
mCamera.translate(
0
.0f,
0
.0f,
100
.0f);
131
132
//如视图的角度更少,放大
133
if
(rotation<=mMaxRotationAngle){
134
float
zoomAmount=(
float
)(mMaxZoom+(rotation*
1.5
));
135
mCamera.translate(
0
.0f,
0
.0f,zoomAmount);
136
if
(mCircleMode){
137
if
(rotation<
40
)
138
mCamera.translate(
0
.0f,
155
,
0
.0f);
139
else
140
mCamera.translate(
0
.0f,(
255
-rotation*
2
.5f),
0
.0f);
141
}
142
if
(mAlphaMode){
143
((ImageView)(child)).setAlpha((
int
)(
255
-rotation*
2.5
));
144
}
145
}
146
mCamera.rotateY(rotationAngle);
147
mCamera.getMatrix(imageMatrix);
148
imageMatrix.preTranslate(-(imageWidth/
2
),-(imageHeight/
2
));
149
imageMatrix.postTranslate((imageWidth/
2
),(imageHeight/
2
));
150
mCamera.restore();
151
}
152
}
这个就是CoverFlow类,说明几点:
1.成员函数
mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
其他的变量都可以无视
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的gettersetter函数都可以无视

ImageAdapter适配器:

viewsource

print?

001
package
com.coverflow;
002
003
import
android.content.Context;
004
import
android.graphics.Bitmap;
005
import
android.graphics.BitmapFactory;
006
import
android.graphics.Canvas;
007
import
android.graphics.LinearGradient;
008
import
android.graphics.Matrix;
009
import
android.graphics.Paint;
010
import
android.graphics.PorterDuffXfermode;
011
import
android.graphics.Bitmap.Config;
012
import
android.graphics.PorterDuff.Mode;
013
import
android.graphics.Shader.TileMode;
014
import
android.graphics.drawable.BitmapDrawable;
015
import
android.view.View;
016
import
android.view.ViewGroup;
017
import
android.widget.BaseAdapter;
018
import
android.widget.ImageView;
019
020
import
com.gallery.R;
021
022
public
class
ImageAdapter
extends
BaseAdapter{
023
int
mGalleryItemBackground;
024
private
ContextmContext;
025
private
Integer[]mImageIds={
026
R.drawable.a1,
027
R.drawable.a2,
028
R.drawable.a3,
029
R.drawable.a4,
030
R.drawable.a5};
031
032
public
ImageAdapter(Contextc){
033
mContext=c;
034
}
035
036
public
int
getCount(){
037
return
mImageIds.length;
038
}
039
040
public
ObjectgetItem(
int
position){
041
return
position;
042
}
043
044
public
long
getItemId(
int
position){
045
return
position;
046
}
047
048
public
ViewgetView(
int
position,ViewconvertView,ViewGroupparent){
049
050
ImageViewi=createReflectedImages(mContext,mImageIds[position]);
051
052
i.setLayoutParams(
new
CoverFlow.LayoutParams(
120
,
100
));
053
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
054
055
//设置的抗锯齿
056
BitmapDrawabledrawable=(BitmapDrawable)i.getDrawable();
057
drawable.setAntiAlias(
true
);
058
return
i;
059
}
060
061
public
float
getScale(
boolean
focused,
int
offset){
062
return
Math.max(
0
,
1
.0f/(
float
)Math.pow(
2
,Math.abs(offset)));
063
}
064
065
public
ImageViewcreateReflectedImages(ContextmContext,
int
imageId){
066
067
BitmaporiginalImage=BitmapFactory.decodeResource(mContext.getResources(),imageId);
068
069
final
int
reflectionGap=
4
;
070
071
int
width=originalImage.getWidth();
072
int
height=originalImage.getHeight();
073
074
Matrixmatrix=
new
Matrix();
075
matrix.preScale(
1
,-
1
);
076
077
BitmapreflectionImage=Bitmap.createBitmap(originalImage,
0
,
078
height/
2
,width,height/
2
,matrix,
false
);
079
080
BitmapbitmapWithReflection=Bitmap.createBitmap(width,
081
(height+height/
2
),Config.ARGB_8888);
082
083
Canvascanvas=
new
Canvas(bitmapWithReflection);
084
085
canvas.drawBitmap(originalImage,
0
,
0
,
null
);
086
087
PaintdeafaultPaint=
new
Paint();
088
canvas.drawRect(
0
,height,width,height+reflectionGap,deafaultPaint);
089
090
canvas.drawBitmap(reflectionImage,
0
,height+reflectionGap,
null
);
091
092
Paintpaint=
new
Paint();
093
LinearGradientshader=
new
LinearGradient(
0
,originalImage
094
.getHeight(),
0
,bitmapWithReflection.getHeight()
095
+reflectionGap,
0x70ffffff
,
0x00ffffff
,TileMode.MIRROR);
096
097
paint.setShader(shader);
098
099
paint.setXfermode(
new
PorterDuffXfermode(Mode.DST_IN));
100
101
canvas.drawRect(
0
,height,width,bitmapWithReflection.getHeight()
102
+reflectionGap,paint);
103
104
ImageViewimageView=
new
ImageView(mContext);
105
imageView.setImageBitmap(bitmapWithReflection);
106
107
return
imageView;
108
}
109
110
}
BitmapDrawabledrawable=(BitmapDrawable)i.getDrawable();
drawable.setAntiAlias(true);
是保证图片绕Y旋转了以后不会出现锯齿.

下面是Activity:

viewsource

print?

01
package
com.coverflow;
02
03
import
android.app.Activity;
04
import
android.graphics.Color;
05
import
android.os.Bundle;
06
07
import
com.gallery.R;
08
09
public
class
HelloAndroid
extends
Activity{
10
/**Calledwhentheactivityisfirstcreated.*/
11
@Override
12
public
void
onCreate(BundlesavedInstanceState){
13
super
.onCreate(savedInstanceState);
14
15
CoverFlowcf=
new
CoverFlow(
this
);
16
//cf.setBackgroundResource(R.drawable.shape);
17
cf.setBackgroundColor(Color.BLACK);
18
cf.setAdapter(
new
ImageAdapter(
this
));
19
ImageAdapterimageAdapter=
new
ImageAdapter(
this
);
20
cf.setAdapter(imageAdapter);
21
//cf.setAlphaMode(false);
22
//cf.setCircleMode(false);
23
cf.setSelection(
2
,
true
);
24
cf.setAnimationDuration(
1000
);
25
setContentView(cf);
26
}
27
28
}
参考自:http://www.eoeandroid.com/thread-70209-1-1.htmlhttp://www.apkbus.com/android-18441-1-1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: