Android ListView Items select and reset - android

I've a problem with my simple application. It uses a listview that has to:
- open a new Activity when pressed and it's on view mode
- highlight the selected item when it's on edit mode
I'm doing the following:
ListView lv = (ListView)findViewById(R.id.categoryListView);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String entry = (String) parent.getItemAtPosition(position);
if (_editMode)
view.setBackgroundColor(Color.parseColor("#5B5B5B"));
else
{
Intent intent = new Intent(MainActivity.this, CategoryActivity.class);
intent.putExtra("CATEGORY", entry);
startActivity(intent);
}
}
});
Then I want that when I turn to view mode, all items must be deselected, and I do this:
for (int i = 0; i < lv.getAdapter().getCount(); i++)
{
lv.getChildAt(i).setBackgroundColor(Color.parseColor("#FFFFFF"));
}
But this is working fine only if all the items in listview are visible.
I've tried implementing this on the adapter without success...
Any suggestion?
Thanks!
EDIT
Ok after Jawad answer I just figured out how does "getView" method work. So this is the solution I've used:
I declared an arraylist containing selected items:
ArrayList<String> itemSelected = new ArrayList<String>();
This is the ListView onItemClick listener (where you can select and deselect items):
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String entry = (String) parent.getItemAtPosition(position);
if (itemSelected.contains(entry))
{
itemSelected.remove(entry);
}
else
{
itemSelected.add(entry);
}
((ArrayAdapter<String>)lv.getAdapter()).notifyDataSetChanged();
}
});
This is the ovverride of getView method:
itmList.setAdapter(new ArrayAdapter<String>(this,R.layout.list_black_text,R.id.list_content, itmStrList){
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView != null)
{
if (itemSelected.contains(itmList.getAdapter().getItem(position))) {
convertView.setBackgroundColor(Color.RED);
} else {
convertView.setBackgroundColor(Color.parseColor("#5B5B5B"));
}
}
return super.getView(position, convertView, parent);
}
});
And this is how to deselect all items:
itemSelected.clear();
((ArrayAdapter<String>)lv.getAdapter()).notifyDataSetChanged();
Thank you man :)

I think your problem is your are not paying attention to view recycling. When you are changing the color of a view's background, the view can be recycled and you will have something not desired. Check this link for details.
You should have a, lets say boolean variable, in your underlyning data called something like isSelected. And add this code in your getView() method.
if(item.isSelected()){
setBackgroundColor(Color.parseColor("#5B5B5B"));
}
else{
setBackgroundColor(Color.parseColor("#FFFFFF"));
}
Then in your onItemClick add replace view.setback... by
lv.getAdapter().getItem(position).setSelected(true);
lv.getAdapter().notifyDataSetChanged();
You may need a cast.
Finally change this
for (int i = 0; i < lv.getAdapter().getCount(); i++)
{
lv.getChildAt(i).setBackgroundColor(Color.parseColor("#FFFFFF"));
}
to this:
for (int i = 0; i < lv.getAdapter().getCount(); i++)
{
lv.getAdapter().getItem(i).setSelected(false);
}
lv.getAdapter().notifyDataSetChanged();
The reason why your portion of code works only if all the items are visible is view recycling. Moreover lv.getChildAt() gives you only the views that are visible. Your code may then crash because adapter.getcount maybe bigger then the number of listview childs.
Hope it helps.

Related

Android Spinner duplicate item gives only position of the first duplicated item

I made a spinner with items from MySQL. In MySQL I have got 2 items with the same value. In the spinner I have got 2 duplicates then. When I try to select the second one I get the position of the first one (this is not correct), and when I select the first one I get the position of the first one (this is correct).
Code:
sp.setVisibility(View.VISIBLE);
//BIND
final ArrayAdapter adapter = new ArrayAdapter(c, android.R.layout.simple_spinner_dropdown_item, optochtenarray){
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View itemView = super.getDropDownView(position, convertView, parent);
if (position == mSelectedIndex) {
itemView.setBackgroundColor(Color.rgb(56,184,226));
}
else {
itemView.setBackgroundColor(Color.TRANSPARENT);
}
return itemView;
}
};
sp.setAdapter(adapter);
//call ID
sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View view, int position, long id) {
String selectedItem = sp.getSelectedItem().toString();
if (selectedItem != "Kies..."){
//kleur veranderen
mSelectedIndex = sp.getSelectedItemPosition();
Log.e("selectPosition", Integer.toString(mSelectedIndex));
Log.e("ID", idarray.get(position));
//naar de volgende pagina met de 'ID'
Intent myIntent = new Intent(c, gekozenOptocht.class);
myIntent.putExtra("ID", idarray.get(position)); //Optional parameters
c.startActivity(myIntent);
sp.setSelection(adapter.getPosition("Kies..."));
}
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Why am I getting the position of the first one when I try to select the second one?
Use position parameter or mSelectedIndex variable for get position.
sp.setSelection(position);
PROBLEM SOLVED! It has something to do with the custom spinner that I had found on the internet.

How to make listview selected one item element?

I am working on the custom Listview using BaseAdapter. I am facing one small issue after tap on listview item that particular row gets highlighted but after that if i'll tap one another list item it's highlighted but still the older one it remains same it's not going to it's previous state.
I want to see one item should select at one time.
MainActivity.java
if (musicRealmResults.get(currentIndex).isSelected() == false) {
musicRealmResults.get(currentIndex).setIsSelected(true);
playSong(currentIndex, true);
adapter.notifyDataSetChanged();
} else {
musicRealmResults.get(currentIndex).setIsSelected(false);
adapter.notifyDataSetChanged();
}
MusicAdapter.java
if (musicRealmResults.get(position).isSelected()) {
Typeface tf = Typeface.createFromAsset(mContext.getAssets(), "fonts/fonts_bold.otf");
holder1.albumsTextView.setTypeface(tf);
holder1.equalizerView.setVisibility(View.VISIBLE);
holder1.albumsImageView.setVisibility(View.INVISIBLE);
holder1.equalizerView.animateBars();
} else {
Typeface tf = Typeface.createFromAsset(mContext.getAssets(), "fonts/fonts_regular.otf");
holder1.albumsTextView.setTypeface(tf);
holder1.equalizerView.setVisibility(View.GONE);
holder1.albumsImageView.setVisibility(View.VISIBLE);
holder1.equalizerView.stopBars();
}
Please kindly go through my post and suggest me how to do select and deselect in a listview row.
Loop through all your array elements and set check state to false, then set currentIndex to true.
MainActivity
for(int i =0 ; i < musicRealmResults.size() ; ++i){
musicRealmResults.get(i).setIsSelected(false);
}
musicRealmResults.get(currentIndex).setIsSelected(true);
playSong(currentIndex, true);
adapter.notifyDataSetChanged();
Seems that you weren't able to setSelected(false) your previous item.
Please check setChoiceMode() of ListView or you may just reset your previous item to setSelected(false).
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
musicRealmResults.get(currentSelected).setIsSelected(false); //Reset previous
currentSelected = position; //Save currentPosition to for reset later
.....todos
}
This is a good alternative too, if u dont want to loop through the rest of positions to deselect them.
int prevSelection =-1; //nothing selected
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (prevSelection==-1) //nothing selected
{
musicRealmResults.get(position).setIsSelected(true);
adapter.notifyDataSetChanged();
prevSelection = position;
}else if (prevSelection == position) //deselect previously selected
{
musicRealmResults.get(position).setIsSelected(false);
adapter.notifyDataSetChanged();
prevSelection = -1;
}else // Some other selection
{
musicRealmResults.get(prevSelection).setIsSelected(false);
musicRealmResults.get(position).setIsSelected(true);
adapter.notifyDataSetChanged();
prevSelection = position;
}
You can manage this in your model class. Just make a toggle Boolean isSelected with its getter and setter, When user tap on list item check whether its already selected or not, if not then mark it as selected and update the Boolean value in your model class.
mListLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(list.get(position).getisSelected()){
// list item is already selected.
mListLayout.setBackgroundColor(Color.WHITE); // normal color
list.get(position).setisSelected(false);
}
else{
// list item is not selected, make it selected
mListLayout.setBackgroundColor(Color.GRAY); // selected color
list.get(position).setisSelected(true);
}
notifyDataSetChanged();
}
});
Try Below Code:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if (musicRealmResults.get(position).isSelected() == false)
{
musicRealmResults.get(position).setIsSelected(true);
playSong(position, true);
adapter.notifyDataSetChanged();
}
else
{
musicRealmResults.get(position).setIsSelected(false);
adapter.notifyDataSetChanged();
}
}
});

Get all views in listview in setOnItemClickListener

I am using below code to setcolor of a selected item of a listview. The rule is only one should be colored. But with below code if I select 2 views both get colored. Can you please help me get all other views in the listview so that when I click on certain view all other views i set to different color and the selected view i set a different color(Green in this case).
Please let me know if any other solution?
lv = (ListView) view.findViewById(R.id.listf);
lv.setAdapter(text![enter image description here][1]Adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView v = (TextView) view.findViewById(R.id.template_text);
view.setBackgroundColor(Color.GREEN);
}
});
I resolved the problem using the below:
I put a loop where only the selected list item is set in RED whereas all others were set in Green, in this way only only one list item will be colored on selected.
lv = (ListView) view.findViewById(R.id.listf);
lv.setAdapter(Adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < 3; i++)
{
if (position == i)
{
parent.getChildAt(i).setBackgroundColor(Color.RED);
}
else
{
parent.getChildAt(i).setBackgroundColor(getResources().getColor(R.color.Dark_Green);
}
}
TextView v = (TextView) view.findViewById(R.id.template_text);
view.setBackgroundColor(Color.GREEN);
}
});
As you told you are not able to change adapter code, you can prefer solution 2.
Solution 1: Create one variable int selectedPosition and method setSelected in your adapter class
int selectedPosition = -1;
public void setSelected(int position)
{
selectedPosition = position;
notifyDatasetChanged();
}
Edit getView() of the adapter class and include following code
if(selectedPosition==position)
{
templateTextView.setBackgroundColor(Color.GREEN);
}
else templateTextView.setBackgroundColor(Color.BLUE);// default textView color
Solution 2: keep reference of previously selected textView as well each time change the color of currently selected textview to green andd previous one to blue
TextView previousSelected = null;
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(previousSelected!=null)
previousSelected.setBackgroundColor(Color.BLUE);
TextView v = (TextView) view.findViewById(R.id.template_text);
view.setBackgroundColor(Color.GREEN);
previousSelected = v;
}
});

How to get a specific Item from a ListView by clicking on it?

First of all, I'm a beginner in android programming. So dont be too harsh :P
Anyway, I have a recycling ListView, containing an Image and a Text per List Item.
Let's say there are 100 different Items. Every Item clicked leads me to my Activity "DetailActivity.class" with the "detail_layout.xml". Now I want to configurate this layout depending on which Item was clicked.
TestActivity.java:
ArrayList<String> list = new ArrayList<String>();
for(int i = 0; i <= 99; i++) {
list.add(detail_array[i]);
//detail_array[] contains Strings which are used to add Items to the list.
}
private ListView myList = (ListView)findViewById(R.id.list);
myList.setAdapter(new MyCustomAdapter(TestActivity.this,list));
MyCustomAdapter.java:
public class MyCustomAdapter extends BaseAdapter {
private ArrayList<String> mListItemsTV;
private LayoutInflater mLayoutInflater;
public View getView(int position, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = mLayoutInflater.inflate(R.layout.list_item, null);
holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);
view.setTag(holder);
} else {
holder = (ViewHolder)view.getTag();
}
String stringItem = mListItemsTV.get(position);
if (stringItem != null) {
if (holder.itemName != null) {
holder.itemName.setText(stringItem);
ImageView imageView = (ImageView) view.findViewById(R.id.list_item_image_view);
if(holder.itemName.getText() == "SomeName") {
imageView.setImageResource(R.drawable.somedrawable);
}
return view;
}
To be honest, I've got those from some kind of tutorial and I guess I know whats happening there^^
Now, how can I manage to get which Item was clicked? I tried it several times with "setOnClickListener" but it never seems to work. How do I use this? Should I use this? Where do I have to use it?
The basic idea is listview is generally dynamic so you will have a collection of an arbatrary number of items that you want to register with a listener. Oclicklistener will not work unless you register each item separate (not a good idea). Use onitemclicklistener to register the collection this link should help. http://www.ezzylearning.com/tutorial.aspx?tid=1351248&q=handling-android-listview-onitemclick-event
You'll want to use setOnItemClickListener. This is an example on how it's used. You'll need to adapt it to your code. But you can see how you would reference an individual item in the list.
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
final String item = (String) parent.getItemAtPosition(position);
view.animate().setDuration(2000).alpha(0)
.withEndAction(new Runnable() {
#Override
public void run() {
list.remove(item);
adapter.notifyDataSetChanged();
view.setAlpha(1);
}
});
}
});
}
I'll fix the formatting when I get home. On mobile ATM. If anyone wants to edit the code feel free.
If you don't want to use an adapter then try this:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
switch(position){
/*
* The case is the list position
*/
case 0:
break;
case 1:
break;
}
}

Android: how to remove an item from a listView and arrayAdapter

I have a collection of items in an ArrayList. I add them to a customer adapter as follows:
this.m_adapter = new MyAdapter(this, R.layout.myitem,
itemCart.m_items);
I have a delete button for each of these items in my list, but I am not sure how to connect the delete button's onClick() with the original item in the ArrayList. Can someone please explain how to do this or point me to a tutorial where I can read up on this? Non-sarcastic/non-condescending responses are greatly appreciated.
You can call the remove() method on your ArrayList
itemCart.m_items.remove(<index of element to remove>);
this.m_adapter.notifyDataSetChanged();
And then you need to call notifyDataSetChanged(); on your adapter to update the ListView
You can get the index of the element by simply noticed that a list view is a collection of child views (the rows of the list).
You can do something like this in your code:
(inside the getView() method, for example)
row.setOnLongClickListener(new OnLongClickListener()
{
#Override
public boolean onLongClick(View view) {
remove(listView.indexOfChild(view));
return true;
}
}
That is, the solution is simply use indexOfChild(View) method to get index of child view that user (long) pressed.
Here's my solution so far:
In the getView() method I do something like this:
deleteButton.setTag(position);
It looks like getTag() returns an Object. So I converted the position int into an Integer object first. It appears to be working.
In the OnClickListener() I do the following:
items.remove(index.intValue());
So far, so good.
Following works for me:
/* Read values from resource into an array */
String[] strColorValues = getResources().getStringArray(R.array.colors);
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < strColorValues.length; i++) {
list.add(strColorValues[i]);
}
ArrayAdapter adapterColors = new ArrayAdapter(getActivity(), android.R.layout.simple_spinner_item, list);
adapterColors.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerColors.setAdapter(adapterPermissionLevels);
spinnerColors.setOnItemSelectedListener(this);
/* Remove first element from the adapter and notify dataset changed. */
String item = spinnerColors.getItemAtPosition(0).toString();
adapterColors.remove(item);
adapterColors.notifyDataSetChanged();
Here's my Code.
transfer.setItemPosition(position, items.get(position).getAddMode());
the transfer here is the instance of the main class. everytime i click the deletebutton, it then pass the position of the that item on the list in this line.
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
final Context context = getContext();
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.listviewitem_layout, null);
}
ItemEntry item = items.get(position);
if (item != null) {
TextView textViewName = (TextView) v.findViewById(R.id.textViewItemName);
ImageView imageViewDelete = (ImageView) v.findViewById(R.id.imageViewDeleteIcon);
imageViewDelete.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
transfer.showDialog(4);
transfer.setItemPosition(position, items.get(position).getAddMode());
}
});
if (textViewName != null) {
textViewName.setText(item.getItemName());
}
if(imageViewDelete != null) {
imageViewDelete.setImageResource(R.drawable.delete);
}
}
return v;
}
}
Remove by position:
mainAdapter.remove(mainAdapter.getItem(position));
Such as the last one:
mainAdapter.remove(mainAdapter.getItem(mainAdapter.getCount() - 1));
Try these codes of lines it was very helpful for me
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, list.size());
}
});
If you use context menu, then you can get
AdapterContextMenuInfo and this structure gives index and id of clicked element.
It seems that you can get the index (or position) of a clicked item in the ListView as follows:
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listview.remove(listview.getItem(position).toString());
}
}
So you need to listen for clicks on Views and then take the index from that.

Categories

Resources