How to handle row background in Android BaseAdapter? - android

I am changing row background color if the fetching data from database size is more than zero as gray otherwise not changing anything.For first item i am setting default folder and remaining as list names for these lists also setting background same like above.When I scroll the list all the bacground positions are changed..I know that positions are changing while scrolling.How to solve this one?
First position should be always Default List. I am giving code snippet for understanding purpose
if(position == 0)
{
holder.listName.setText("Default List");
int c = //getting database table size
if(c == 0 )
{
holder.rowLayout.setBackgroundColor(Color.GRAY);
}
}
else
{
list =//getting lists from database(different table)
if(list!=null)
{
holder.listName.setText(list.getListName());
}
if(list size==0)
{
holder.rowLayout.setBackgroundColor(Color.GRAY);
}
}

The ListItem recycled when you scroll the List that is why you are getting random background for ListItem. You have to change background of ListItem to it default color.
as follows..
if(list size==0)
holder.rowLayout.setBackgroundColor(Color.GRAY);
else
holder.rowLayout.setBackgroundColor(Color.BLACK);

Related

On scroll recyclerview item Background color changed when recylcerview scroll

I want to change Recyclerview item background color on my condition but when I scroll background color automatically changed I know holder.setIsRecyclable(false); but I don't want to set holder.setIsRecyclable(false);
and I know
if(item.value == 1){
// do something
} else{
// do something
}
but i want to do using nested if else
if (feetInt > 0 && feetInt < 4) {
((PatientViewHolder) holder).rlClientItemMain.setBackgroundColor(ContextCompat.getColor(mContext, R.color.player_list_green));
} else if (feetInt >= 4 && feetInt < 6) {
((PatientViewHolder) holder).rlClientItemMain.setBackgroundColor(ContextCompat.getColor(mContext, R.color.player_list_yellow));
} else if (feetInt == 0 || feetInt >= 6) {
((PatientViewHolder) holder).rlClientItemMain.setBackgroundColor(ContextCompat.getColor(mContext, R.color.player_list_red));
}else{
((PatientViewHolder) holder).rlClientItemMain.setBackgroundColor(ContextCompat.getColor(mContext, R.color.player_list_grey));
}
Instead of changing color on feetInt maintain a flag in your object class and on the basis of particular flag change your background color
It looks like you are not updating the value of feetInt for every single object in list. That's why you are facing this issue.
Update feet int value in list for different different position, you will get the desire result.
Also, remove getItemViewCount() and setIsRecyclable(). These are not required at all. Also, share your code for more specific answers.
holder.setIsRecyclable(false);

Change color of end of record in ListView

Is it possible to change the color of end of scroll in a listView.. When I scroll to the end of listview or beginning of listView I get white color in the top and bottom of end of scroll. Can I change that color?
Thanks!
you can do this in your adapter getview function the getview function will called everytime a new listview item is show on screen. put below if else statement in your getview function
if(position == 0 || position == getCount()){
// change to the color you want to change
} else {
// change back to the normal color
}
To chang color of last item,
if (position == list.length - 1) {
holder.title.setTextColor(Color.RED);
}else{
holder.title.setTextColor(Color.BLACK);
}

RecyclerView keeps repeating cached (?) subview and not looking to onBindViewHolder

I have RecyclerView where every list item has an ImageButton, thee image of which I define in the adapter's onBindViewHolder():
int myVote = getMyVote();
if (myVote != 0) {
Log.d("dbg", myVote + "");
holder.ratingButton.setImageResource(R.drawable.ic_star_grey600_36dp);
}
So ratingButton is a star in the right bottom corner of the list item layout. Its shape is filled with gray color (and accordingly, a log record is pushed) if the condition (myVote != 0) is satisfied.
The problem is that when I scroll the list down I can watch other stars became filled even though I can see the only one record in the log window (for the correct list item). Moreover, this list items with incorrectly changed buttons repeat every 5 rows, and that's what's confusing me. If I changemListView.setItemViewCacheSize(0); the repeat period changes to 3, so we can assume it somehow connected with the RecyclerView's caching and recycling mechanism.
Please, help me to work the problem out. Thanks!
Don't forget to implement
public long getItemId(int position) {}
otherwise, you'll see repeated items in RecyclerView.
Try to change your code to:
if (myVote != 0) {
Log.d("dbg", myVote + "");
holder.ratingButton.setImageResource(R.drawable.ic_star_grey600_36dp);
} else {
holder.ratingButton.setImageResource(int another resource);
}
}
You may also have to write else part of main condition with some another resource like:
if (myVote != 0) {
Log.d("dbg", myVote + "");
holder.ratingButton.setImageResource(R.drawable.ic_star_grey600_36dp);
} else {
holder.ratingButton.setImageResource(int another_resource);
}
It is worked for me.

ListView Images change back to original settings when scrolled out of view - Android

I have a ListView that contains multiple ListView items. The ListView items Layout contains an ImageView. I use this ImageView as a button. When the button is clicked it changes the ImageView from a gray image to a green image. But when I scroll the ImageView out of visible view and then back to it, it returns to its original color. When the ImageView is created it can be either green or gray, it depends on a JSON array. So if an image is green and clicked it turns to gray. Then when its out of visible view and returned to visible view it is green again! How can I make the images maintain their new state?
Here is my code,
if(p.getJSON().equals("NO")){
imageView.setBackgroundResource(R.drawable.gray);
imageView.setTag(0);
}//end if equals NO
if(p.getJSON().equals("YES")){
imageView.setClickable(false);
imageView.setBackgroundResource(R.drawable.green);
imageView.setTag(1);
}//end if equals yes
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View imageView) {
final int status = (Integer) imageView.getTag();
if (status == 0){
imageView.setBackgroundResource(R.drawable.green);
imageView.setTag(1);
}
else{
imageView.setBackgroundResource(R.drawable.gray);
imageView.setTag(0);
}
}//end on click
});
You need to persist the state for the items that you have modified with the button press and then restore that state when your adapter's getView() is called for that item.
There are many ways you can do this: in memory, database, etc. You'll have to pick the method that works best for your purposes.
i.e. - item 3 gets clicked and the image changes from grey to green, store something to represent the state of the image (grey vs. green, a boolean would be great for this exact case) and then persist that data somewhere. Then when getView() gets called again for item 3 (it's about to be displayed again) you set the color of the image based on the data you persisted for item 3.
You could just modify the value in the original JSONArray that backs the ListView, btw.
The reason for this behaviour is because you do not persist the state of the items (if they were clicked or not). Each time the list is scrolled, the getView() is called and it executes the following code and the state is reset:
if(p.getJSON().equals("NO") ){
imageView.setBackgroundResource(R.drawable.gray);
imageView.setTag(0);
}//end if equals NO
if(p.getJSON().equals("YES")){
imageView.setClickable(false);
imageView.setBackgroundResource(R.drawable.green);
imageView.setTag(1);
}//end if equals yes
What is needed is a way to keep track of the state of each item based on its position. So you could confidently tell: item at position k is "YES" or "NO"!
You need to keep track of the items which have been clicked so that when getView() is called, you can update the state of the based on its current value (not based on JSON value).
1) Maintain a map of items positions which are checked, and corresponding state value ("YES" or "NO").
2) If item is clicked, add its (position, new state) to the map. If it is clicked again, update its state inside the map.
3) Use this map and set the state of the item in the getView(), something like:
Private field:
HashMap<Integer, String> map = new HashMap<Integer, String>();
In your getView():
String state = p.getJSON();
if(map.containsKey(position)) {
state = map.get(position);
}
if(state.equals("NO") ){
imageView.setBackgroundResource(R.drawable.gray);
imageView.setTag(0);
}//end if equals NO
if(state.equals("YES")){
imageView.setClickable(false);
imageView.setBackgroundResource(R.drawable.green);
imageView.setTag(1);
}//end if equals yes
final int pos = position;
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View imageView) {
final int status = (Integer) imageView.getTag();
if (status == 0){
imageView.setBackgroundResource(R.drawable.green);
imageView.setTag(1);
map.put(pos, "YES")
}
else {
imageView.setBackgroundResource(R.drawable.gray);
imageView.setTag(0);
map.put(pos, "NO")
}
}//end on click
});
Note: this is just one of the many ways of getting what you want, however the basic idea should be the same..

Android: Help required in card matching game?

I have 20 cards of which there are 10 pair of images. The player is meant to find a match of each card/image.
The problem is that if a player taps or clicks each card twice then that card gets decremented from the remaining ones . I need to disable the click listener of the ImageView. How can do that?
ivOne = (ImageView)findViewById(R.id.ivOne);
ivOne.setId(a[0]);
//final ImageView ivOne = (ImageView)findViewById(R.id.ivOne);
//ivOne.setEnabled(false);
ivOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
ivOne.setBackgroundResource(images[a[0]]);
Log.e("r[0]:", Integer.toString(a[0]));
if (firstTap)
{
firstId = v.getId();
firstTap = false;
}
else
{
//ivOne.setEnabled(false);
int secondId = v.getId();
Log.e("secondId", Integer.toString(secondId));
if ((secondId == firstId) && (score != 0))
{
//ivOne.setEnabled(false);
if (ivOneScored == false)
{
score--;
ivOneScored = true;
}
}
firstTap = true;
}
tvScore.setText("Remaining:" + Integer.toString(score));
}
});
I have a memory matching game on the market that works very similar. What I did was make a class that represents the card (with image and id properties) and assign an id (0-9) to the cards and the image as I loaded them into a temporary arraylist of just the 10 image objects.
public class GameTile {
public int id;
public Drawable image;
}
Then I iterated over the list twice and added the cards to the main arraylist that I use for my adapter... after which I used Collections.shuffle to shuffle the cards... Now... on to the selection. AS you know, in a memory game, you only want 2 cards flipped at any time. I am using a gridview to hold my cards... so what I did was use the OnItemClickListener from the gridview and not the imageview. Secondly, when a card is clicked, I add the position to another arraylist called "selected" that never contains more than 2 items... the position of the items we are attempting to match... In the OnItemClickListener, when the event is fired, I check to see if the item already exists in "selected" and return if it does... in effect ignoring the click.
if (selected.contains(position)) {
return;
}
When "selected" contains 2 items, I ignore all clicks until the handler finishes checking for a match.
if (selected.size() > 1) {
return;
}
So when a user has selected 2 items, I set a handler to call a runnable that checks for a match. If a match is made (by comparing the id fields I set when I first loaded the images), I add the two positions to another arraylist that contains only matched items and that handler also clears "selected" and, if there were matches, I change the images to blanks. When all 20 cards have been matched I fire a win which does all of the win stuff and resets the gameboard.
You have to make sure that those cards have the same symbol, but are not the same card.
So your line
if ((secondId == firstId) && (score != 0))
must rather look like something in the lines of
if ((firstCard != secondCard) && (secondId == firstId) && (score != 0))
where firstCard and secondCard identify the card on the table (not the symbol on the card)
If I understand you right, you just need to say view.setOnClickListener(null) if those two match? If you want to disable both of them, you just store a map to link an ID to a View, and then clear the click listener for both "view" and whichever view belongs to the second ID.

Categories

Resources