getView method setting the background of button - android

I am setting the background of my ImageButton in getView of adapter the problem I was facing was the background image wasn't properly set, i at first used this.
if(exist) {
bookmark.setBackgroundResource(R.drawable.ic_action_important);
}
but the button background always set the background image to important, then i used this and this solves my problem.
if(exist) {
bookmark.setBackgroundResource(R.drawable.ic_action_important);
} else {
bookmark.setBackgroundResource(R.drawable.ic_action_not_important);
}
I don't know the reason why i have to add the else because in the xml view i set the bookmark default image to ic_action_not_important, i was wondering that why we have to use else when the image ic_action_not_important is already in the adapter view, can anyone please explain. Thanks a lot in advance.

#Elduderino Answered your question in comments. The views get recycled.
Meaning the view currently holding position #10's data, might have been holding position #3's data before you scrolled, or opened and closed the view.
In the first example, you only set the background to "important" in your if-statement when the condition is true. Meaning if the background was set to important once, it will never be set to unimportant even after it gets recycled and is used to show data at a different position.
Hence your second example is correct.

Related

Recyclerview Setting BackGround of Item

I have a simple horizontal recyclerview. As the user scrolls, the current item looses focus has background set to transparent and the new focused item is to have its background color changed to green. I have a simple method that takes in the focused position, changes it's color and sets the reset of the items to transparent.
public void resetRecycleColor(int rowindex){
for(int i=0; i < mRecyclerView.getAdapter().getItemCount(); i++){
if(i== this.rowindex){
Log.v("SCROLLS ", "COLOR GREEN "+ i);
mRecyclerView.getLayoutManager().findViewByPosition(i).setBackgroundColor(Color.GREEN);
}else{
Log.v("SCROLLS ", "COLOR TRANSPARENT "+i );
mRecyclerView.getLayoutManager().findViewByPosition(i).setBackgroundResource(R.color.gridBackgroundBlack);
}
}
}
Am I attempting to change the item background correctly? Something is wrong because it crashes on the line where the color is set. Comment out those lines and scrolling works fine. Can somebody point out why the crash may occur?
Thanks
You don't seem to understand the ViewHolder pattern.
You only have enough views (plus about 2) to fill RecyclerView. For example if you have 2000 items but they are represented in list that shows 3 items each, you only have 5 ViewHolders created. That way when scrolling views that exit the screen, reenter from the other side but displayed values are changed (in OnBindViewHolder).
Crash is occurring in findViewByPosition(i) since you're trying to get views for entire list but you only have views for a few of them, so this returns null.
I don't understand your use case entirely, but if you're repeatedly calling your method during onScroll then it has really bad performance, cleaner solution would be modifying your adapters onBindViewHolder to properly modify focused view and calling notifyItemChanged() to trigger rebinds on new/old focused view.

Android list view adapter hiccup

So I have noticed something weird in Android List Adapters.
I have an adapter that is inflated with lets say template.xml, this template has a text view (TextView1 default: "hello"). In some cases TextView1 must have a value of "not now" and in other cases nothing (ie the default should be displayed). When the list contains all the default values everything is ok.
But as soon as in the GetView of a specific adapter I change it to "not now" it effects the others as well (not always if I close the activity and reopen it it may work).
What do you guys think?
Hard to say without your code, but this looks like a problem with reused views.
Make sure that you put back to default or to custom text every view in 'getView'. If you do not change it, it will leave the value that was previously set, which might not be the default one.
That behavior happens as intended.
The adapter recycles views through the use of convertView, which means that, for example, a view that you returned on position 10 can be reused on position 19.
For example:
If you set your position 10 to be "not now", and didn't change it back to the default value in your getView method in the position 19, it will keep the value you set for position 10.

Android - dynamically update GridView views

I've got a GridView with a custom Adapter, displaying thumbnails of pictures to the user. I can select and deselect pictures (I use setAlpha(0.25) on the views to notify the user of the change), and that's all well and fine.
Now what I want to do next, is have a button on top of the gridview that clears the whole selection, i.e. call setAlpha(1.0) on all views that were changed. So far I can reset my elements in the adapter, and I can setAlpha to 1, but the view doesn't update unless I scroll it out of the display, and then get back to it, or notify the adapter of changes, which redraws all my views, which does not look too pretty if only one element was selected.
I already dynamically set and reset individual elements through the GridView's onClickListener, but can't do this for more. I even tried calling performClick on all selected items through my button, but again it only displays the changes after the views have been out of the screen and are shown again.
Here's how I simulate the clicks:
for (int i = 0; i < mAdapter.getCount(); i++) {
PictureForSelection tempPic = (PictureForSelection) mAdapter.getItem(i);
if (tempPic.isPicSelected()) {
//tempPic.setIfSelected(false);
gridview.performItemClick(mAdapter.getView(i, null, null), i, i);
}
}
EDIT:
Conclusion - don't simulate clicks like this :)
So now I skip click simulation and use this:
gridview.getChildAt(i).setAlpha((float) 1.0);
In general it does exactly what I wanted it to do, except for one case:
If I have for example 3 pictures selected, one is off screen, one is partly shown, and one is fully shown, the ones shown (even partially) don't update their views.
If all the selected pictures are displayed it works flawlessly, but if some are out of the display, the rest do not update until the adapter's getView() gets called by Android. Still, thanks #mmlooloo for getting me so far.
If anyone knows a way around this, please do share :)
After setting your alpha you can call imageview.invalidate(); this causes your imageview to redraw itself.
if notifyDataSetChanged() is not working you can try like this.
i'm not sure whether this works,
1.onclick of the button you set the gridView.setAdapter(null);
2. Then set a new CustomAdapter object to gridview with default values.

ICS ListView background disabled when set onclicklistener

I'm working on an Android application with ListView/GridView.
Since I set an onClickListener on the convertView (The view I return in the getView() method of my Adapter), the cell's background doesn't shine anymore when pressed.
I know I can set my own drawable (with a specific pressed state) in my xml layout file (with value 'background') but I'd like to keep the original one (like when no onClickListener is set).
Can somebody tell me how I can keep the original background (with pressed state, ...)?
Thank you
PS: Sorry for my poor English, I'm French
If its an Adapter view, why don't you add OnItemClickListener ?.

Android ArrayAdapter tell all other views to refresh themselves

I need all of the other views in my arrayadapter to check their attributes and return to a default attribute at certain times
use case: listview items (a)(b)(c)(d) , when you touch (a) it's background turns black. This is done in the ontouchListener. But when you touch view (b) it's background turns black BUT (a)'s needs to turn back to the default which is not black
I dabbled around with recalling the arrayadapter at the end of the view.OnClickListener but the problem with this is that it also resets the scroll position of the view, so if this list was much longer - which it is - and user touched item (r) , then it would reset the list and put the user back at item (a) at the top
I was looking at notifydatasetchangedbut I am not sure how to use that and where it should work
insight appreciated
notifyDataSetChanged will do the job. You can call that at any time in your code and this will trigger the adapter to call getView for the visible list items again and so update their content. So basically the only thing you have to do is to update the list item states or information before calling that method.

Categories

Resources