I want to be able to long press items in the spinner view and have a contextMenu appear. I tried this code:
spinner = (Spinner) findViewById(R.id.catagorySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,android.R.layout.simple_dropdown_item_1line, data);
spinner.setAdapter(adapter);
registerForContextMenu(spinner);
but as you can guess this added a context menu to the actual Spinner and not to the contents inside. Does anyone know how i can do this?
Have you tried this?
spinner.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int arg2, long arg3) {
view.showContextMenu();
return true;
}
});
You can register for each item inside the adapter's getView() method.
View getView(View convertView, ... ) {
....
// inflate view or reuse.
....
getContext().registerForContextMenu(convertView);
....
return convertView;
}
Related
I would like to change an item background color when clicked, in a simple listView. Here's my code:
boolean[] selectedItem = new boolean[listElement.length]
final ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1, listElement);
final ListView mylist = (ListView) findViewById(R.id.listView);
final ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, list1);
mylist.setAdapter(adapter);
mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
int firstVisiblePosition = mylist.getFirstVisiblePosition();
int effectivePosition = pos - firstVisiblePosition;
if (!selectedItem[pos]) {
mylist.getChildAt(effectivePosition).setBackgroundColor(Color.parseColor("#66F44336"));
} else {
mylist.getChildAt(effectivePosition).setBackgroundColor(Color.parseColor("#EEEEEE"));
}
selectedItem[pos] = !selectedItem[pos];
}
});
When the list is short (no scroll involved) it works, when it's long it does not: the background color of the clicked item does change, but when I start to scroll the background color of every item starts to change, and I can't find any logic in those changes, they change and reverse without me even touching them, just by scrolling, wich is strange since the color should only change when onItemClick() is called, right? What am I missing?
You're missing the point that the ListView re-uses its item layouts when they go out of screen (i.e. you scroll the list).
You need to save the background for each of your item and set it once the view is requested. That happens inside of ListView adapter's getView.
A quick fix would be to use a custom adapter on the go:
final boolean[] selectedItem = new boolean[listElement.length];
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, list1) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (selectedItem[position]) {
view.setBackgroundColor(Color.parseColor("#66F44336"));
} else {
view.setBackgroundColor(Color.parseColor("#EEEEEE"));
}
return view;
}
};
This lacks error checking but you should get the idea. Good luck!
I'm trying to get an AutoCompleteTextView's ID after I clicked a value on the list. Tried looking up on google and stackoverflow, but the provided answers didn't work. Here's what I've got:
Created the view in my class declaration:
public class ActivityCadastrarCliente extends Activity implements OnClickListener, OnItemClickListener {
AutoCompleteTextView E_Nome_Cliente, E_CPF;
List<String> Nomes = new ArrayList<String>();
...
Associated the view to an XML element:
E_Nome_Cliente = (AutoCompleteTextView)findViewById(R.id.Nome_Cliente);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, Nomes.toArray(new String[0]));
E_Nome_Cliente.setAdapter(adapter);
E_Nome_Cliente.setOnItemClickListener(this);
and my onItemClick method is called normally as below:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//switch (parent.getId()) {
//case R.id.Nome_Cliente:
...
//}
}
Does anybody know how I can access this view inside onItemClick? Tried several ways, but I only get exceptions:
//Class cast exception
AutoCompleteTextView input = (AutoCompleteTextView)view.getParent();
//Class cast exception
AutoCompleteTextView input = (AutoCompleteTextView)parent;
//Class cast exception
AutoCompleteTextView input = (AutoCompleteTextView)parent.getParent();
I need to identify which view was clicked, because I'm using 3 to 5 AutoCompleteTextView and based on the selected value I'll automatically fill in a bunch of other fields.
Have a look at the class AutoCompleteTextViewClickListener in this answer.
Change your setOnItemClickListener call in the following way:
E_Nome_Cliente.setOnItemClickListener(
new AutoCompleteTextViewClickListener(E_Nome_Cliente, this));
Now you can get the id by accessing the modified view parameter:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view had been modified by AutoCompleteTextViewClickListener
//to contain the original AutoCompleteTextView
switch (view.getId()) {
case R.id.Nome_Cliente:
//...
}
}
An easier way:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Adapter adapter = parent.getAdapter();
if (adapter == autoCompleteTextView1.getAdapter()) {
// Do something
} else if (adapter == autoCompleteTextView2.getAdapter()) {
// Do something else
}
}
i am not sure what do you mean by view id? do you want to get the selected value?
if yes, then the below code will do it, otherwise please clarify more what do you need and why you want to access the view itself.
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//switch (parent.getId()) {
String selected = adapter.getItem(position);
//}
}
more on adapter methods are here
Use parent.findViewById(R.id.id_of_autocompleteTextView) on the parent of the AutoCompleteTextView.
I have a requirement wherein I want to disable items in the list view.
Say e.g., I have 5 items in the listview out of which I want to only enable 1 item.
Note: disabling means greying out the item.
Following is my code:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,android.R.layout.simple_list_item_1, movies);
I don't want to go with the custom adapter wherein we get the getView().
Is there any other way to implement this functionality?
In the adapter there is a method name isEnabled which you can override. This is called for each row like getview. The onclicklistener will only fire if this function returns true. So try doing that in your custom adapter.
#Override
public boolean isEnabled(int position) {
if(YOUR CONDTITION){
return false;
}
return true;
}
Without adapter:
Then you need to disable the item by getting view at specific position.
Please implement the listener for this method setOnItemSelectedListener . So you can disable any item that you want.
You can also disable item using:
final Set<Integer> disabledPositions = new HashSet<Integer>();
disabledPositions.add(positionYouWantToDisable);
disabledPositions.add(positionYouWantToDisable);
disabledPositions.add(positionYouWantToDisable);
ListView listView = new ListView(this);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long arg3) {
if(!disabledPositions.contains(position) {
// do what you want
}
}
});
try this:
final List<Integer> disabledItems = new ArrayList<Integer>();
disabledItems.add(0);
disabledItems.add(2);
lvMovies.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if (disabledItems.contains(arg2)) {
Toast.makeText(getApplicationContext(), "DISABLED", Toast.LENGTH_SHORT).show();
arg1.setEnabled(false);
} else {
Toast.makeText(getApplicationContext(), "NOT DISABLED", Toast.LENGTH_SHORT).show();
arg1.setEnabled(true);
}
}
});
Long version I have two spinners on my screen and when I select the one, I do certain operations, and the other spinner should display the original selection, because of design patterns. In this situation, I let the user select the elements on a list by year, and by state. You would agree with me that when the user choose to select by year, the spinner regarding the state should display the default selection (the one that displays all of the item) and not the last selected one.
I am trying to do this from this morning, but when I found this solution I really though I was done.
Short version I want to setSelection(0) on the spinner which is not clicked, without triggering its listener (which by the way, will setSelection(0) on the first spinner, if triggered)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
// irrelevant code...
mYearSpinner.setOnItemSelectedListener(onYearSelected);
mStateSpinner.setOnItemSelectedListener(onStateSelected);
// irrelevant code...
}
private AdapterView.OnItemSelectedListener onYearSelected = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mStateSpinner.setOnItemSelectedListener(null);
mStateSpinner.setSelection(0);
mStateSpinner.setOnItemSelectedListener(onStateSelected);
// Do something...
}
#Override
public void onNothingSelected(AdapterView<?> parent) { }
};
private AdapterView.OnItemSelectedListener onStateSelected = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mYearSpinner.setOnItemSelectedListener(null);
mYearSpinner.setSelection(0);
mYearSpinner.setOnItemSelectedListener(onYearSelected);
// Do something...
}
#Override
public void onNothingSelected(AdapterView<?> parent) { }
};
But no! The listeners will just fire, indiscriminately.
Is there someone who knows how to handle this problem?
Why this solution wouldn't work?
As requested, here is the full code of my onCreateView(...) method
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_career, container, false);
mExamListView = (ListView) view.findViewById(R.id.exam_list_view);
mYearSpinner = (Spinner) view.findViewById(R.id.select_by_year_spinner);
mStateSpinner = (Spinner) view.findViewById(R.id.select_by_state_spinner);
mLoadingView = view.findViewById(R.id.fragment_career_loading_spinner);
mExamListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Exam exam = (Exam) parent.getItemAtPosition(position);
if (exam.isBookable()) {
FragmentManager fm = getActivity().getSupportFragmentManager();
SessionsDialogFragment.newInstance(exam).show(fm, null);
}
}
});
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> yearAdapter = ArrayAdapter.createFromResource(getActivity(),
R.array.spinner_year, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
yearAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> stateAdapter = ArrayAdapter.createFromResource(getActivity(),
R.array.spinner_state, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
stateAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mYearSpinner.setAdapter(yearAdapter);
mStateSpinner.setAdapter(stateAdapter);
mYearSpinner.setOnItemSelectedListener(onYearSelected);
mStateSpinner.setOnItemSelectedListener(onStateSelected);
return view;
}
I tried implementing what --- suggested and I want to report here what happens.
When the application starts all the two listeners are executed only once.
Then, if I select an item on the first spinner (let's say the year spinner), the expected listener is executed only once (as it should be), and so it is, if I keep selecting items on it.
Ultimately, if I select and item on the state spinner, the listeners are executed in this way
1. onStateListener
2. onYearListener
3. onStateListener
From reading your comments it sounds like you want to set the selection of a second spinner to 0 from your first spinners onItemClick method without triggering its listener.
If you keep a record of the old position the spinners are at in integer variables we can check if the position has changed and only run the code if it has.
That way if we set the old position variable to 0 before changing the spinners current position to 0 it will think its position hasn't changed and so won't run the code in the listener.
private AdapterView.OnItemSelectedListener onYearSelected = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (lastYearPosition != position) {
//Do you code here
lastStatePosition = 0;
mStateSpinner.setSelection(0);
}
lastYearPosition = position;
}
#Override
public void onNothingSelected(AdapterView<?> parent) { }
};
private AdapterView.OnItemSelectedListener onStateSelected = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (lastStatePosition != position) {
//Do your code here
lastYearPosition = 0;
mYearSpinner.setSelection(0);
}
lastStatePosition = position;
}
I'd like to have both type of clicks on a listView - onClick and LongClick.
I've implemented it like this:
this.listViewSub = (ListView) this.findViewById(R.id.listsub);
this.listViewSub.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(final AdapterView parent, final View view, final int position,
final long id) { ... } });
// listen to long click - to share texts
this.listViewSub.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) { ... } });
But it does't fire the Long Click.
Anyone has any idea why?
You have to enable the LongClickable
list.setLongClickable(true);
and
list.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int arg2, long arg3) {
}
});
#Vadim, are your listview's adapter is extends from BaseAdapter? if yes, then also need to set convertView.setLongClickable(true); in the getView().
For me, I had to set android:longClickable="true" in the XML file that contains my ListView row layout (not ListView layout) for the item to be long-clickable.
onLongClick returns true if the callback consumed the long click, false otherwise. So if the event is handled by this method, return true.