Android实现CoverFlow效果
来源:互联网 发布:打字软件手机版 编辑:程序博客网 时间:2024/05/16 18:50
Android实现CoverFlow效果
先上一张效果图:
CoverFlow从Gallery继承过来
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
Camera mCamera =
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(Context context) {
022
super
(context);
023
this
.setStaticTransformationsEnabled(
true
);
024
}
025
026
public
CoverFlow(Context context, AttributeSet attrs) {
027
super
(context, attrs);
028
this
.setStaticTransformationsEnabled(
true
);
029
}
030
031
public
CoverFlow(Context context, AttributeSet attrs,
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(View view) {
074
return
view.getLeft() + view.getWidth() /
2
;
075
}
076
077
protected
boolean
getChildStaticTransformation(View child, Transformation t) {
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
* @param w
100
* Current width of this view.
101
* @param h
102
* Current height of this view.
103
* @param oldw
104
* Old width of this view.
105
* @param oldh
106
* Old height of this view.
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
* @param imageView
117
* ImageView the ImageView whose bitmap we want to rotate
118
* @param t
119
* transformation
120
* @param rotationAngle
121
* the Angle by which to rotate the Bitmap
122
*/
123
private
void
transformImageBitmap(ImageView child, Transformation t,
124
int
rotationAngle) {
125
mCamera.save();
126
final
Matrix imageMatrix = 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这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的getter和setter函数都可以无视
ImageAdapter适配器:
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
Context mContext;
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(Context c) {
033
mContext = c;
034
}
035
036
public
int
getCount() {
037
return
mImageIds.length;
038
}
039
040
public
Object getItem(
int
position) {
041
return
position;
042
}
043
044
public
long
getItemId(
int
position) {
045
return
position;
046
}
047
048
public
View getView(
int
position, View convertView, ViewGroup parent) {
049
050
ImageView i = createReflectedImages(mContext,mImageIds[position]);
051
052
i.setLayoutParams(
new
CoverFlow.LayoutParams(
120
,
100
));
053
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
054
055
// 设置的抗锯齿
056
BitmapDrawable drawable = (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
ImageView createReflectedImages(Context mContext,
int
imageId) {
066
067
Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), imageId);
068
069
final
int
reflectionGap =
4
;
070
071
int
width = originalImage.getWidth();
072
int
height = originalImage.getHeight();
073
074
Matrix matrix =
new
Matrix();
075
matrix.preScale(
1
, -
1
);
076
077
Bitmap reflectionImage = Bitmap.createBitmap(originalImage,
0
,
078
height /
2
, width, height /
2
, matrix,
false
);
079
080
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
081
(height + height /
2
), Config.ARGB_8888);
082
083
Canvas canvas =
new
Canvas(bitmapWithReflection);
084
085
canvas.drawBitmap(originalImage,
0
,
0
,
null
);
086
087
Paint deafaultPaint =
new
Paint();
088
canvas.drawRect(
0
, height, width, height + reflectionGap, deafaultPaint);
089
090
canvas.drawBitmap(reflectionImage,
0
, height + reflectionGap,
null
);
091
092
Paint paint =
new
Paint();
093
LinearGradient shader =
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
ImageView imageView =
new
ImageView(mContext);
105
imageView.setImageBitmap(bitmapWithReflection);
106
107
return
imageView;
108
}
109
110
}
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
是保证图片绕Y旋转了以后不会出现锯齿.
下面是Activity:
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
/** Called when the activity is first created. */
11
@Override
12
public
void
onCreate(Bundle savedInstanceState) {
13
super
.onCreate(savedInstanceState);
14
15
CoverFlow cf =
new
CoverFlow(
this
);
16
// cf.setBackgroundResource(R.drawable.shape);
17
cf.setBackgroundColor(Color.BLACK);
18
cf.setAdapter(
new
ImageAdapter(
this
));
19
ImageAdapter imageAdapter =
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
}
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android实现CoverFlow效果
- Android自定义Gallery,实现CoverFlow效果
- Android自定义Gallery,实现CoverFlow效果
- openFlow实现CoverFlow效果
- Android-Coverflow 效果
- Android中类似于IOS的CoverFlow效果实现源码分析
- wp7 上实现coverflow效果
- Unity3d 脚本实现CoverFlow 效果
- Unity3d 脚本实现CoverFlow 效果
- iOS-coverFlow效果简单实现
- Android 用CoverFlow的效果
- hdu FatMouse and Cheese(dp)
- java学习_Timer相关
- 老大们,请教一下和FAAD 的30 day rev share 靠谱不? 1000美金。
- 游戏中产生全局对象惟一ID的方法
- 京东的投资方是不是活雷锋
- Android实现CoverFlow效果
- 日本各产业不断下降,除了机器人和佳能在上升,汽车成唯一支柱产业
- Linux 下 SSH Session复制
- opencv中的多通道矩阵CvMat元素的访问
- VIEW双缓冲
- leeboy的linux学习笔记一
- Microsoft CRM修改密码页面的编写
- linux shell 字符串操作(长度,查找,替换)详解
- 谈 Spring-Transaction(Spring事务管理 第一篇)