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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/*
* Copyright (C) 2010 Neil Davies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* [url]http://www.apache.org/licenses/LICENSE-2.0[/url]
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This code is base on the Android Gallery widget and was Created
* by Neil Davies neild001 'at' gmail dot com to be a Coverflow widget
*
* @author Neil Davies
*/
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private Integer[] mImageIds ;
private ImageView[] mImages;
public ImageAdapter(Context c, int[] ImageIds) {
mContext = c;
mImageIds = ImageIds;
mImages = new ImageView[mImageIds.length];
}
public boolean createReflectedImages() {
// The gap we want between the reflection and the original image
final int reflectionGap = 4;
int index = 0;
for (int imageId : mImageIds) {
Bitmap originalImage = BitmapFactory.decodeResource(
mContext.getResources(), imageId);
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// Create a Bitmap with the flip matrix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit
// reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint deafaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);
// Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,
null);
// Create a shader that is a linear gradient that covers the
// reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0,
bitmapWithReflection.getHeight() + reflectionGap,
0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width,
bitmapWithReflection.getHeight() + reflectionGap, paint);
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
imageView
.setLayoutParams(new GalleryFlow.LayoutParams(160, 240));
// imageView.setScaleType(ScaleType.MATRIX);
mImages[index++] = imageView;
}
return true;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// Use this code if you want to load from resources
/*
* ImageView i = new ImageView(mContext);
* i.setImageResource(mImageIds[position]); i.setLayoutParams(new
* CoverFlow.LayoutParams(350,350));
* i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
*
* //Make sure we set anti-aliasing otherwise we get jaggies
* BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
* drawable.setAntiAlias(true); return i;
*/
return mImages[position];
}
/**
* Returns the size (0.0f to 1.0f) of the views depending on the
* 'offset' to the center.
*/
public float getScale(boolean focused, int offset) {
/* Formula: 1 / (2 ^ offset) */
return
Math.max(
0
,
1
.0f / (
float
) Math.pow(
2
, Math.abs(offset)));
}
}
}
|
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
public
class
GalleryFlow
extends
Gallery {
/**
* Graphics Camera used for transforming the matrix of ImageViews
*/
private
Camera mCamera =
new
Camera();
/**
* The maximum angle the Child ImageView will be rotated by
*/
private
int
mMaxRotationAngle =
60
;
/**
* The maximum zoom on the centre Child
*/
private
int
mMaxZoom = -
120
;
/**
* The Centre of the Coverflow
*/
private
int
mCoveflowCenter;
public
GalleryFlow(Context context) {
super
(context);
this
.setStaticTransformationsEnabled(
true
);
}
public
GalleryFlow(Context context, AttributeSet attrs) {
super
(context, attrs);
this
.setStaticTransformationsEnabled(
true
);
}
public
GalleryFlow(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
this
.setStaticTransformationsEnabled(
true
);
}
/**
* Get the max rotational angle of the image
*
* @return the mMaxRotationAngle
*/
public
int
getMaxRotationAngle() {
return
mMaxRotationAngle;
}
/**
* Set the max rotational angle of each image
*
* @param maxRotationAngle
*the mMaxRotationAngle to set
*/
public
void
setMaxRotationAngle(
int
maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
/**
* Get the Max zoom of the centre image
*
* @return the mMaxZoom
*/
public
int
getMaxZoom() {
return
mMaxZoom;
}
/**
* Set the max zoom of the centre image
*
* @param maxZoom
*the mMaxZoom to set
*/
public
void
setMaxZoom(
int
maxZoom) {
mMaxZoom = maxZoom;
}
/**
* Get the Centre of the Coverflow
*
* @return The centre of this Coverflow.
*/
private
int
getCenterOfCoverflow() {
return
(getWidth() - getPaddingLeft() - getPaddingRight()) /
2
+ getPaddingLeft();
}
/**
* Get the Centre of the View
*
* @return The centre of the given view.
*/
private
static
int
getCenterOfView(View view) {
return
view.getLeft() + view.getWidth() /
2
;
}
/**
* {@inheritDoc}
*
* @see #setStaticTransformationsEnabled(boolean)
*/
protected
boolean
getChildStaticTransformation(View child, Transformation t) {
final
int
childCenter = getCenterOfView(child);
final
int
childWidth = child.getWidth();
int
rotationAngle =
0
;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if
(childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t,
0
);
}
else
{
rotationAngle = (
int
) (((
float
) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if
(Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle <
0
) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}
return
true
;
}
/**
* This is called during layout when the size of this view has changed. If
* you were just added to the view hierarchy, you're called with the old
* values of 0.
*
* @param w
*Current width of this view.
* @param h
*Current height of this view.
* @param oldw
*Old width of this view.
* @param oldh
*Old height of this view.
*/
protected
void
onSizeChanged(
int
w,
int
h,
int
oldw,
int
oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super
.onSizeChanged(w, h, oldw, oldh);
}
/**
* Transform the Image Bitmap by the Angle passed
*
* @param imageView
*ImageView the ImageView whose bitmap we want to rotate
* @param t
*transformation
* @param rotationAngle
*the Angle by which to rotate the Bitmap
*/
private
void
transformImageBitmap(ImageView child, Transformation t,
int
rotationAngle) {
mCamera.save();
final
Matrix imageMatrix = t.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);
}
// 在Y轴上旋转,对应图片竖向向里翻转。
// 如果在X轴上旋转,则对应图片横向向里翻转。
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth /
2
), -(imageHeight /
2
));
imageMatrix.postTranslate((imageWidth /
2
), (imageHeight /
2
));
mCamera.restore();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.layout_gallery);
Integer[] images = { R.drawable.img0001, R.drawable.img0030,
R.drawable.img0100, R.drawable.img0130, R.drawable.img0200,
R.drawable.img0230, R.drawable.img0300, R.drawable.img0330,
R.drawable.img0354 };
ImageAdapter adapter =
new
ImageAdapter(
this
, images);
adapter.createReflectedImages();
GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.gallery_flow);
galleryFlow.setAdapter(adapter);
}
|