collapse all recycler view sections except one.. set image resource - android

I am trying to collapse all sections in recyclerview except one ( currently selected)..
I can collapse all items successfully.. but I want to reverse the arrow direction in headerholder.. I Using the library as https://github.com/luizgrp/SectionedRecyclerViewAdapter..
while reversing the arrow it is giving null pointer exception for headerholders out of window ( not visible in present screen)..
{
for (int i = 0; i < deviceInfoList.size(); i++) {
ExpandableDeviceSection section = (ExpandableDeviceSection) sectionAdapter.getSection(deviceInfoList.get(i).getdName());
if (section.expanded && !section.dName.equals(dName)) {
section.expanded = false;
HeaderViewHolder headerViewHolder1=(HeaderViewHolder)recyclerView.findViewHolderForAdapterPosition(sectionAdapter.getHeaderPositionInAdapter(section.dName));
//getting null for sectionHeader which is not available.
if(headerViewHolder1!=null)
headerViewHolder1.imgArrow.setImageResource(section.expanded ? R.drawable.ic_expand_less : R.drawable.ic_expand_more);
}
}
// sectionAdapter.notifyDataSetChanged();
}
here is my all collapse code in onclick listener.. I hope this clarifies.. let me know if anything else required..

Problem solved.. forgot to set image view (imagearrow) in onbindheaderview holder..
No need to set it in for loop now .

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);

how to add button when listview is updated?

I'm working on App which get the data from GCM , After this I display the data in the listview and when get new data from GCM , I add these new data to the listview and I used this code
public void updateListView2(List<FeedItem> newItems) {
for(FeedItem item : newItems)
{
//Toast.makeText(this, "Title : "+item.getTitle(), Toast.LENGTH_LONG).show();
// this to add the new items at the top of the list
listAdapter.insert(item, 0);
}
// to retain the position of the listview after updated
int lastViewIndex = listView.getFirstVisiblePosition();
View view = listView.getChildAt(0);
int top = (view == null) ? 0 : view.getTop() ;
listView.setSelectionFromTop(lastViewIndex, top);
listAdapter.notifyDataSetChanged();
//this to add the button programitcally like "New Stories"
Button updateBt = new Button(this);
updateBt.setText("Updated");
feedLayout.addView(updateBt);
}
but when I tried to add the button like this "New Stories" I failed , Nothing is viewed !! so can anyone Help Me .
I would play with visibility (VISIBLE && GONE). When you get info you don't have to add the button but make it visible and with visibility GONE after clicking it (or whatever the event you want).
This may make you easier to work with hierarchies of views because you define the button in your xml layout (with visibility gone by default, at the top or in the position you need it) and change its properties dinnamically.
The best way to do is add that button and place it wherever you want in your xml layout file and set
android:visibility="gone"
or
android:visibility="invisible"
when you need the button to display, display it from java code like this
myButton.setVisibility(View.VISIBLE);
follow this, you'll get no issues.

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.

Saving state of a dynamically added view through an adapter

I've been struggling with this problem for two days and haven't found anything helpful online.
My setup is like this, I've a Gridview which I am populating with images through API. Now each cell of GridView contains a button , when clicked is supposed to add an overlay to the cell. This is being done dynamically depending on the values through webservice. Now the problem is when I scroll up or down the overlay that was added shifts to other cells.How can I tackle this problem?
What I've tried:
I've tried the SparseBooleanArray solution which is used to save the state of the checkboxes through saving the position,but this approach will not solve the problem as I am struggling with keeping the state of the view intact.
What I suspect:
The code adds the overlay through a method which is called on click of the button. I am using the clicked position to get the cell through gridView.getChildat(position) and adding the overlay as a child to it. I think my convertView is not updating that's why the overlay keeps on drawing on different cell positions.
Relevant code:
This is inside my getView method,
if (convertView == null) {
convertView = inflater.inflate(R.layout.grid_image_row, null);
holder = new Holder();
holder.iv_product_image = (ImageView) convertView.findViewById(R.id.id_iv_product_image) ;
RelativeLayout.LayoutParams iv_product_image_params = new RelativeLayout.LayoutParams(imageWidth,imageHeight) ;
holder.iv_product_image.setLayoutParams(iv_product_image_params) ;
iv_product_image_params = null ;
holder.iv_loader_image = (ImageView) convertView.findViewById(R.id.id_iv_loader_image) ;
holder.bt_expand_save_overlay = (CheckBox) convertView.findViewById(R.id.id_bt_expand_save_overlay) ;
holder.tv_productname = (TextView) convertView.findViewById(R.id.id_tv_productname) ;
customFonts.SetSoureLightFont(holder.tv_productname) ;
holder.tv_sellingprice = (TextView) convertView.findViewById(R.id.id_tv_sellingprice) ;
customFonts.SetSoureLightFont(holder.tv_sellingprice) ;
holder.tv_price = (TextView) convertView.findViewById(R.id.id_tv_price) ;
customFonts.SetSoureRegularFont(holder.tv_price) ;
holder.parent_cell = null;
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
EDIT : This is how I am setting tags with the positions...
if (session.isLoggedIn()) {
holder.bt_expand_save_overlay.setTag("1,"+position) ;
int i=0;
for (i=0; i<savedItemsHashMap.size(); i++) {
HashMap<String,String> savedItems = new HashMap<String, String>() ;
savedItems = savedItemsHashMap.get(i) ;
if (savedItems.get(GlobalVariables.KEY_PRODUCT_ID).equals(mapStr.get(GlobalVariables.KEY_ID))) {
holder.bt_expand_save_overlay.setButtonDrawable(R.drawable.wishlist_saved_drawable) ;
break ;
}
}
if (i==savedItemsHashMap.size()) {
holder.bt_expand_save_overlay.setButtonDrawable(R.drawable.wishlist_unsaved_drawable) ;
}
} else {
holder.bt_expand_save_overlay.setTag("0,"+position) ;
}
This is how I am binding click listener inside getView,I am saving the position in the tags.
holder.bt_expand_save_overlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String getTagString = (String)v.getTag() ;
String [] items = getTagString.split(",");
selectedExpandButton = Integer.valueOf(items[1]) ;
ExpandSaveForLaterOverlay (selectedExpandButton) ;
}
The ExpandSaveForLaterOverlay adds the view to the selected cell but this does not remain on the same child when scrolled.
Thanks in advance for any help or tips!
Update: I checked the google play music application and they have the same setup. They have a gridview with a button which shows a menu overlay on click. But before scrolling the menu goes invisible, and only after that it scrolls. Is there no way to save the overlay in the view instance itself?
Try to use setTag() on imageview in adapter like
holder.imageView.setTag(position);
And getTag() when you are adding the overlay as a child like
holder.imageView.getTag();
then add overlay.
Ok finally my idea about android architecture was wrong. What I needed was to show the added layout as dropdown. And the added layout should be scrolled when the gridview is scrolled.Which is not possible in any way by available android sdk. I might have to make my own view for such implementations which will keep track of the virtual y and x position of the added overlay.

Custom adapter view not updating correctly

Ok, I have a custom AdapterView. Whenever I detect a long click, I call a method to change a custom editable status.
public void setEditing(boolean editing) {
this.editing = editing;
//Set editing to children
for (int i=0; i < getChildCount(); i++){
((PresentationPickerGalleryCellView)getChildAt(i)).setEditing(editing);
if (editing == true)
getChildAt(i).setVisibility(View.INVISIBLE);
//((PresentationPickerGalleryCellView)getChildAt(i)).deleteImageButton.setVisibility(View.VISIBLE);
}
}
It's executed in the main thread as far as I am concerned.
Now, if I call:
getChildAt(i).setVisibility(View.INVISIBLE);
It hides the whole view correctly when editing==true. But if I call:
((PresentationPickerGalleryCellView)getChildAt(i)).deleteImageButton.setVisibility(View.VISIBLE);
The deleteImageButton is a button inside the cell. It won't show the deleteImageButton at all. I tried invalidate, postInvalidate, layout, requestLayout, refreshDrawableState, but nothing...
Any ideas?
Ok...
It seems if I set View.GONE at the beginning, and then I try to set View.VISIBLE, it won't show the button...
I have to work only with View.INVISIBLE and View.VISIBLE :/

Categories

Resources