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();
}
}
});
Related
I have a RecyclerView with a large list of items. This RecyclerView has OnScrollListener for endless scrolling.
When an item is selected I highlight it with a specific colour and
when unselected the colour changes to normal/white.
The issue that I am facing is after selecting a few visible items in my view when I scroll up or down to select a few more items the colour of already selected items changes to white.
I tried adding a boolean variable (isSelected) in the model class and highlight the selected item but still I am facing the same issue as earlier. Currently the recyclerView allows to select just one item from the view and after some research I figured some of the concepts were taken from this article to implement single item selection. I wonder how do I modify/tweak this code to be able to select multiple items.
I am not presenting the code as it is quite huge and is confidential but if there is any general fix for this scenario then what would it be?
Background: the application is a chat app and I am showing the sent and received texts. The user should be able to select a few specific texts and should be able to share it with someone else.
Edit: I am putting the code in my onBindViewHolder:
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final PostDataColumns mPostDataColumns = data.get(position);
holder.textCardView.setBackgroundColor(mPostDataColumns.isSelected() ? getResources().getColor(R.color.long_press):
getResources().getColor(android.R.color.white));
holder.textCardView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mPostDataColumns.setSelected(!mPostDataColumns.isSelected());
if(mPostDataColumns.isSelected()) {
holder.textCardView.setBackgroundResource(R.color.long_press);
multipleSelectedPositions.add(holder.getLayoutPosition());
} else if(!mPostDataColumns.isSelected()) {
holder.textCardView.setBackgroundResource(android.R.color.white);
multipleSelectedPositions.remove(holder.getAdapterPosition());
}
//Adapter.this.onLongClick(holder, position);
return true;
}
});
holder.textCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.textCardView.setBackgroundResource(android.R.color.white);
/* clearLongSelection(holder, position, alignParentRight,
data.get(position).getReceiverUserId().length() > 5); */
}
});
}
The code which I have commented in onCLick and onLongClick were used when the requirement was to select a single item.
these are the methods which were called in onClick and onLOngClick:
public boolean clearLongSelection(ViewHolder holder, int position) {
if (selectedPosition >= 0) {
if (selectedPosition == position) {
holder.parentLayout.setBackgroundResource(android.R.color.transparent);
if (alignParentRight) {
holder.mediaCardView.setBackgroundResource(android.R.color.white);
holder.assessmentCardView.setBackgroundResource(android.R.color.white);
holder.surveyCardView.setBackgroundResource(android.R.color.white);
holder.documentCardView.setBackgroundResource(android.R.color.white);
holder.textCardView.setBackgroundResource(android.R.color.white);
} else {
holder.mediaCardView.setBackgroundResource(R.color.long_press);
holder.assessmentCardView.setBackgroundResource(R.color.long_press);
holder.surveyCardView.setBackgroundResource(R.color.long_press);
holder.documentCardView.setBackgroundResource(R.color.long_press);
holder.textCardView.setBackgroundResource(R.color.long_press);
}
selectedPosition = -1;
invalidateOptionsMenu();
getSupportActionBar().setTitle(intentData.getName());
}
return true;
}
return false;
}
public void onLongClick(ViewHolder holder, int position) {
if (selectedPosition < 0) {
holder.parentLayout.setBackgroundResource(R.color.long_press);
holder.mediaCardView.setBackgroundResource(R.color.long_press);
holder.assessmentCardView.setBackgroundResource(R.color.long_press);
holder.surveyCardView.setBackgroundResource(R.color.long_press);
holder.documentCardView.setBackgroundResource(R.color.long_press);
holder.textCardView.setBackgroundResource(R.color.long_press);
selectedPosition = position;
invalidateOptionsMenu();
getSupportActionBar().setTitle("1 Selected");
} else {
}
}
The variable selectedPosition in onClick and clearLongSelection is initialised in the class as instance variable- selectedPosition = -1.
Use SparseBooleanArray to keep track of selected items in recycler view adapter
Initialize the SparseBooleanArray as private memeber variable
private SparseBooleanArray mClickedItems=new SparseBooleanArray();
Then inside your click function while clicking any item,store the clicked item position as true.
mClickedItems.put(getAdapterPosition(),true);
notifyDataSetChanged();
Then in the onBindViewHolder check if the position is already selected or not like this
if(mClickedItems.get(position)==true){
//Show selected color
}else {
//show unselected color
}
I have a problem with my listview. What I want to do is when I click an item in the listview, it should remain highlighted, and when I click another item, new item should be highlighted.
Here's what I've done so far:
public void setSelection(int position) {
if (selectedPos == position) {
selectedPos = NOT_SELECTED;
} else {
selectedPos = position;
}
notifyDataSetChanged();
}
Adapter GetView:
if (position == selectedPos) {
// your color for selected item
viewHolder.tvTitle.setTextColor(context.getResources().getColor(R.color.main_blue));
viewHolder.tvDetails.setTextColor(context.getResources().getColor(R.color.main_blue));
}
else {
// your color for non-selected item
viewHolder.tvTitle.setTextColor(context.getResources().getColor(R.color.dark_grey));
viewHolder.tvDetails.setTextColor(context.getResources().getColor(R.color.dark_grey));
}
Activity:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
episodesAdapter.setSelected(position);
}
});
This is working as expected, but the problem is with notifyDataSetChanged, it's delaying the time to highlight item that is being selected next. What should I do to automatically get it highlighted? Any help would be truly appreciated. Thanks!
Update:
I tested and it took 8-10secs before a new item is highlighted. There is a slight delay in highlighting an item.
Is there any way to find whether an item in a ListView is clicked for the first time in Android?
Initialize an arraylist with false for how many items in your listView, then try the following
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(arrayList.get(position) == false){ //Make sure you initialize your arraylist with false values (same amount as listView size)
arrayList.set(position, true); //set true to an arrayList in the same index of the listView that was pressed
}else{
//Has been clicked before, do something
}
}
});
If you need to, you could include this info to the model wrapper, for example if you display list of Items, so you will have wrapper:
class ItemWrapper {
Item mItem;
boolean mIsClicked;
}
In this case when you click on your item you could get info about if this item was already clicked.
If you need for example list of Checkable items (list of checkboxes) it's the right way to do, because this item is a part of your logic, you could definitely answer if you item is checked.
This will help you.
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
int count = 0;
try {
count = map.get(your_listview_value);
} catch (Exception e) {
e.printStackTrace();
}
map.put(your_listview_value, (count + 1));
Toast.makeText(getBaseContext(),
String.valueOf(count), Toast.LENGTH_LONG).show();
}
To know about the basic functionality of list view , Check this
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;
}
});
I wish to manually rearrange the order of a ListView. The way I (want to) achieve this is by tapping on the item to be moved, setting the background of that item to a different colour, storing its position (oldPosition) and then tapping on the item which it is to appear below and finally resetting the background of the original item location.
The code I use to do this is:-
List<String> catarray; // string array declared in main activity
ArrayAdapter<String> catadapter; // adapter for Spinner declared in main activity
ListView cats; // listview declared in list activity
ArrayAdapter<String> adapter; // adapter for listview declared in list activity
int oldPosition = -1;
cats.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (oldPosition < 0) {
oldPosition = position;
try {
dr = parent.getChildAt(position).getBackground();
parent.getChildAt(position).setBackgroundColor(Color.argb(255, 0, 153, 204));
}
catch (Exception e) {
}
}
else {
String item = PhotoActivity.catarray.remove(oldPosition);
PhotoActivity.catarray.add(position,item);
try {
parent.getChildAt(oldPosition).setBackground(dr);
}
catch (Exception e) {
}
oldPosition = -1;
changed = true;
PhotoActivity.catadapter.notifyDataSetChanged();
adapter.notifyDataSetChanged();
}
}
});
The problem that I have is that if the list is larger than the displayed view then both the item that I tap on gets the background changed but so does an additional item that is below the visible range.
So, for example, if the full list is, say, 12 items long of which the first 8 are being displayed, if I tap on the second item then both that item but also item 11 (ie the second item plus one below the visible range) is highlighted.
Why does this happen?
How can I either stop it or, if I can't do that, reset the incorrectly highlighted item given that it is not visible and therefore not accessible via parent.getChildAt ...
The only answer I've found is to add a getView method for the adapter, call super.getView and then change the background colour there.
Also, you need to call view.setBackgroundColor in the OnItemClickListener event to make sure that the background is changed at the point of clicking.
So, my code ends up as being:-
cats.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (oldPosition < 0) {
oldPosition = position;
try {
view.setBackgroundColor(Color.argb(255, 0, 153, 204));
}
catch (Exception e) {
}
}
else {
String item = PhotoActivity.catarray.remove(oldPosition);
PhotoActivity.catarray.add(position,item);
oldPosition = -1;
changed = true;
PhotoActivity.catadapter.notifyDataSetChanged();
adapter.notifyDataSetChanged();
}
}
});
adapter = new ArrayAdapter<String>(c, android.R.layout.simple_list_item_1, PhotoActivity.catarray) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) super.getView(position, convertView, parent);
if (oldPosition> -1 && oldPosition==position) {
textView.setBackgroundColor(Color.argb(255, 0, 153, 204));
}
else {
textView.setBackgroundColor(Color.argb(0, 0, 0, 0));
}
return textView;
}
};
cats.setAdapter(adapter);
My thanks to Cameron Saul at SO answer here for pointing me in the right direction.