Created
March 6, 2011 04:37
-
-
Save conceptdev/857032 to your computer and use it in GitHub Desktop.
MonoDroid port of a CoverFlow-showing Activity for Android http://twitpic.com/46n72l
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ORIGINAL (JAVA) CODE LICENCE | |
* | |
* 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 | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* 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 | |
*/ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Android.App; | |
using Android.Content; | |
using Android.OS; | |
using Android.Runtime; | |
using Android.Views; | |
using Android.Widget; | |
using Android.Graphics; | |
using Android.Util; | |
using Android.Views.Animations; | |
namespace net.conceptdevelopment.monodroid | |
{ | |
public class coverflow : 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 coverflow(Context context) | |
: base(context) | |
{ | |
//super(context); | |
this.SetStaticTransformationsEnabled(true); | |
} | |
public coverflow(Context context, IAttributeSet attrs) | |
: base(context, attrs) | |
{ | |
//super(context, attrs); | |
this.SetStaticTransformationsEnabled(true); | |
} | |
public coverflow(Context context, IAttributeSet attrs, int defStyle) | |
: base(context, attrs, 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 (Width - PaddingLeft - PaddingRight) / 2 + PaddingLeft; | |
} | |
/** | |
* Get the Centre of the View | |
* @return The centre of the given view. | |
*/ | |
private static int getCenterOfView(View view) | |
{ | |
return view.Left + view.Width / 2; | |
} | |
/** | |
* {@inheritDoc} | |
* | |
* @see #setStaticTransformationsEnabled(boolean) | |
*/ | |
protected override bool GetChildStaticTransformation(View child, Transformation t) | |
{ | |
int childCenter = getCenterOfView(child); | |
int childWidth = child.Width; | |
int rotationAngle = 0; | |
t.Clear(); | |
t.TransformationType = Transformation.TypeMatrix; | |
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 override void OnSizeChanged(int w, int h, int oldw, int oldh) | |
{ | |
mCoveflowCenter = getCenterOfCoverflow(); | |
base.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(); | |
Matrix imageMatrix = t.Matrix; | |
int imageHeight = child.LayoutParameters.Height; ; | |
int imageWidth = child.LayoutParameters.Width; | |
int rotation = Math.Abs(rotationAngle); | |
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); | |
mCamera.GetMatrix(imageMatrix); | |
imageMatrix.PreTranslate(-(imageWidth / 2), -(imageHeight / 2)); | |
imageMatrix.PostTranslate((imageWidth / 2), (imageHeight / 2)); | |
mCamera.Restore(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ORIGINAL (JAVA) CODE LICENCE | |
* | |
* 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 | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* 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 | |
*/ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Android.App; | |
using Android.Content; | |
using Android.OS; | |
using Android.Runtime; | |
using Android.Views; | |
using Android.Widget; | |
using Android.Graphics; | |
using Android.Util; | |
using Android.Views.Animations; | |
using Java.IO; | |
using Android.Graphics.Drawables; | |
/* | |
* Source: | |
* http://www.inter-fuser.com/2010/02/android-coverflow-widget-v2.html (latest) | |
* http://www.inter-fuser.com/2010/01/android-coverflow-widget.html (original) | |
* via http://stackoverflow.com/questions/725496/android-coverflow | |
* | |
* Usage: | |
* Requires 10 images (Beatles01.jpg ... Beatles10.jpg) in \Resources\Drawable\ folder | |
* | |
* Screenshot: | |
* http://twitpic.com/46n72l | |
*/ | |
namespace net.conceptdevelopment.monodroid | |
{ | |
[Activity(Label = "CoverFlowExample", MainLauncher = true)] | |
public class CoverFlowExample : Activity | |
{ | |
/** Called when the activity is first created. */ | |
protected override void OnCreate(Bundle savedInstanceState) | |
{ | |
base.OnCreate(savedInstanceState); | |
Console.WriteLine("[CoverFlowExample] OnCreate"); | |
coverflow coverFlow = new coverflow(this); | |
ImageAdapter coverImageAdapter = new ImageAdapter(this); | |
// Create reflections (or not, if commented out) | |
coverImageAdapter.CreateReflectedImages(); | |
coverFlow.Adapter = coverImageAdapter; | |
coverFlow.SetSpacing(-40); // originally -25 | |
coverFlow.SetSelection(4, true); | |
coverFlow.SetAnimationDuration(1000); | |
SetContentView(coverFlow); | |
//Use this if you want to use XML layout file | |
//SetContentView(Resource.Layout.Main); | |
//coverFlow = FindViewById<net.conceptdevelopment.monodroid.coverflow>(Resource.Id.CoverFlow); | |
} | |
public class ImageAdapter : BaseAdapter//, ISpinnerAdapter | |
{ | |
private Context mContext; | |
private bool mShowReflection; | |
/// <summary>TODO: these images are 'hardcoded' resources in Monodroid project \Resources\Drawable\ folder</summary> | |
private int[] mImageIds = { | |
Resource.Drawable.Beatles01 | |
,Resource.Drawable.Beatles02 | |
,Resource.Drawable.Beatles03 | |
,Resource.Drawable.Beatles04 | |
,Resource.Drawable.Beatles05 | |
,Resource.Drawable.Beatles06 | |
,Resource.Drawable.Beatles07 | |
,Resource.Drawable.Beatles08 | |
,Resource.Drawable.Beatles09 | |
,Resource.Drawable.Beatles10 | |
}; | |
private ImageView[] mImages; | |
public ImageAdapter(Context c) | |
{ | |
mContext = c; | |
mImages = new ImageView[mImageIds.Length]; | |
mShowReflection = false; | |
} | |
public bool CreateReflectedImages() | |
{ | |
mShowReflection = true; | |
Console.WriteLine("[CoverFlowExample] ImageAdapter.createReflectedImages"); | |
//The gap we want between the reflection and the original image | |
int reflectionGap = 4; | |
int index = 0; | |
foreach (int imageId in mImageIds) | |
{ | |
Console.WriteLine("[CoverFlowExample] ImageAdapter.createReflectedImage for {0}", imageId); | |
Bitmap originalImage = BitmapFactory.DecodeResource(mContext.Resources, imageId); | |
int width = originalImage.Width; | |
int height = originalImage.Height; | |
//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)), Bitmap.Config.Argb8888); | |
//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 defaultPaint = new Paint(); | |
canvas.DrawRect(0, height, width, height + reflectionGap, defaultPaint); | |
//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.Height, 0, | |
bitmapWithReflection.Height + reflectionGap, 0x70ffffff, 0x00ffffff, | |
Shader.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(PorterDuff.Mode.DstIn)); | |
//Draw a rectangle using the paint with our linear gradient | |
canvas.DrawRect(0, height, width, | |
bitmapWithReflection.Height + reflectionGap, paint); | |
ImageView imageView = new ImageView(mContext); | |
imageView.SetImageBitmap(bitmapWithReflection); | |
imageView.LayoutParameters = new coverflow.LayoutParams(120, 180); | |
imageView.SetScaleType(ImageView.ScaleType.Matrix); | |
mImages[index++] = imageView; | |
} | |
return true; | |
} | |
public override int Count | |
{ | |
get | |
{ | |
return mImageIds.Length; | |
} | |
} | |
public override Java.Lang.Object GetItem(int position) | |
{ | |
return position; | |
} | |
public override long GetItemId(int position) | |
{ | |
return position; | |
} | |
public override View GetView(int position, View convertView, ViewGroup parent) | |
{ | |
Console.WriteLine("[CoverFlowExample] ImageAdapter.GetView {0}", position); | |
if (mShowReflection) | |
{ | |
// HACK: mostly repeated code from below | |
ImageView i = new ImageView(mContext); | |
//i.SetImageResource(mImageIds[position]); | |
i.SetImageDrawable(mImages[position].Drawable); // from "ML" on http://www.inter-fuser.com/2010/02/android-coverflow-widget-v2.html | |
i.LayoutParameters = new coverflow.LayoutParams(130, 130); | |
i.SetScaleType(ImageView.ScaleType.CenterInside); | |
//Make sure we set anti-aliasing otherwise we get jaggies | |
BitmapDrawable drawable = (BitmapDrawable)i.Drawable; | |
drawable.SetAntiAlias(true); | |
return i; | |
} | |
else | |
{ | |
//Use this code if you want to load from resources | |
ImageView i = new ImageView(mContext); | |
i.SetImageResource(mImageIds[position]); | |
i.LayoutParameters = new coverflow.LayoutParams(130, 130); | |
i.SetScaleType(ImageView.ScaleType.CenterInside); | |
//Make sure we set anti-aliasing otherwise we get jaggies | |
BitmapDrawable drawable = (BitmapDrawable)i.Drawable; | |
drawable.SetAntiAlias(true); | |
return i; | |
} | |
} | |
///** Returns the size (0.0f to 1.0f) of the views | |
// * depending on the 'offset' to the center. */ | |
//public float GetScale(bool focused, int offset) | |
//{ | |
// /* Formula: 1 / (2 ^ offset) */ | |
// return Math.Max(0, 1.0f / (float)Math.Pow(2, Math.Abs(offset))); | |
//} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment