Created
March 1, 2011 03:35
-
-
Save conceptdev/848571 to your computer and use it in GitHub Desktop.
Custom Android View in MonoDroid: pan around an image larger than the screen
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
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 MagshopDemo; | |
using Android.Util; | |
/* | |
* Source: | |
* http://www.anddev.org/large_image_scrolling_using_low_level_touch_events-t11182.html | |
* | |
* Usage: | |
* <net.conceptdevelopment.monodroid.largeimagescroller | |
android:id="@+id/pageimageview" | |
android:layout_width="fill_parent" | |
android:layout_height="wrap_content" | |
/> | |
*/ | |
namespace net.conceptdevelopment.monodroid | |
{ | |
public class largeimagescroller : View, IJavaObject | |
{ | |
//HACK: hardcoded for Samsung Galaxy Tab | |
// Physical display width and height. | |
private int displayWidth = 600; | |
private int displayHeight = 1024; | |
private static Bitmap bmLargeImage; //bitmap large enough to be scrolled | |
private static Rect displayRect = null; //rect we display to | |
private Rect scrollRect = null; //rect we scroll over our bitmap with | |
private int scrollRectX = 0; //current left location of scroll rect | |
private int scrollRectY = 0; //current top location of scroll rect | |
private float scrollByX = 0; //x amount to scroll by | |
private float scrollByY = 0; //y amount to scroll by | |
private float startX = 0; //track x from one ACTION_MOVE to the next | |
private float startY = 0; //track y from one ACTION_MOVE to the next | |
// Not sure if all these ctor overloads are req'd in #MonoDroid...? | |
public largeimagescroller(IntPtr handle) | |
: base(handle) | |
{ constructor(); } | |
public largeimagescroller(Context context) | |
: base(context) | |
{ constructor(); } | |
public largeimagescroller(Context ctx, IAttributeSet attrs) | |
: base(ctx, attrs) | |
{ constructor(); } | |
void constructor () | |
{ | |
// Destination rect for our main canvas draw. It never changes. | |
displayRect = new Rect(0, 0, displayWidth, displayHeight); | |
// Scroll rect: this will be used to 'scroll around' over the | |
// bitmap in memory. Initialize as above. | |
scrollRect = new Rect(0, 0, displayWidth, displayHeight); | |
//HACK: hardcoded to load specific image | |
// Load a large bitmap into an offscreen area of memory. | |
bmLargeImage = BitmapFactory.DecodeResource(Resources, Resource.Drawable.p000); | |
} | |
public override bool OnTouchEvent(MotionEvent @event) { | |
switch (@event.Action) { | |
case MotionEventActions.Down: | |
// Remember our initial down event location. | |
startX = @event.RawX; | |
startY = @event.RawY; | |
break; | |
case MotionEventActions.Move: | |
float x = @event.RawX; | |
float y = @event.RawY; | |
// Calculate move update. This will happen many times | |
// during the course of a single movement gesture. | |
scrollByX = x - startX; //move update x increment | |
scrollByY = y - startY; //move update y increment | |
startX = x; //reset initial values to latest | |
startY = y; | |
Invalidate(); //force a redraw | |
break; | |
} | |
return true; //done with this event so consume it | |
} | |
protected override void OnDraw(Canvas canvas) { | |
// Our move updates are calculated in ACTION_MOVE in the opposite direction | |
// from how we want to move the scroll rect. Think of this as dragging to | |
// the left being the same as sliding the scroll rect to the right. | |
int newScrollRectX = scrollRectX - (int)scrollByX; | |
int newScrollRectY = scrollRectY - (int)scrollByY; | |
// Don't scroll off the left or right edges of the bitmap. | |
if (newScrollRectX < 0) | |
newScrollRectX = 0; | |
else if (newScrollRectX > (bmLargeImage.Width - displayWidth)) | |
newScrollRectX = (bmLargeImage.Width - displayWidth); | |
// Don't scroll off the top or bottom edges of the bitmap. | |
if (newScrollRectY < 0) | |
newScrollRectY = 0; | |
else if (newScrollRectY > (bmLargeImage.Height - displayHeight)) | |
newScrollRectY = (bmLargeImage.Height - displayHeight); | |
// We have our updated scroll rect coordinates, set them and draw. | |
scrollRect.Set(newScrollRectX, newScrollRectY, | |
newScrollRectX + displayWidth, newScrollRectY + displayHeight); | |
Paint paint = new Paint(); | |
canvas.DrawBitmap(bmLargeImage, scrollRect, displayRect, paint); | |
// Reset current scroll coordinates to reflect the latest updates, | |
// so we can repeat this update process. | |
scrollRectX = newScrollRectX; | |
scrollRectY = newScrollRectY; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment