I am trying to make long and normal onItemClickListener for my ListView. This code works but when I call the Long-click and removing my finger after the longClickListener was triggered onItemClickListener triggers too. What I'm doing wrong?
listView.setOnItemClickListener(new SubjectOnItemClick(listAdapter, getSherlockActivity()));
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
new ColorPickerDialog(
getSherlockActivity(),
listAdapter,
position
);
return false;
}
});
Simpy,return true instead of return false in your onItemLongClick.
Returning true means telling Android you already got what you want, and need nothing more. Hence, the code will stop. (not triggering onClick)
Related
I have a ListView that when I hold (long touch) on an item, the item is removed from the list.
It's registering a touch right after, while the long touch is still happening.
Here is my code -
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), MapsActivity.class);
intent.putExtra("placeNumber", i);
intent.putExtra("Type", "Fav");
startActivity(intent);
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Log.i("Removing", "" + favouriteLocations.get(position));
favouriteLocations.remove(position);
Favourites.arrayAdapter.notifyDataSetChanged();
return false;
}
});
After letting go of long touch a 'phantom' touch appears on the item where the long touch had been (a new item has moved up in the list) and the activity loads as if it has been touched.
It worked fine at one point, I'm sure I didn't change the code. Any ideas?
Thanks.
you need to return true from the long click listner, you must have this in the xml too android:longClickable="true" but list view is long clickable by default so no need to update xml at all.
I wish to have a behaviour x when I click an item and a behaviour y when I push and hold the same item. I seem to be able to do one or the other, but not both.
So I have this Listview lv.
In onCreate I give it
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.v(TAG, "click position: " + position);
}
});
And when I click any item in my listview I get the log.
Say I remove the setOnItemClickListener. And now I add:
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
Log.v(TAG, "long click position: " + position);
return true;
}
});
When I do a long click (press and hold for 3s) I get the log. Yay.
But, if I try to use both together, the setOnItemLongClickListener eclipses the setOnItemClickListener. The onItemClick never gets called and only when I do a long click do I get the line logged.
The xml holding the items in the ListView has both:
android:longClickable="true"
android:clickable="true"
What fundamental concept about what I am trying to do did I get wrong?
If all else fails you can use onTouch on the listview and use 2 threads to handle long touches and short touches. It becomes alot more of a pain, but this is how i built a dragNdrop listview and swipe to delete listview. I hope that gives you a start in a way to solve this.
Ironically, from the xml containing my ListView items I removed the following:
android:longClickable="true"
android:clickable="true"
And now both listeners work as I intended them to!
I have a list view in which I have implemented both onItemClick and onItemLongClick.
The list view row is custom where there is checkbox which is selected when ItemClick happens.
Now WHen User does a long click, I am still getting a ItemClick which selects the checkbox and this looks odd as the user is trying to do something else.
How to fix this
Set an OnItemLongClickListener for your list view.
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
/*Make sure to return true so that the event will be consumed here, and not
propogated to the onListItemClick listener.*/
return true;
}
});
See similar answer here.
I need to change the Adapter of my Spinner exactly at the moment when I click on it.
I'm trying to display a Spinner with The value "Make Your choice" and then when the user click, another adapter is loaded on the Spinner and he can make his choice (without displaying the "Make Your choice").
Here is my code
ArayAdapter adapterclasse = new ArrayAdapter(this,android.R.layout.simple_spinner_item, affp.classes);
ArrayAdapter adaptermodule = new ArrayAdapter(this,android.R.layout.simple_spinner_item, affp.matiers);
spinner.setAdapter(adapterclasse);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
spinner.setAdapter(adaptermodule);
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
but it's not working. When the app is launched, I got the second adapter loaded instead of the first.
Please help and thanks.
The second adapter is set because when the spinner is loaded the method onItemSelected is called, that's normal (the first element is selected).
Anyway, in general I don't think you need 2 adapters, you can just put "Make Your choise" on top and onItemSelected if the user has selected that, you can stop him and ask to select a real value.
Actually, it's possible to load a new adapter when the user touch the view (spinner)
spinner.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
spinner.setAdapter(adapterclasse2);
return false;
}
});
It appears that android's Spinner class (and possibly ListView in general, although I don't know for sure) calls your OnItemSelectedListener's onItemSelected() method after you call setAdapter(), even if the user hasn't explicitly selected anything yet.
I can see how this would be useful in many situations, but there are times when I only want onItemSelected() to be called when an item is actually specifically selected.
Is there a way to control this behaviour and have Spinner NOT call onItemSelected() after setting the adapter?
I haven't used this solution for very long yet so I'm not totally confident that it works as expected, but I've had luck so far with this workaround:
spinner.setOnItemSelectedListener( new OnItemSelectedListener() {
protected Adapter initializedAdapter = null;
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Always ignore the initial selection performed after setAdapter
if( initializedAdapter !=parent.getAdapter() ) {
initializedAdapter = parent.getAdapter();
return;
}
...
}
}
Is there a better way?
Add listener to spinner like below:
spinner.post(new Runnable(){
public void run()
{
spinner.setOnItemSelectedListener( new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
...
}
}
}
});
I've used the setTag and getTag methods, and created a resource id called "spinnerstate".
Then whenever I programmatically set the adapter, I set the "spinnerstate" tag to "init", and in the fired event, set it to "ready" and ignore the event. (note my code is Mono for Android se it will look different):
Set Adapter:
profileSpn.SetTag (Resource.Id.spinnerstate, "init");
profileSpn.Adapter = new ArrayAdapter (this, Android.Resource.Layout.SimpleSpinnerItem, items.ToArray ());
Item Selected event:
string state = (string)((Spinner)sender).GetTag (Resource.Id.spinnerstate);
if (state == "init") {
((Spinner)sender).SetTag (Resource.Id.spinnerstate, "ready");
return;
}
I agree that this is not desired behaviour in almost 100% of cases, and I don't think it's good design on the part of Google, but there you go.
I did similar things before, I used count value. Using parent adapter object is incomplete because it can be a problem when view is refreshed or getView() called again.
Therefore, I recommend that using array of counter.
At first, define array of count in adapter globally.
private int isInitializedView[];
And then initialize it on getView().
isInitializedView[position] = 0;
In the selection listener, do something that you want if it already initialized.
holder.mySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
isInitializedView[position]++;
if(isInitializedView[position] > 1) {
// do someting that you want
}
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {}
});
(Note that isInitializedView[position]++; can be come after if() routine, and only trigger event when this value is >0 . It's your choice.)
I had three spinner in my activity and all spinner adapter data has been filled at runtime(from web-service data after call from onCreate method). So it automatically call onItemSelected(AdapterView<?> parent, View view, int position, long id) method of spinner.
I solved this issue by using onUserInteraction() method of activity
check this method that user is interacting with spinner or not. if yes then perform the action else not
Declare isUserIntract boolean variable globally
in onItemSelected method use following procedure
If(isUserIntract)
{
//perform Action
}
else{
//not perform action
}
use below code in activity
#Override
public void onUserInteraction() {
super.onUserInteraction();
isUserIntract = true;
}