Android : Update Image in GridView on touch event in Adapter - java

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;
}

Related

Using states to manage onTouchEvent

I am making a single screen application of a simple logic circuit. I am using onTouchEvent to handle user interactions. I am using ACTION_UP, ACTION_MOVE, & ACTION_DOWN right now, but this only allows me to use one gesture. I want to be able to selection an option in my UI, such as "AND" gate. I want to use one touch to select what I want to do, then the next touch to place the gate on the screen. Instead, my onTouchEvent only allows me to touch the component I want and I have to keep my finger on the screen to drag it to the location I want to place it. This is not want I want.
I've tried researching how to implement some sort of state variable to allow onTouchEvent to wait for the next touch, but I don't think I correctly understand how to implement it.
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
Log.d("Debugging", "In onTouchEvent");
if((motionEvent.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
Touch.horizontalTouched = (int)motionEvent.getX()/ grid.getBlockSize();
Touch.verticalTouched = (int)motionEvent.getY()/ grid.getBlockSize();
whatWasTouched = whatWasTouched(Touch.horizontalTouched, Touch.verticalTouched);
}else if((motionEvent.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE){
//do nothing, finger is moving on screen
}
else if((motionEvent.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP){
Touch.secondHorizontalTouch = (int)motionEvent.getX()/ grid.getBlockSize();
Touch.secondVerticalTouch = (int)motionEvent.getY()/ grid.getBlockSize();
placeComponent();
draw();
}
return true;
}
I expect my first touch on the screen to be able to select an option, ex: "AND", "OR", "NOT", "SWITCH", "EDIT", etc. and then my second touch completes the desired action. I also want to be able to touch a component I placed on the screen and then touch another component so I can wire them together.
By default, event listeners in Android are for waiting - you don't have to provide any delay.
Simply set the onTouchEvent(...) listener on the ImageView and show the first bitmap. When the ImageView is touched, show the next bitmap and so on. All you have to do is keep a count of how many touches there have been in order to know which image to show (image 1, 2, 3, 4 etc).
Example...
public class LoadImage extends Activity {
int imageNumber = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load_image);
//get an image and create a bitmap from it
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(bitmap);
}
#Override
public boolean onTouchEvent(MotionEvent evt) {
if (evt.getAction() == MotionEvent.ACTION_DOWN) {
imageNumber++;
switch (imageNumber) {
case 2:
// show image 2
break;
case 3:
// show image 3
break;
...
}
return true;
}
return false;
}
}
I was able to figure this out by using a static class that will handle the state of my touches.
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
Log.d("Debugging", "In onTouchEvent");
if (placeState.getState() == false) {
if ((motionEvent.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
Touch.horizontalTouched = (int) motionEvent.getX() / grid.getBlockSize();
Touch.verticalTouched = (int) motionEvent.getY() / grid.getBlockSize();
whatWasTouched = whatWasTouched(Touch.horizontalTouched, Touch.verticalTouched);
if(whatWasTouched.equals("DELETE")){
visualComponents.clear();
logicalComponents.clear();
}
placeState.toggleState();//sets to true
draw();
}
}else if (placeState.getState() == true) {
Touch.secondHorizontalTouch = (int) motionEvent.getX() / grid.getBlockSize();
Touch.secondVerticalTouch = (int) motionEvent.getY() / grid.getBlockSize();
placeComponent();
placeState.toggleState();//sets to false
draw();
}
return true;
}

AndroidStudio MotionEvent: detect only ACTION_UP on a second view, starting ACTION_DOWN on first view

Solved it by using emandt's suggestion. My personal Solution added below.
I'm using Android Studio for this.
I searched for solutions but couldn't find anything resembling this.
I want to know on which ImageView an UP action occurs while starting the DOWN action on a different ImageView (to eventually be able to drag one image over the other and make it snap to the same position by getting the position of the image I dragged over).
My example has two ImageViews with the id imageView (left) and imageView2(right).
In my example I'm not dragging anything yet, I just want to touch the left image, see "Action was down" in the log and lift the finger over the right image showing "Action was up2".
I don't know if this is easily possible.
As far as I can tell from testing, the MotionEvent.ACTION_UP only fires for an ImageView when you also pressed down on it beforehand. So when I release on top of imageView2 it only shows "Action was up" from the left image.
I wondered if it was possible by playing with return false, since the return value tells if an ActionEvent is consumed so I thought if the UP event of imageView returns false, maybe it does trigger the UP event of imageView2 but no. (Either complete misunderstanding on my part or it doesn't recognise UP on the second because it didn't start with a DOWN and MotionEvents probably always have to start with a DOWN).
public class MainActivity extends Activity {
ImageView imageView;
ImageView imageView2;
String DEBUG_TAG = "action";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
imageView2 = findViewById(R.id.imageView2);
imageView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
//int action = MotionEventCompat.getActionMasked(event);
int action = event.getActionMasked();
switch(action) {
case (MotionEvent.ACTION_DOWN) :
Log.d(DEBUG_TAG,"Action was DOWN"+v.toString());
return true;
case (MotionEvent.ACTION_MOVE) :
//Log.d(DEBUG_TAG,"Action was MOVE");
return true;
case (MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG,"Action was UP"+v.toString());
return false;
default :
//return true;
}
return true;
}
});
imageView2.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
//int action = MotionEventCompat.getActionMasked(event);
int action = event.getActionMasked();
switch(action) {
case (MotionEvent.ACTION_DOWN) :
Log.d(DEBUG_TAG,"Action was DOWN2"+v.toString());
return true;
case (MotionEvent.ACTION_MOVE) :
//Log.d(DEBUG_TAG,"Action was MOVE");
return true;
case (MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG,"Action was UP2"+v.toString());
return true;
default :
//return true;
}
return true;
}
});
}
}
If there is no simple way to do this, I'm thinking about solving this mathematically, but maybe some of you can help.
So my question is, is there a way to recognise an UP action on a second ImageView while currently being in a MotionEvent of another ImageView?
SOLUTION (see emandt's answer)
I ditched the second OnClickListener because I realised that the 2nd image doesn't need any, I just need its position.
Added this method:
#Nullable
private View getDroppedView(View droppedView, int x, int y, List<View> arrayOfPossibilities) {
Rect cVisibleBoundsRect = new Rect();
for (View cView : arrayOfPossibilities) {
//if currently iterated view doesn't have values for getGlobalVisibleRect, skip the .contains part
//ignore the item which is your current active item (which would potentially be dropped)
//getGlobalVisibleRect sets cVisibleBoundsRect immediately to the Rect given as parameter
if (!cView.getGlobalVisibleRect(cVisibleBoundsRect)||(cView.equals(droppedView))) continue;
if (cVisibleBoundsRect.contains(x, y)) {
Log.d(DEBUG_TAG,"Found something");
//THIS "cView" IS THE VIEW WHERE YOU RELEASED THE FINGER
return cView;
}
}
Log.d(DEBUG_TAG,"Found nothing");
return null;
}
And added this in onUP:
case (MotionEvent.ACTION_UP) :
View dropTarget;
Log.d(DEBUG_TAG,"Action was UP"+v.toString());
dropTarget = getDroppedView(v, (int)event.getRawX(), (int)event.getRawY(), listOfViews);
if (dropTarget != null){
v.setX(dropTarget.getX());
v.setY(dropTarget.getY());
}
I think you want to know which is the View where you release the finger from the screen, am I right?
To do this you can use the same "View.OnTouchListener()" for all of your Views and in the ACTION_UP you have to call a new method similar to this (pseudo-code):
....
case (MotionEvent.ACTION_UP) :
View[] cArrayOfPossibileViews = new View[]{ findViewById(IMAGE_1), findViewById(IMAGE2) }
getDroppedView(v, event.getRawX(), event.getRawY(), cArrayOfPossibileViews);
break;
}
....
#Nullable
private View getDroppedView(View view, int x, int y, View[] arrayOfPossibilities) {
Rect cVisibleBoundsRect = new Rect();
for (View cView : arrayOfPossibilities) {
if (!cView.getGlobalVisibleRect(cVisibleBoundsRect)) continue;
if (cVisibleBoundsRect.contains(x, y)) {
//THIS "cView" IS THE VIEW WHERE YOU RELEASED THE FINGER
return cView;
}
}
return null;
}
This method get View bounds and compare them avains X and Y of your Touch Event. If X and Y are contained inside a View bounds it means that View is the one you need.

Avoid overlap between touch and click android in OnTouch(), in IOnTouchListener?

I am creating this app.
code of my onsingletapup.cs file
class SingleTapUp : Android.Views.GestureDetector.SimpleOnGestureListener
{
public override bool OnSingleTapUp(MotionEvent e) {
// Toast.MakeText(this,, ToastLength.Long).Show();
return true;
}
}
here is my mainactivity.cs
public class MainActivity : ActionBarActivity, View.IOnTouchListener
{
GestureDetector gestureDetector;
float _viewX;
float _viewY;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
PopulateListView(someList,anynumbertoshow)
}
private void QueueListView(Queue<FeedItem> feedItemsList, int count)
{
RelativeLayout rl = this.FindViewById<RelativeLayout>(Resource.Id.newsContainer);
if(rl.Visibility == ViewStates.Gone)
{
this.FindViewById<LinearLayout>(Resource.Id.newsList).Visibility = ViewStates.Gone;
rl.Visibility = ViewStates.Visible;
}
Paint layerPaint = new Paint();
layerPaint.AntiAlias = true;
layerPaint.FilterBitmap = true;
layerPaint.Dither = true;
// RelativeLayout parentLayout = (RelativeLayout)LayoutInflater.from(context).inflate(R.layout.myLayout, null);
rl.SetLayerType(LayerType.Hardware, layerPaint);
rl.SetClipChildren(false);
Random rnd = new Random();
//this.progressDialog.Dismiss();
for (int i = 0; i < count; i++)
{
FeedItem rss = theNewsQueue.Dequeue();
var viewObj = this.LayoutInflater.Inflate(Resource.Layout.NewTile, rl, false);
TextView tv = viewObj.FindViewById<TextView>(Resource.Id.textView2);
TextView link = viewObj.FindViewById<TextView>(Resource.Id.link);
link.Text = rss.Link;
tv.Text = rss.Title;
viewObj.Rotation = angle;
angle = rnd.Next(-3, 3);
viewObj.SetLayerType(LayerType.Hardware, layerPaint);
rl.AddView(viewObj);
gestureDetector = new GestureDetector(this, new SingleTapUp());
viewObj.SetOnTouchListener(this); //Here I am adding my listener to all my control
rl.SetLayerType(LayerType.Hardware, layerPaint);
theNewsQueue.Enqueue(rss);
rss = null;
}
}
public bool OnTouch(View v, MotionEvent e)
{
if (gestureDetector.OnTouchEvent(e))
{
//will detect a click and open in browser
return true;
}
else
{
int initialTouchX = 0, initialTouchY = 0;
int newx = 0;
var x = v.Left;
switch (e.Action)
{
case MotionEventActions.Down:
{
_viewX = e.GetX();
_viewY = e.GetY();
initialTouchX = (int)e.RawX;
initialTouchY = (int)e.RawY;
break;
}
case MotionEventActions.Up:
{
int lastX = (int)e.GetX();
int lastY = (int)e.GetY();
if ((x - newx) > 40)
{
//right Swipe
sendViewToBack(v);
}
else if ((newx - x > 40))
{
//left Swipe
sendViewToBack(v);
}
break;
}
case MotionEventActions.Move:
{
// click = false;
var left = (int)(e.RawX - _viewX);
newx = left;
var right = (int)(left + v.Width);
var top = (int)(e.RawY - _viewY);
var bottom = (int)(top + v.Height);
v.Layout(left, top, right, bottom);
break;
}
}
}
// _gestureDetector.OnTouchEvent(e);
return true;
}
public void sendViewToBack(View child)
{
var parent = (ViewGroup)child.Parent;
if (null != parent)
{
parent.RemoveView(child);
if(viewType==0)
parent.AddView(QueueListView (theNewsQueue), 0);
else
parent.AddView(QueueListView (theNewsQueue), parent.ChildCount-1);
}
}
}
Now my question is on some devices my current code is giving some abnormal behavior. Like even if I perform OnSingleTapUp() which is supposed to perform click operation but it is performing a move operation. My question is what is wrong with my code so that it is not working correctly. Any help will be greatly appreciated. Thank you.
The onTouch and onClick doesn't work together. In all the cases the onTouch is going to get the priority, in fact onClick in also sort of fine implementation of onTouch. If you want to have onClick sort of functionality, let go the original onClick and try to handle that in onTouch. You can take help of the GestureDetector.SimpleOnGestureListener in Xamarin. For an example to override the double tap you can do it like this
class MyDoubleTapListener : GestureDetector.SimpleOnGestureListener
{
public override bool OnDoubleTap(MotionEvent e)
{
//Your code here
return false;
}
}
and then in your activity
public class Test : Activity, View.IOnTouchListener
{
private GestureDetector _gestureDetector = null;
protected override void OnCreate (Bundle bundle)
{
_gestureDetector = new GestureDetector(new MyDoubleTapListener (this));
_editText.SetOnTouchListener(this);
}
public bool OnTouch(View v, MotionEvent e)
{
return _gestureDetector.OnTouchEvent(e);
}
}
GestureDetector also provides you other methods that you can overide to suit your need. Follow this, https://developer.xamarin.com/api/type/Android.Views.GestureDetector/
I couldn't get exactly what your are trying to do inside onTouch interface. Anyway there's some points you must know:
1) When you handle a touch event, onTouch method returns a boolean that indicates if event was consumed (true) or not (false). If you consume touch event related to click, click listener won't be triggered. So, make sure you are only consuming what is desired.
2) When you set listeners as onClick or onTouch to some view, it becomes clickable and touchable, respectively, if it wasn't. If you are setting this attributes to false in some part of your code make sure it's enabled again when you want to handle such events.

Android GridView item change image on pressed and change back

Problem Description
In my application I have GridView with 12 items in it. Every item in the GridView has its own icon like it is shown in the image below. For every icon I have two images one pressed and one normal.
Question
I try to find some standard mechanisms to change images from Normal state to Presses state when user press on the item and then release the button, but can't find. Instead of that I use public boolean onTouch(View v, MotionEvent event) method but it brings to some side effects for example when user scroll down or slide screen to change tab, items are clicked.
Source Code
#Override
public boolean onTouch(View v, MotionEvent event) {
/* Get Action on Touch. */
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
float currentXPosition = event.getX();
float currentYPosition = event.getY();
lastPressedPosition = gvCategories.pointToPosition((int) currentXPosition, (int) currentYPosition);
if(lastPressedPosition < 0 || lastPressedPosition > sDefaultArray.length)
return false;
/* Set Pressed Image. */
Drawable drawable = getActivity().getResources().getDrawable(sPressedArray[lastPressedPosition]);
Category category = (Category) gvCategories.getItemAtPosition(lastPressedPosition);
category.setImage(((BitmapDrawable) drawable).getBitmap());
CategoriesGridAdapter adapter = (CategoriesGridAdapter)gvCategories.getAdapter();
adapter.notifyDataSetChanged();
}
else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
/* Get current possition to compare with the last one. */
float currentXPosition = event.getX();
float currentYPosition = event.getY();
int currentPosition = gvCategories.pointToPosition((int) currentXPosition, (int) currentYPosition);
if(currentPosition == -1 && lastPressedPosition == -1)
return false;
if (currentPosition == lastPressedPosition && action == MotionEvent.ACTION_UP) {
Category category = (Category) gvCategories.getItemAtPosition(currentPosition);
Log.i(TAG, String.format("Category Title is: %s", category.getTitle()));
if (category == Category.More) {
//tracker.trackEvent("Category Clicked", "More", "", 0L);
/* Get current selected language. */
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
final String lang = preferences.getString(Preferences.LANGUAGE, "en");
/* Load All categories available in the application. */
updateCategoriesAdapter(lang, true);
}
else {
//tracker.trackEvent("Category Clicked", category.getTitle(), "", 0L);
CategoryDetailsActivity.sFragmentManager = getFragmentManager();
/* Start categories detail activity. */
Intent intent = new Intent(getActivity().getApplicationContext(), CategoryDetailsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CategoryDetailsActivity.CATEGORIES_IDS, category.getIDs());
intent.putExtra(CategoryDetailsActivity.CATEGORY_NAME, category.getTitle());
getActivity().getApplicationContext().startActivity(intent);
}
}
if(lastPressedPosition == -1)
return false;
/* Set Pressed Image. */
Drawable drawable = getActivity().getResources().getDrawable(sDefaultArray[lastPressedPosition]);
Category category = (Category) gvCategories.getItemAtPosition(lastPressedPosition);
category.setImage(((BitmapDrawable) drawable).getBitmap());
CategoriesGridAdapter adapter = (CategoriesGridAdapter)gvCategories.getAdapter();
adapter.notifyDataSetChanged();
}
return false;
}
If you have the two images already made, use a Button element in your GridView and set the Background element of your button to a state selector drawable. refer to this link for XML declarations on making your selector drawable example here .
For your scenario you will have to create different selector XML files for each button.

Flipper and ListView in android

I am using Flipper as parent and Listview as child. My problem here is the flipping and clicking of item in listview. When I flip to next page (by dragging from right to left) I accidentally click a list Item.
How will I disable the onClick of listview when I already made a gesture for flipping?
Code:
Flipper Ontouch:
public boolean dispatchTouchEvent(MotionEvent touchevent) {
super.dispatchTouchEvent(touchevent);
switch (touchevent.getAction()) {
case MotionEvent.ACTION_DOWN: {
lastX = touchevent.getX();
break;
}
case MotionEvent.ACTION_UP: {
float currentX = touchevent.getX();
if (lastX - 100 > currentX) {
if (result_pageNum < max_pageNum) {
result_pageNum++;
if (vf.getDisplayedChild() == 0) {
listView[1].setClickable(false);
setListView(1);
} else {
listView[0].setClickable(false);
setListView(0);
}
vf.setInAnimation(this, R.anim.in_from_right);
vf.setOutAnimation(this, R.anim.out_to_left);
vf.showNext();
}
} else if (lastX + 100 < currentX) {
if (result_pageNum > 0) {
result_pageNum--;
if (vf.getDisplayedChild() == 1) {
listView[0].setClickable(false);
setListView(0);
} else {
listView[1].setClickable(false);
setListView(1);
}
vf.setInAnimation(this, R.anim.in_from_left);
vf.setOutAnimation(this, R.anim.out_to_right);
vf.showPrevious();
}
}
break;
}
}
return false;
}
listView onClick:
private void listView_onClick() {
for (int i = 0; i < listView.length; i++) {
listView[i].setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.maketext(this,"Working!",Toast.LENGTH_LONG).show();
}
});
}
}
In your dispatchTouchEvent method, when a fling gesture has been detected (under ACTION_UP event), try returning true as a boolean value rather that returning false every time. When no fling gesture is detected according to your movement calculation, then only return false .
You shouldn't really be using dispatchTouchEvent(MotionEvent) for this purpose.
Instead you should use onInterceptTouchEvent(MotionEvent) and onTouchEvent(MotionEvent).
The relationship between these methods are documented in the methods' Javadoc, but as a summary:
onInterceptTouchEvent(MotionEvent) decides whether a ViewGroup intercepts a user touch events from any of it's child views. For instance, your ViewFlipper decides whether the ListView recieves the events.
onTouchEvent(MotionEvent) is where your ViewFlipper can actually react to it's touch events.

Categories

Resources