ListView - get adjacent items of the clicked item - java

I am trying to make a ListView where you can have no more than 4 items clicked at once.
These items have to be adjacent to each other.
When I click my first item, I want to see if the previous OR the following item is clicked already.
Note: When I click an item, I change the background color. So if I want to tell if an item is clicked or not, I just want to check the background color.
public void OnItemClick(AdapterView<?> parent, View, view, int position, long id){
View currentItem = view;
currentItem.setBackgroundResource(R.drawable.li_gradient);
// How do I get the view in front of and behind currentItem
// to check their current background color? (Assuming they exist)
}

You should do this inside your adapter class, the model item need to have a background resource property.
Just cast the adapter, get the previous or next item, set the new background and notify the listView
public void OnItemClick(AdapterView<?> parent, View, view, int position, long id){
YourAdapterClass adapter = (YourAdapterClass) parent.getAdapter();
// TODO check if is a valid position
YourItem item = (YourItem) adapter.getItem(position-1);
item.setBackgroundResource(R.drawable.li_gradient);
adapter.notifyDataSetChanged();
}

Keep in mind that if the activity is recreated (because of configuration change for example) or if the list view is redrawn (for example when it is notified of a change) it will not automatically know about the changes made to the view in the onClick method and the background changes could be lost.
I would make a custom AdapterView with methods like itemSelected(int i), clearAllSelected(), getSelectedItems(), etc and make the adapterview the single point of responsibility for tracking and maintaining those changes and for rendering the background.

Related

ListView updating more than one row when clicking on one item

I have a ListView where I store a list of order.
When clicking an item, it should expand to let the user see the detail.
The problem is that the item is actually expanding, but so is another item randomly in the list.
If I scroll the list while one item is open, the first item collapse and another take his place. The second expanded item is NEVER in sight, I have to scroll to see it.
I don't understand anything to this bug, can you help me?
Here is the listener that interract with the listview
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
View v = CommandesSalarieActivity.this.list.getChildAt(position);
LinearLayout ll = view.findViewById(R.id.commande_salarie_list_item_layout_main_layout);
ImageView iv = view.findViewById(R.id.commande_salarie_list_item_layout_dropdown);
if (ll.getVisibility() == View.VISIBLE) {
ll.setVisibility(View.GONE);
iv.setImageResource(R.drawable.ic_dropdown_ressource);
} else {
ll.setVisibility(View.VISIBLE);
iv.setImageResource(R.drawable.ic_dropup_ressource);
}
}

Programmatic changes to a view aren't applied

I made a list that's loaded with Contact friends and the user can select them by tapping on them. If a person is selected, the listitem's backgorund changes colour, if deselected, the bg colouring goes away.
Problem is, when I call my method on an OnClickListener, it's fine.
When I however call it in a loop to colour already selected friends (e.g. when revisiting the list), it doesn't do the colouring.
The loop that goes through the elements to call colorize if needed:
for (int i = 0; i < adapter.getCount();i++){
ContactFriend cf = (ContactFriend) adapter.getItem(i);
View v = getViewByPosition(i,listView);
colorizeFriendBg(v, cf);
adapter.notifyDataSetChanged();
}
note I do the exact same in the listener and it works fine there.
And the colorizer:
private void colorizeFriendBg(View v, ContactFriend friend){
if(friend.isSelected()){
v.setBackgroundColor(0x993399ff);
}else{
v.setBackgroundColor(0x00000000);
}
v.invalidate();
}
This issue is quite strange and I have no idea what to do in order to make it right. The whole bunch is called from onActivityCreated, if that matters.
Edit:
I debugged it of course and the code runs and should change the colour, not running isn't the issue.
Edit again:
here's the listener implementation:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ContactFriend fr = (ContactFriend) adapter.getItem(position);
addToSelected(fr);
//TODO: make it switch some BG colour when clicked. use getViewByPosition.
View v = getViewByPosition(position,listView);
colorizeFriendBg(v,fr);
adapter.notifyDataSetChanged();
}
});
what type of item View are you getting from the Adapter?
that View could / should implement colorize() and color itself;
for example: v.colorize(contact.isSelected()) to switch colors.
or with Android Data-Binding XML (where the viewModel is an instance of Contact):
<data class="com.acme.databinding.ContactViewHolderBinding">
<variable name="viewModel" type="com.acme.model.Contact"/>
</data>
...
android:backgroundColor="#{viewModel.isSelected ? R.color.MAGENTA : R.color.BLACK}"
class Contact just would require a getter and a setter for property isSelected.
one actually can also bind event handlers, which would be an alternate approach.
You need to call invalidate() on your view to make the color changes visible.
invalidate() forces a redraw with the new colors.

Set the color of particular element on item in custom adapter

For example I have Custom Adapter List View, and my list item is a layout that contains different elements: textview, imageView and so on. How can I set the color of imageview of selected list item? Suppose I want to add this item in favourite and I want to change the color of star favourite for yellow color. Thank you)
list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getActivity(), PlaceName[position] + " in favourite",
Toast.LENGTH_SHORT).show();
//Do smth here, set the color of element on item, add to favourite and something else
return true;
}
});
Well, you have this line:
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
https://developer.android.com/reference/android/widget/AdapterView.OnItemLongClickListener.html
According to the docs, view is the layout that you actually clicked, so you can get the child of that View using something like this:
ImageView favorite = view.findViewById(R.id.yourFavoriteImageView);
Note that if you scroll through your list, the layout might render again, and your change won't be visible again.
view.setBackgroundColor(Color.parseColor("#222222"));

Change the View's background of a ListView initially

I'm now implementing an application that contains an Activity includes ListView, when the user selects any item in the list view, the background & text color of this view are changed, So, i placed the code of this changes in the onItemClick(AdapterView<?> arg0, View arg1,int position, long arg3) method ..but,this is not the problem.
The problem is, when i open the activity, i need to make an initial selection "before the user selects any thing"..so i made listView.setSelection(index);, but, unfortunately, this code doesn't invoke the onItemClick(AdapterView<?> arg0, View arg1,int position, long arg3)..So, the view doesn't changed "background and text color".
Any solution for that..?!!!
Thanks,
try onItemSelected for selection
selecting a iem in list view does not fires onItemClick
Create a method in yout Adapter to set the selection (or do it in the constructor):
public myAdapter (COntext context, int initialSelectedPos){
setSelectedPos(initialSelectedPos);
}
public void setSelectedPos(int pos){
mSelectedPos = pos;
}
Then check in your getView is given pos is the same than mSelectedPos.
#Override
public View getView(..., int pos){
/*convertView stuff*/
if (pos == mSelectedPos){
//Put the background as it is selected
}else{
//...
}
return view;
}
In your OnItemClick method from your OnItemClickListener call the setSelectedPos method of your Adapter.
You will solve the issue you commented and also when your selected view is no longer visible on screen and comes back to screen, will still be marked as selected ( I am pretty sure it was appearing with the original background).
after setting selection
listView.setSelection(index);
and then after call the
listView.getAdapter().notifyDatasetChanged();
i think this will solve your problem

Set selection on longClick?

How can I set a long-clicked item as selected?
This does not work (item does not maintain selected when clicked):
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
listView.setSelection(position);
return true;
}
});
If you're trying to use a multi-select list, make sure you flag it as such:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
If it's a single-select list, you still need to flag it as a "choice mode" list, as opposed to one where clicking just performs an action, not selects the item.
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
And since you've got the view you want to select being passed in as a parameter, you don't need to set by position, you can set by the view instead, like so:
view.setSelected(true);
Try using
view.setSelected(true);
If the background of your listview items has selected state - this will change the background to this selected state.

Categories

Resources