I have implemented an application with image view in my application i would like to implement when user move the image right side then i would like to get the next acitvity.
How can i write an event or any other code for move the image just right side?
I have used am imageView code as:
(ImageView)findViewById(R.id.slide) //event for move right here
Intent it = new Intent(Slide.this,NextActivity.class);
startActivity(it);
Please any body help me...
So, if i understood you correctly, you want to move an ImageView across the screen, drag it, and when you hit a certain spot with it you want to start another activity?
If so, you could try and use the code below...which let's you drag your imageview across the screen
Just add an onTouchListener to the imageView you're trying to slide (move/drag)
yourSlideImageViewObject.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
onSlideTouch(v, event);
return false;
}
});
Then add this code to handle the Touch events
public void onSlideTouch( View view, MotionEvent event )
{
//When the user pushes down on an ImageView
if ( event.getAction() == MotionEvent.ACTION_DOWN )
{
inDragMode = true; //Set a variable so we know we started draggin the imageView
//Set the selected ImageView X and Y exact position
selectedImageViewX = Math.abs((int)event.getRawX()-((ImageView)view).getLeft());
selectedImageViewY = Math.abs((int)event.getRawY()-((ImageView)view).getTop());
//Bring the imageView in front
((ImageView)view).bringToFront();
}
//When the user let's the ImageView go (raises finger)
if ( event.getAction() == MotionEvent.ACTION_UP )
{
inDragMode = false; //Reset the variable which let's us know we're not in drag mode anymore
}
//When the user keeps his finger on te screen and drags it (slides it)
if ( event.getAction() == MotionEvent.ACTION_MOVE )
{
//If we've started draggin the imageView
if ( inDragMode )
{
//Get the imageView object
ImageView slide = (ImageView)findViewById(R.id.slide);
//Get a parameters object (THIS EXAMPLE IS FOR A RELATIVE LAYOUT)
RelativeLayout.LayoutParams params = RelativeLayout.LayoutParams)slide.getLayoutParams();
//Change the position of the imageview accordingly
params.setMargins((int)event.getRawX()-selectedImageViewX, (int)event.getRawY()-selectedImageViewY, 0, 0);
//Set the new params
slide.setLayoutParams(params);
//If we hit a limit with our imageView position
if( slideImageView_position is inside an interval )
{
//Open another activity
Intent it = new Intent(Slide.this,NextActivity.class);
startActivity(it);
}
}
}
}
The above should drag your imageview accross the screen.
You can also implement in the MotionEvent.ACTION_MOVE event .... to limit the movement of the ImageView accross the screen. So check the new coordinates of your finger across the screen and check if they are out of bounds. If so, then do nothing. If they aren't out of bounds, then change the left and upper margins of the ImaveView.
Also, on the MotionEvent.ACTION_UP event, check to see if the left margin of the ImaveView is over a predefined limit (which means the user slided the imageView over you intended position). If so, you can continue doing whatever you want, which means starting an activity. OR, if you don't want to open the activity while the user is dragging, not only after he has removed his finger from the imageView, then just do that if () i've written under the MotionEvent.ACTION_MOVE event. Insert there the interval you want, so when the imageView is dragged inside that interval, the activity starts.
If you're confused, please ask :) It's very late here, and i'm tired, so i might have not explained it properly :D
I don't quite understand your question, but I interpret it as that you want to slide an ImageView containing Activity into another Activity.
If that is the case, I would actually convert those Activities to being Fragments and then use a ViewPager. Here is a good Google Developer blog post that introduces this concept: http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html
You'll want to implement a FragmentPagerAdapter with getCount being the number of pages the user can swipe between. Then getItem should return a Fragment containing the first ImageView for position 0 and a Fragment containing what is in your NextActivity for position 1. You can return more Fragments for positions 2 and higher to have an interface that you can swipe between, left and right. This hopefully gives you the sliding user experience that you are looking for.
package avatar.view.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class customview extends View {
private int PanX, PanY;
private GestureDetector gestureDetector;
private Bitmap mBitmap;
private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
public customview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO 自動生成されたコンストラクター・スタブ
}
public customview(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO 自動生成されたコンストラクター・スタブs
}
public customview(Context context) {
super(context);
// TODO 自動生成されたコンストラクター・スタブ
}
private float pointX = 0, pointY = 0;
private void setPoint(MotionEvent e) {
pointX = e.getX();
pointY = e.getY();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null) {
pointX = PanX - (mBitmap.getWidth() / 2);
pointY = PanY - (mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, pointX, pointY, mPaint);
}
}
/*
* (非 Javadoc)
*
* #see android.view.View#onMeasure(int, int)
*/
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// ビューのサイズを設定する
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec
.getSize(heightMeasureSpec));
}
public void setPanX(int panX) {
PanX = panX;
}
public int getPanX() {
return PanX;
}
public void setPanY(int panY) {
PanY = panY;
}
public int getPanY() {
return PanY;
}
public void setmBitmap(Bitmap mBitmap) {
this.mBitmap = mBitmap;
}
public Bitmap getmBitmap() {
return mBitmap;
}
}
Custom a view . Then in Main Activity
#Override
public boolean onTouch(View v, MotionEvent e) {
// TODO 自動生成されたメソッド・スタブ
if (isSelected == false) {
return false;
}
final int action = e.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
panX = (int) e.getX();
panY = (int) e.getY();
ctview.setPanX(panX);
ctview.setPanY(panY);
ctview.invalidate();
Log.v("ACTION_DOWN", "ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
panX = (int) e.getX();
panY = (int) e.getY();
ctview.setPanX(panX);
ctview.setPanY(panY);
ctview.invalidate();
Log.v("ACTION_MOVE", "ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.v("ACTION_UP", "ACTION_UP");
if (isSelected) {
isSelected = false;
ctview.setmBitmap(null);
ctview.invalidate();
}
break;
default:
break;
}
return true;
}
And Oncreate
Customview.setmBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ImageSlide);
Related
Supposing that I have two circles inside my onDraw() method.
protected void onDraw(Canvas canvas) {
canvas.drawCircle(redX, redY, redRad, redPaint);
canvas.drawCircle(cx, cy, rad, p);
}
nevermind of the variables that I have used, through the method provided by the View class onTouchEvent() I can put an action on a circle if it is alone, but what if I want them to have an on onTouchEvent() separately even though they are at the same onDraw() method, is it possible? What is the best way to do that?
I don't think this is possible as onTouchEvent is method of view class and you can override it only once.
Only thing you can do is to override ontouchEvent and then from its touch position you can find out in which area you are touching and do the operation that you need to do.
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
upCell = -1;
xPos = event.getX();
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
xPos = event.getX();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
}
return super.onTouchEvent(event);
}
You need to store the position of each object & check for overlap every time the touch event for this view is invoked.
A sample is given below(Assuming your objects are circles):
public class CircleDrawingView extends View
{
//constructor - to be used when creating view from code
public CircleDrawingView(final Context ct) {
super(ct);
init();
}
//constructor - invoked when view is used in xml
public CircleDrawingView(final Context ct, final AttributeSet attrs) {
super(ct, attrs);
init();
}
//constructor - invoked when view is used in xml
public CircleDrawingView(final Context ct, final AttributeSet attrs, final int defStyle) {
super(ct, attrs, defStyle);
init();
}
Paint mCirclePaint;
ArrayList<CircleArea> allCircles;//list of all circles drawn on the view
private void init() {
allCircles = new ArrayList<>();
//CircleArea is a class defined below. It's constructor params are:
//CircleArea(int CenterX,int CenterY,int Radius,String TAG)
allCircles.add( new CircleArea(150,50,50, "C1"));
allCircles.add( new CircleArea(150,250,90, "C2"));
allCircles.add( new CircleArea(220,550,50, "C3"));
allCircles.add( new CircleArea(250,350,150, "C4"));
mCirclePaint = new Paint();
mCirclePaint.setColor(Color.BLACK);
mCirclePaint.setStyle(Paint.Style.FILL);
}
#Override
public void onDraw(final Canvas canv) {
canv.drawARGB(0, 0, 0, 0);
for (CircleArea obj : allCircles)
canv.drawCircle(obj.centerX, obj.centerY, obj.radius, mCirclePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float xTouch = event.getX();
float yTouch = event.getY();
for (CircleArea obj : allCircles)
{
//Check if the touched co-ordinates lies in one of the drawn circle
if(Math.abs(obj.centerX-xTouch)<obj.radius && Math.abs(obj.centerY-yTouch)<obj.radius)
{
onTouch(obj.tag);
//return true; - If you want the touch event of other views to be invoked
//return false; - If you want to consume the touch event,
// i.e. touch event for other views will not be invoked
//Do not return if objects(circles) drawn on this view are overlapping
//and you want to invoke touch event for each object if such a scenario occurs
}
}
return super.onTouchEvent(event);
}
private void onTouch(String tag)
{
switch (tag)
{
case "C1":
//Touched circle 1
break;
case "C2":
//Touched circle 2
break;
case "C3":
//Touched circle 3
break;
case "C4":
//Touched circle 4
break;
default:
//Didnt touch any circle
}
}
/** Stores data about single circle */
private static class CircleArea {
int radius;
int centerX;
int centerY;
String tag;
CircleArea(int centerX, int centerY, int radius, String tag) {
this.radius = radius;
this.centerX = centerX;
this.centerY = centerY;
this.tag = tag;
}
}
}
I am using an EditText widget and would like to modify the context menu that is displayed when the user long presses the view. The problem that I am having is that I need to know the character position within the text of the long press so I can determine what I need to add to the context menu. The base class is doing this because one of the choices in the menu is 'Add “word_clicked_on” To Dictionary.' Setting ClickableSpans within the text does not appear to be a solution since it consumes the click event which makes it impossible to move the edit cursor within the spans.
Here is the solution that I came up with and it does work so I wanted to share it:
First I concluded that I needed to extend the EditText class so that I could intercept the onTouchEvent, capture the ACTION_DOWN event, and save the position. Now that I have the position of the down point I can call getOffsetForPosition(downPointX, downPointY) and get the character position of the long-press. There is one big problem, getOffsetForPosition was not added until SDK 14! To make this solution work I had to back port the functionality of getOffsetForPosition and branch if the current SDK is earlier than SDK_INT 14. Here is the source code for the new class:
public class ScrapEditText extends EditText{
protected float LastDownPositionX, LastDownPositionY;
public ScrapEditText(Context context)
{
super(context);
}
public ScrapEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
final int action = event.getActionMasked();
if(action == MotionEvent.ACTION_DOWN)
{
LastDownPositionX = event.getX();
LastDownPositionY = event.getY();
}
return super.onTouchEvent(event);
}
public float GetLastDownPositionX()
{
return LastDownPositionX;
}
public float GetLastDownPositionY()
{
return LastDownPositionY;
}
public int GetOffsetForLastDownPosition()
{
if(Build.VERSION.SDK_INT > 13)
{
// as of SDK 14 the getOffsetForPosition was added to TextView
return getOffsetForPosition(LastDownPositionX, LastDownPositionY);
}
else
{
return GetOffsetForPositionOlderSdk();
}
}
public int GetOffsetForPositionOlderSdk()
{
if (getLayout() == null) return -1;
final int line = GetLineAtCoordinateOlderSDK(LastDownPositionY);
final int offset = GetOffsetAtCoordinateOlderSDK(line, LastDownPositionX);
return offset;
}
public int GetLineAtCoordinateOlderSDK(float y)
{
y -= getTotalPaddingTop();
// Clamp the position to inside of the view.
y = Math.max(0.0f, y);
y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
y += getScrollY();
return getLayout().getLineForVertical((int) y);
}
protected int GetOffsetAtCoordinateOlderSDK(int line, float x) {
x = ConvertToLocalHorizontalCoordinateOlderSDK(x);
return getLayout().getOffsetForHorizontal(line, x);
}
protected float ConvertToLocalHorizontalCoordinateOlderSDK(float x) {
x -= getTotalPaddingLeft();
// Clamp the position to inside of the view.
x = Math.max(0.0f, x);
x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
x += getScrollX();
return x;
}
}
In your Activity derived class:
ScrapText = (ScrapEditText) findViewById(R.id.sample_text);
ScrapText.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener(){
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
int charOffset = FileText.GetOffsetForLastDownPosition();
}
});
I am making a grid-based game that will be much larger than the screen, and the user would scroll around in it. I basically put a bunch on ImageViews inside of a custom class that extends a relative layout. The problem is that even though RelativeLayout.LayoutParams is set to the correct size I want (1280*1280). The images are crammed against the sides of the screen and don't extend past it. I have got the scrolling logic working, and when I scroll, I can see it is a rectangle of images the size of one screen. How can I make it so the images extend past the screen?
The class that extends a relative layout:
public class GameGrid extends RelativeLayout {
ImageView[][] subViews;
int rows=0, cols=0, cellsize=0;
int width, height;
//Dragging variables
float startX;
float startY;
float lastX;
float lastY;
boolean touching;
boolean dragging;
int clickedChild;
public GameGrid(Context context) {
super(context);
init();
}
public GameGrid(Context context, int rws, int cls, int clsze) {
super(context);
rows=rws;
cols=cls;
cellsize=clsze;
init();
}
public GameGrid(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GameGrid(Context context, AttributeSet attrs, int defaultStyles) {
super(context, attrs, defaultStyles);
init();
}
public void init() {
rows=10;
cols=10;
cellsize=128;
startX = 0;
startY = 0;
lastX=0;
lastY=0;
touching = false;
dragging = false;
clickedChild = -1;
subViews = new ImageView[cols][rows];
setLayoutParams(new RelativeLayout.LayoutParams(cellsize*cols,cellsize*rows));
width=this.getLayoutParams().width;
height=this.getLayoutParams().height;
this.setMinimumWidth(width);
this.setMinimumHeight(height);
Log.i("info","****************");
Log.i("info","GameGrid Made.");
Log.i("info","width: "+width+"\nheight: "+height);
Log.i("info","****************");
makeGrid();
// this.setOnTouchListener()
}
public boolean getDragging(){
return dragging;
}
public void makeGrid() {
for(int y=0;y<rows;y++){
for(int x=0;x<cols;x++){
ImageView temp = new ImageView(getContext());
temp.setImageResource(R.drawable.water1);
temp.setScaleType(ImageView.ScaleType.FIT_XY);
RelativeLayout.LayoutParams temp2 = new RelativeLayout.LayoutParams(width/cols,height/rows);
if (x == 0 && y == 0){ //If this is the first view being made, set it relative to the parent.
temp2.addRule(RelativeLayout.ALIGN_PARENT_TOP);
temp2.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
}
else if (x == 0){ //If this is in the first column, set it below the one above.
temp2.addRule(RelativeLayout.ALIGN_LEFT,subViews[0][y-1].getId());
temp2.addRule(RelativeLayout.BELOW,subViews[0][y-1].getId());
}
else { //Align the bottom with first one of that row.
temp2.addRule(RelativeLayout.RIGHT_OF,subViews[x-1][y].getId());
temp2.addRule(RelativeLayout.ALIGN_BOTTOM,subViews[0][y].getId());
}
temp.setLayoutParams(temp2);
subViews[x][y]=temp;
subViews[x][y].setId(x+y*cols+1);
// Toast.makeText(getContext(), "" + v.getId(), Toast.LENGTH_SHORT).show();
subViews[x][y].setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v,MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
clickedChild = v.getId();
return false;
}
});
addView(temp);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{ // when the user touches the screen
startX = event.getX();
startY = event.getY();
lastX = event.getX();
lastY = event.getY();
touching = true;
dragging = false;
return true;
}
else if (event.getAction() == MotionEvent.ACTION_MOVE)
{ // when the user moves the touch
if (!dragging)
dragging = true;
int distX = (int)(event.getX()-lastX);
int distY = (int)(event.getY()-lastY);
this.scrollBy(-distX, -distY);
lastX = event.getX();
lastY = event.getY();
return true;
}
else if (event.getAction() == MotionEvent.ACTION_UP)
{ // when the user lifts the touch
if (!dragging){
if (clickedChild>0){
Toast.makeText(getContext(), "getHeight()= " + getHeight(), Toast.LENGTH_SHORT).show();
clickedChild = -1;
}
}
touching = false;
dragging = false;
return true;
}
else if (event.getAction() == MotionEvent.ACTION_CANCEL)
{ // if something gets lost in translation
startX = 0;
startY = 0;
lastX=0;
lastY=0;
touching = false;
dragging = false;
return true;
}
return false;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth, parentHeight);
}
The Activity:
public class Attacktics2 extends Activity {
/** Called when the activity is first created. */
GameGrid grid;
int rows, cols, cellsize;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
}
public void start(View view) {
view.setVisibility(View.GONE);
grid = new GameGrid(this,10,10,128);
setContentView(grid);
}
}
Since you're already doing the heavy lifting of managing all the scrolling, I'd suggest that you implement your entire layout logic yourself and not rely on RelativeLayout. Except for ScrollView and HorizontalScrollView, the stock layout classes are going to restrict their children to be within the parent bounds. Those, in turn, will be restricted to the screen dimensions. If you handle the layout logic yourself, you can position child views so that they extend off screen. It then forms a viewport into a larger grid and can just render those children that are visible within the viewport.
I'm not a programmer, but I'm trying to learn android development, and having a blast.
Lately I've hit a fork in the road, and I don't know that any of the directions I can identify will meet all my needs. This is where you (the experts) can help ;)
Endpoint: I want to have the user touch a ball, and drag it to any location on the screen. I would also like to animate this ball when it gets drawn, and when it gets dropped.
I can accomplish the dragging part using a custom class (that doesn't extend anything... just a class like is found in this tutorial: basic drag & drop, however, I don't know how to apply the tween animation to it since it's not a view.
I have also developed an animated version of an ImageView with my image in it, however, I can't manage to apply the same drag & drop functionality without using AbsoluteLayout, which I know is a no-no.
So... how do I move an ImageView around a ??? layout using MotionEvents, or how do I animate (using tweens defined in XML) a non-view based custom class?
Please ask questions if this is not clear. I don't know all the terminology as well as most of you might.
There is also a copy of this question on the anddev.org forums, so I'll keep this post updated with any responses I get over there.
Why can't you extend View? Then, you have complete control over how it draws because you can override the OnDraw() method. Just make the ColorBall class extend View. Change its position when you move and then invalidate just that one view and have it draw itself instead of having the DrawView class draw it.
Edit - Here is an example class
public class Card extends View
{
private Bitmap mImage;
private final Paint mPaint = new Paint();
private final Point mSize = new Point();
private final Point mStartPosition = new Point();
public Card(Context context)
{
super(context);
}
public final Bitmap getImage() { return mCardImage; }
public final void setImage(Bitmap image)
{
mImage = image;
setSize(mCardImage.getWidth(), mCardImage.getHeight());
}
#Override
protected void onDraw(Canvas canvas)
{
Point position = getPosition();
canvas.drawBitmap(mCardImage, position.x, position.y, mPaint);
}
public final void setPosition(final Point position)
{
mRegion.set(position.x, position.y, position.x + mSize.x, position.y + mSize.y);
}
public final Point getPosition()
{
Rect bounds = mRegion.getBounds();
return new Point(bounds.left, bounds.top);
}
public final void setSize(int width, int height)
{
mSize.x = width;
mSize.y = height;
Rect bounds = mRegion.getBounds();
mRegion.set(bounds.left, bounds.top, bounds.left + width, bounds.top + height);
}
public final Point getSize() { return mSize; }
#Override
public boolean onTouchEvent(MotionEvent event)
{
// Is the event inside of this view?
if(!mRegion.contains((int)event.getX(), (int)event.getY()))
{
return super.onTouchEvent(event);
}
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
mStartPosition.x = (int)event.getX();
mStartPosition.y = (int)event.getY();
bringToFront();
onSelected();
return true;
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
int x = 0, y = 0;
if(mLock == DirectionLock.FREE || mLock == DirectionLock.HORIZONTAL_ONLY)
{
x = (int)event.getX() - mStartPosition.x;
}
if(mLock == DirectionLock.FREE || mLock == DirectionLock.VERTICAL_ONLY)
{
y = (int)event.getY() - mStartPosition.y;
}
mRegion.translate(x, y);
mStartPosition.x = (int)event.getX();
mStartPosition.y = (int)event.getY();
invalidate();
return true;
}
else
{
return super.onTouchEvent(event);
}
}
}
I'm not a programmer, but I'm trying to learn android development, and having a blast.
Lately I've hit a fork in the road, and I don't know that any of the directions I can identify will meet all my needs. This is where you (the experts) can help ;)
Endpoint: I want to have the user touch a ball, and drag it to any location on the screen. I would also like to animate this ball when it gets drawn, and when it gets dropped.
I can accomplish the dragging part using a custom class (that doesn't extend anything... just a class like is found in this tutorial: basic drag & drop, however, I don't know how to apply the tween animation to it since it's not a view.
I have also developed an animated version of an ImageView with my image in it, however, I can't manage to apply the same drag & drop functionality without using AbsoluteLayout, which I know is a no-no.
So... how do I move an ImageView around a ??? layout using MotionEvents, or how do I animate (using tweens defined in XML) a non-view based custom class?
Please ask questions if this is not clear. I don't know all the terminology as well as most of you might.
There is also a copy of this question on the anddev.org forums, so I'll keep this post updated with any responses I get over there.
Why can't you extend View? Then, you have complete control over how it draws because you can override the OnDraw() method. Just make the ColorBall class extend View. Change its position when you move and then invalidate just that one view and have it draw itself instead of having the DrawView class draw it.
Edit - Here is an example class
public class Card extends View
{
private Bitmap mImage;
private final Paint mPaint = new Paint();
private final Point mSize = new Point();
private final Point mStartPosition = new Point();
public Card(Context context)
{
super(context);
}
public final Bitmap getImage() { return mCardImage; }
public final void setImage(Bitmap image)
{
mImage = image;
setSize(mCardImage.getWidth(), mCardImage.getHeight());
}
#Override
protected void onDraw(Canvas canvas)
{
Point position = getPosition();
canvas.drawBitmap(mCardImage, position.x, position.y, mPaint);
}
public final void setPosition(final Point position)
{
mRegion.set(position.x, position.y, position.x + mSize.x, position.y + mSize.y);
}
public final Point getPosition()
{
Rect bounds = mRegion.getBounds();
return new Point(bounds.left, bounds.top);
}
public final void setSize(int width, int height)
{
mSize.x = width;
mSize.y = height;
Rect bounds = mRegion.getBounds();
mRegion.set(bounds.left, bounds.top, bounds.left + width, bounds.top + height);
}
public final Point getSize() { return mSize; }
#Override
public boolean onTouchEvent(MotionEvent event)
{
// Is the event inside of this view?
if(!mRegion.contains((int)event.getX(), (int)event.getY()))
{
return super.onTouchEvent(event);
}
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
mStartPosition.x = (int)event.getX();
mStartPosition.y = (int)event.getY();
bringToFront();
onSelected();
return true;
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
int x = 0, y = 0;
if(mLock == DirectionLock.FREE || mLock == DirectionLock.HORIZONTAL_ONLY)
{
x = (int)event.getX() - mStartPosition.x;
}
if(mLock == DirectionLock.FREE || mLock == DirectionLock.VERTICAL_ONLY)
{
y = (int)event.getY() - mStartPosition.y;
}
mRegion.translate(x, y);
mStartPosition.x = (int)event.getX();
mStartPosition.y = (int)event.getY();
invalidate();
return true;
}
else
{
return super.onTouchEvent(event);
}
}
}