Android OnDraw and onTouchEvent not working together - java

I am new to android development as well as the Java programming language and would definitely appreciate some help with this issue.
Currently I have some code which creates a canvas and draws a bitmap picture onto it, this appears to work. I also have another bit of code which detects where the users finger is on the devices screen and this also works. when I try to combine the two the bitmap will display but as soon as I click the screen the app crashes.
I have a feeling that this issue is with the canvas/bitmap side of this as i have also noticed that any widgets that have added to layout vanish when the canvas/bitmap feature is running.
This is the code for the canvas/bitmap:
public class myView extends View{
Bitmap image;
DisplayMetrics metrics;
public myView(Context context) {
super(context);
metrics = context.getResources().getDisplayMetrics();
// TODO Auto-generated constructor stub
image = BitmapFactory.decodeResource(getResources(), R.drawable.bhead);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Matrix matrix = new Matrix();
float angle = 90;
float imageCenterX = 50;
float imageCenterY = 50;
matrix.setRotate(angle, imageCenterX, imageCenterY);
Bitmap temp;
temp = BitmapFactory.decodeResource(getResources(), R.drawable.bhead);
image = Bitmap.createScaledBitmap(temp, 100, 100,true);
matrix.postTranslate(((width/2)-50), ((height/2)-100));
canvas.drawBitmap(image, matrix, null);
}
}
and this is the code for the finger location on the screen:
public class MainActivity extends ActionBarActivity {
myView mview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mview = new myView(this);
setContentView(mview);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
EditText txt = (EditText)findViewById(R.id.editText1);
txt.setText("X = "+ x +" Y = " + y);
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Your view hierarchy does not have an EditText with the id editText1. This is because you have set the content view to be a single instance of your class MyView (class names should start with uppercase) with this code in onCreate():
mview = new myView(this);
setContentView(mview);
As a result, you get a NullPointerException on the line txt.setText("X = "+ x +" Y = " + y); because the previous line cannot find the EditText.
You need to include both views in the layout. You can use MyView in XML by writing its fully qualified name. For example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.your.package.name.MyView
android:id="#+id/my_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
... />
</LinearLayout>

Related

Android Studio - how to drag and drop ImageView in an accurate position

so I made an app that draws bitmap into canvas as a template, and I want the user to be able add images from gallery then scale, position and rotate. currently stuck in positioning the imageView properly, when I drag and drop in different position the imageView gets little off the position I placed in.
here is the xml of my project to demonstorate the layout structure:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".search.CreateActivity">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
tools:layout_editor_absoluteX="283dp">
<!-- reault_layout contains layout and imageView:
layout for canvas the contains bitmap
layout for the image added by the user -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/result_layout"
android:layout_width="512dp"
android:layout_height="512dp"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/canvas_layout"
android:layout_width="512dp"
android:layout_height="512dp">
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="#+id/iv_promo"
android:layout_width="100dp"
android:layout_height="100dp"
app:srcCompat="..."/>
</androidx.constraintlayout.widget.ConstraintLayout>
</HorizontalScrollView>
<!-- this button to add the image -->
<Button
android:id="#+id/add_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- this button saves whatever in the result layout as image in internal storage-->
<Button
android:id="#+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
another issue is, the imageView can not be placed at the far right when I scroll, it's only placed within the visible area of the screen before scrolling.
I set the canvas layout width and height to 512dp because its the actual drawable is 512dpx512dp and if I set it to match_parent it might get smaller and harder to place small images in certain areas inside of the template.
For the template to be drawn I placed these two lines inside onCreate();
create_canvas = new CreateCanvas(this);
nCanvas_layout.addView(create_canvas);
I did not use setContentView(); to not draw the template on the entire layout, so this will draw inside the canvas_layout
here is the CreateCanvas class that draws the template:
public class CreateCanvas extends View {
Drawable temp_drawable
Bitmap temp_bitmap
public CreateCanvas(Context context) {
super(context);
this.context = context;
// DRAWABLE OF THE TEMPLATE
temp_drawable = ContextCompat.getDrawable(context, R.drawable.ic_template_master);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//drawableToBitmap() IS A CUSTOM METHOD TO CONVERT THE DRAWABLE TEMPLATE TO BITMAP
// RETURNS BITMAP
temp_bitmap = drawableToBitmap(temp_drawable);
// DRAWS THE TEMPLATE INTO CANVAS
canvas.drawBitmap(temp_bitmap, left, top, null);
}
// THE CUSTOM METHOD TO CONVERT DRAWABLE TO BITMAP
public Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
bitmap.setHeight(getWidth());
bitmap.setWidth(getWidth());
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
the above class helps in drawing the template into canvas_layout, below canvas_layout there's animageView where the user can upload image from internal storage.
I have added these implements to get user touch events
implements View.OnTouchListener, View.OnDragListener, GestureDetector.OnGestureListener
then got these #overrides methods:
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// the imageView that host the image added by user: iv_promo
if (view.getId() == R.id.iv_promo)
{
nGestureDetector.onTouchEvent(motionEvent);
return true;
}
return true;
}
#Override
public boolean onDown(MotionEvent motionEvent) {return false;}
#Override
public void onShowPress(MotionEvent motionEvent) {}
#Override
public boolean onSingleTapUp(MotionEvent motionEvent) {return false;}
#Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {return false;}
#Override
public void onLongPress(MotionEvent motionEvent) {
View.DragShadowBuilder builder = new View.DragShadowBuilder(nIv_promo);
nIv_promo.startDragAndDrop(null, builder, null, 0);
builder.getView().setOnDragListener(this);
}
#Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {return false;}
#Override
public boolean onDrag(View view, DragEvent dragEvent) {
// I was trying thses outside if-statment to check if its working, but did not work
//nIv_promo.setX(dragEvent.getX()-(nIv_promo.getWidth()/2f));
//nIv_promo.setY(dragEvent.getY()-(nIv_promo.getHeight()/2f));
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_STARTED)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION)
{
//nIv_promo.setX(dragEvent.getX());
//nIv_promo.setY(dragEvent.getY());
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_EXITED)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DROP)
{
// . . .
}
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_ENDED)
{
nIv_promo.setX(dragEvent.getX()-(nIv_promo.getWidth()/2f));
nIv_promo.setY(dragEvent.getY()-(nIv_promo.getHeight()/2f));
}
return true;
}
I did not like the DragShadowBuilder(), I wanted to drag the the actual imageView
and drop on different position on the screen. but Im too consumed by the placing the imageView accurately. if possible please help me with that too

Android Studio change background color multiple times with 1 button click

I am brand new to Android Studio and am trying to figure out how to change the background color of my start up app.
The moment the app loads, I see a button on the screen, and when I click, it goes to the color red.
What I want is when you click the button, it goes from red to green to blue than back to red.
However, I keep getting these errors:
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.
Error:(72, 9) error: class, interface, or enum expected
Main Activity XML File:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/layout">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Color"
android:onClick="onChangeColor"/>
</LinearLayout>
Test Activity Java Code:
private int colorIndex = 1;
public void onChangeColor(View view) {
int color;
if(colorIndex==0) {
color = Color.RED;
colorIndex = 1;
}else if(colorIndex==1) {
color = Color.GREEN;
colorIndex = 2;
}else {
//colorIndex = 2
color = Color.BLUE;
colorIndex = 0;
}
View layout = findViewById(R.id.layout);
layout.setBackgroundColor(color);
}
public class TestActivity extends AppCompatActivity {
View view;
//declare a string variable in java a class
//private var colour = "green";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View layout = findViewById(R.id.layout);
layout.setBackgroundColor(Color.RED);
view= this.getWindow().getDecorView();
view.setBackgroundResource(R.color.gray);
}
public void goRed(View v)
{
//if (colour == "green"){
view.setBackgroundResource(R.color.red);
//colour = "red";
//}
}
}
To give you a excellent help, it will be necessary to see you code.
Any way if i andersted you right maybe this will help you :
On your xml layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/layout">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Color"
android:onClick="onChangeColor"/>
</LinearLayout>
On your activity :
private int colorIndex = 1;
public void onChangeColor(View view) {
int color;
if(colorIndex==0) {
color = Color.RED;
colorIndex = 1;
}else if(colorIndex==1) {
color = Color.GREEN;
colorIndex = 2;
}else {
//colorIndex = 2
color = Color.BLUE;
colorIndex = 0;
}
View layout = findViewById(R.id.layout);
layout.setBackgroundColor(color);
}
On you onCreate in the activity
View layout = findViewById(R.id.layout);
layout.setBackgroundColor(Color.RED);
If I understood correctly what you want is, to transition over a series of colours over time, and each colour lasting for some 1-2 seconds. You can use Android's default CountDownTimer.
Keep Your xml layout same.
In your Activity:
public class TestActivity extends AppCompatActivity {
LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = (LinearLayout)findViewById(R.id.layout);
layout.setBackgroundColor(Color.RED);
}
public void onChangeColor(View view) {
// start your timer on button click
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
changeBackground(3-millisUntilFinished/1000);
}
}.start();
}
private void changeBackground(int colorIndex){
int color;
if(colorIndex==1) {
color = Color.GREEN;
}else if(colorIndex==2) {
color = Color.BLUE;
}else {
color = Color.RED;
}
layout.setBackgroundColor(color);
}
}
Hope this might help. If I misunderstood something please comment.
Edit: I typecasted View to LinearLayout

How to move a view in circle with onTouch in android

I am facing a problem in an project. I have a activity in which i had create a Round shape layout with Framelayout. My problem is that i don;t know how to implement items in layout in round shape. and move the items with ontouch event and when the items come on the specific postion a toast display or alert dialog show. I am attach the image for demo.
What you are looking for is a View that implements the onTouch event with a Drag feature.
1) In order to give your view the round shape, you need to create a file that contains those specifications in the drawable folder.
Create your drawable/your_circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF"
android:angle="270"/>
</shape>
2) In your View that you want to make round, set the background to that same drawable like
<YourView
android:id="#+id/your_id"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/your_circle"/>
And then, apply the following procedure to the Activity
public class DraggableActivity extends Activity {
float dX;
float dY;
int lastAction;
View.OnTouchListener touchListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drag_view_layout);
// 1 - Create the touch listener
touchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
lastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_MOVE:
view.setY(event.getRawY() + dY);
view.setX(event.getRawX() + dX);
lastAction = MotionEvent.ACTION_MOVE;
break;
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN) {
Toast.makeText(DraggableView.this, "Clicked!", Toast.LENGTH_SHORT).show();
}
break;
default:
return false;
}
return true;
}
};
// 2 - Add a reference to your view that already is stated on the layout
final View dragView = findViewById(R.id.your_id);
// 3 - Attac the the TouchListener to your view
dragView.setOnTouchListener(this);
}
}
Let me know if it works.
Regards,

Adding 5 rectangles drawn by drawRect method in canvas to layout.xml in android

I created 5 rectangles with different colors on the screen using drawRect method in Canvas. I want to add a seek bar to the bottom of the screen that changes the color of the rectangles gradually as it moves from left to right. I am having a problem in adding the rectangles to the layout and the program crashes.
Here is my rectangle class that draws 5 rectangles:
public class RectAngle extends View {
public RectAngle(Context context) {
super(context);
setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = getWidth();
float y = getHeight();
Paint topLeftRect = new Paint();
Paint bottomLeftRect = new Paint();
Paint topRightRect = new Paint();
Paint midRightRect = new Paint();
Paint bottomRightRect = new Paint();
// Draw the top left rectangle
topLeftRect.setStyle(Paint.Style.FILL);
topLeftRect.setColor(Color.parseColor("#FFFF99"));
// canvas.drawPaint(topLeftRect);
canvas.drawRect(0, 0, x / 2, y / 2, topLeftRect);
//Draw the bottom left rectangle
bottomLeftRect.setStyle(Paint.Style.FILL);
//bottomLeftRect.setColor(Color.WHITE);
// canvas.drawPaint(bottomLeftRect);
bottomLeftRect.setColor(Color.parseColor("#FFFFFF"));
canvas.drawRect(0, y / 2, x / 2, y, bottomLeftRect);
//Draw the top tight rectangle
topRightRect.setStyle(Paint.Style.FILL);
//topRightRect.setColor(Color.WHITE);
topRightRect.setColor(Color.parseColor("#FF6600"));
//canvas.drawPaint(topRightRect);
canvas.drawRect(x / 2, 0, x, y / 3, topRightRect);
// Draw the middle right rectangle
midRightRect.setStyle(Paint.Style.FILL);
//midRightRect.setColor(Color.WHITE);
midRightRect.setColor(Color.parseColor("#66FFFF"));
// canvas.drawPaint(midRightRect);
canvas.drawRect(x / 2, y/3, x, 2*y / 3, midRightRect);
//Draw the bottom right rectangle
bottomRightRect.setStyle(Paint.Style.FILL);
//bottomRightRect.setColor(Color.WHITE);
bottomRightRect.setColor(Color.parseColor("#CCCC00"));
// canvas.drawPaint(bottomRightRect);
canvas.drawRect(x/2, 2*y/3, x, y, bottomRightRect);
}
}
Here is my main activity class:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(new RectAngle(this));
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I know that setContentView(new RectAngle(this)) call draws the rectangles on the screen, but it doesn't add it xml file to be used by the seek bar.
Here's my activity_main.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.example.hassan.modernartui.RectAngle
android:id="#+id/rectangle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<SeekBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/seekBar"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:max="100" />
</RelativeLayout>
Layout Image
Thanks for your help.
I think the problem is that u have not defined the right constructor.
Add the other 2 constructors after the 1st one like this
public RectAngle(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RectAngle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

Android : Update Image in GridView on touch event in Adapter

I have a GridView and attached adapter to it. Adapter populates images in the grid. I have set setOnTouchLister to GridView in my Activity and implemented in the adapter only. In adapter I have an Integer[] imageIDs that contains resource ids of all images that are added & an ArrayList<ImageSourceObject> imgObjsArr that extends ImageView & has other properties set.
Now onTouch(), I want to change the image of the selected image to other one. Here's my code :
SEtting adapter of grid in Activity in onCreate :
// Set Objects in Game View
gameView = (GridView) this.findViewById(R.id.game_gridView);
gameObjAdapter = new GameObjectsAdapter(this, R.id.game_gridView, null);
gameView.setAdapter(gameObjAdapter);
ADAPTER :
public class GameObjectsAdapter extends BaseAdapter implements OnTouchListener {
super();
mContext = c;
this.layoutResourceId = layoutResourceId;
objects = data;
gridViewResAdap = (GridView) mContext.findViewById(this.layoutResourceId);
createObjectsArray();
Log.d("GOA", "Created Objects Array");
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageSourceObject imgView;
if (convertView == null) {
imgView = new ImageSourceObject(mContext);
imgView.setLayoutParams(new GridView.LayoutParams(20, 20));
imgView.getScaleType();
imgView.setScaleType(ScaleType.FIT_XY);
imgView.setPadding(0, 0, 0, 0);
} else {
imgView = (ImageSourceObject) convertView;
}
// Chk status of touched of imgView & set image accordingly
if (imgView.isTouched())
imgView.setImage(R.drawable.droid_touched2);
else
imgView.setImage(imageIds[position]);
return imgView;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getActionMasked();
float currentXPos = event.getX();
float currentYPos = event.getY();
int position = gridViewResAdap.pointToPosition((int)currentXPos, (int) currentYPos);
// Key was Pressed Here
if (action == MotionEvent.ACTION_UP) {
if (position > 0) {
// Get the object which is clicked
ImageSourceObject isb = this.imgObjsArr.get(position);
Log.d("GA", " Postion ID " + isb.getId() + " [] ID : " + imageIds[position]);
// Change the status of touched & set image
isb.setTouched(true);
isb.setImage(R.drawable.droid_touched2);
// Update the ArrayList & Integer[] with this updated obj
this.imgObjsArr.set(position, isb);
imageIds[position] = R.drawable.droid_touched2;
Log.d("ISB", "++++ Object ID : " + isb.getId() + " [] ID : " + imageIds[position] + " ISB Touched :" + isb.isTouched());
Toast.makeText(mContext, "Postion Pressed : " + (position+1),
Toast.LENGTH_SHORT).show();
//this.gridViewResAdap.invalidate();
}
return true;
}
return false;
}
Logs :
02-19 15:19:11.615: D/GA(2046): Postion ID 2130837556 [] ID : 2130837556
02-19 15:19:11.617: D/ISB(2046): ++++ Object ID : 2130837559 [] ID : 2130837559 ISB Touched :true
The logs say that the object in Integer[] & ArrayList both are updated & have right values. After all this also the image is not updated on the screen. The gridViewResAdap is also the object of grid that is passed from the activity. I tried calling invalidate() on it also, but yet no results. As in my getView(), I am using imageIDs, so I have kept that also updated.
ImageSourceObject :
public class ImageSourceObject extends ImageView {
public void setImage(int resourceId) {
super.setImageResource(resourceId);
this.setId(resourceId);
}
Also, onTouch() gives error to call onPerformClick(), I am not sure where to call & why to call. I have alos not implemented onClickListener in the adapter. What can be done in this case & what to write in onClickListener when things are manged in onTouch().
Can you help me know why the image object is not updating and where am I going wrong ? I thought I have to refresh the grid, so have also called invalidate(), but no results.
Any help is highly appreciated.
Thanks
After your ImageView begins handling the TouchEvent, it is the only view allowed to do anything with that touch gesture. You want your GridView to intercept the TouchEvent, check the X and Y coordinates of the TouchEvent (event.getX(); event.getY()) and see if those coordinates fall within the bounds of one of your ImageView objects. If yes, set a flag on the ImageView or something that can trigger your setImageDrawable() method. I was able to achieve a similar effect in one of my projects but I had to create a custom GridView class (public class yourGridView extends GridView), then override the following:
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
int action = event.getAction();
switch(action) {
case MotionEvent.ACTION_DOWN:
Log.i(AGL, "InterceptAction = DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.i(AGL, "InterceptAction = MOVE");
break;
case MotionEvent.ACTION_CANCEL:
Log.i(AGL, "InterceptAction = CANCEL");
return false;
}
return true; //returning true tells your main Activity that you want the custom GridView to handle this TouchEvent; It will then send the TouchEvent to your GridView's onTouchEvent() method for handling.
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch(action) {
case MotionEvent.ACTION_MOVE:
int xCoord = (int) event.getX();
int yCoord = (int) event.getY();
Log.i(AGL, "MOVE EVENT;" + "\n" + "Touch X = " + Integer.toString(xCoord) + "\n" +
"Touch Y = " + Integer.toString(yCoord));
for(int i = 0; i < this.getChildCount(); i++) {
ImageView suspect = (ImageView) this.getChildAt(i);
if(suspect.getBounds().contains(xCoord, yCoord)) {
suspect.CHANGE_YOUR_IMAGE_HERE();
suspect.invalidate();
}
}
break;
}
return true;
}
PLEASE NOTE: getBounds() is a method I wrote in my custom ImageView class. This method returns a Rect object that represents the bounding box of the ImageView object. You will have to use your own logic for fetching the bounds of your ImageView.
ALSO NOTE: When I run this logic in my project, my ImageViews change images rapidly during the touch gesture. I haven't figured out yet how to limit it to one image change per MotionEvent.ACTION_MOVE.
I hope this helps.
You can simply do:
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getActionMasked();
float currentXPos = event.getX();
float currentYPos = event.getY();
int position = gridViewResAdap.pointToPosition((int)currentXPos, (int) currentYPos);
// Key was Pressed Here
if (action == MotionEvent.ACTION_UP) {
if (position > 0) {
((ImageView)v).setImageDrawable(ctx.getResources().getDrawable(R.drawable.droid_touched2));
}
return true;
}
return false;
}

Categories

Resources