Why are these recyclerview items not filling their views? - android

I have a horizontal RecyclerView inside a NestedScrollView inside a SwipeRefreshLayout. Presumably this is a cause for error. When I load the data the children display fine but once I scroll to an end and rescroll the children aren't filling their views.
In action
I've found a bunch of different advice on how to fix this with layout constraints, different parent view types, and changing focus but the problem still occurs. onBindViewHolder is definitely getting called but for some reason the binding doesn't happen?

This strange happened because of recycling process for the recycler view, all layout code written at the bind view (in the View holder) will ignored on recycling, and to solve it, add this code:
RecyclerView.setRecyclerListener(new RecyclerView.RecyclerListener() {
#Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
((BusinessChildViewHolder) holder).onBind();
// onBind method inside your holder and it just applies the layout changes that you need
}
});

Found the issue: In my viewholder I set certain layouts as invisible and since the views are recycled they weren't showing. All I had to do was set them to visible.
From this solution https://stackoverflow.com/a/29325270/6136947

Related

Recycler view in a recycler view

I am looking for solution that solves a problem of a dynamic list that in turn contains a dynamic list of rows.
I have a recycler view which holds a card view that eventually holds another recyclerview. I can see that the parent recycler view is showing up but the child recycler is not showing up.
{{recyclerView{cardView{recyclerView}}}
The getItemCount method is being called but all the other methods such as onCreateViewHolder and bind are not being called.
I have made sure both the recycler views have the linearlayoutmanager implemented and have setFixedSize as true.
I believe it is the issue with your xml layout. Maybe it is not coming in focus hence it is not calling those overridden methods,as recylerview becomes unavailable.Make sure that the padding,height and rest other things are such that the child recyclerview is visible.Actually when I implemented it, I faced the same issue and the reason was my xml layout with the same reason as my second recyler was not visible due to overpadding and margin.
Found the problem. Had to upgrade to a newer version of recycler view. And added wrap content. It started working.

Android: Lock/Freeze layout for the time changes are made programmatically?

I do reorganization of my layout programmatically adding and removing several views. The problem is after the first removeView the activity/fragment starts to measure/layout the remaining views. Is it possible to put this on hold until I have done all the changes?
Inspired by the post from Arkde I finally found a solution for my problem. I simply override requestLayout() and prevent the call to be propagated to the parent ViewGroup on demand. This enable me to stop the layout process from interfering as long as I reorganize my views.
1st idea
Removes a range of views during layout.The removeView() method looks like this in ViewGroup
public void removeView(View view) {
removeViewInternal(view);
requestLayout();
invalidate(true);
}
The calls to requestLayout() and invalidate() cause your group to trigger measure/layout methods.
In order to avoid this mechanism, you should extend your ViewGroup and override this method, or create a new one to remove chunks of views,and after that trigger requestLayout() and invalidate()
or, if you want to remove all the views starting at a certain position, to another position in layout use,
public void removeViews(int start, int count) {
removeViewsInternal(start, count);
requestLayout();
invalidate(true);
}
that removes a range of views during layout.
2nd idea
If you want your layout to be dynamic and you want to grammatically add or remove parts of the screen, I think you should use Fragments instead.
3rd idea
When you need to change your layout, just create another ViewGroup programatically (or by inflating from xml different layouts), and add all the childs you need there. After that remove all views from current view using ViewGroup.removeAllViews()and add the newly created ViewGroup.

Scrollbar for every view (View class)?

I was just reading few stackoverflow threads about scrolling views larger than parents. Everywhere is used ScrollView or HorizontalScrollView for this, but what is puzzling me is why does every single view have methods and xml attributes for setting scrolling? For example, Im currently overriding method onScrollChanged() of View class. I mean can every view have a scrollbar?
Because View is a class/Object.
To give you a more to the point example here you go:
public class Test extends View {
}
Therefor, it's pretty much obvious for View to have methods for each instance of the object.Right?

How can I tell when a Layout (and all its child Views) has fully finished inflating?

I have a situation where I have a custom Layout which contains a bunch of children and which I inflate into a ViewFlipper.
My problem is that the ViewFlipper badly stutters its animation as it tries to animate the Layout in, even as the Layout is still loading all its child Views.
I tried using onLayout, but that gets called the moment the parent Layout is done inflating (it doesn't wait for the child views to inflate, so the stutter persists)
I also tried onMeasure, but that's called dozens of times and keeps getting called every time anything in the Layout changes (such as the EditText getting focus, or changing value).
So, I'm stumped... does *ANYTHING happen, that I can listen for, when the Layout is fully inflated, so that I can THEN tell the Flipper to perform the animation?
You can override onFinishInflate() in your custom layout. This is called as the last phase of inflation, after all child views have been added.
You could use an OnPreDrawListener. This will be called immediately before the View is going to draw its first frame, at which point all of the children will be laid out.
CustomView myCustomView = (CustomView) findViewById(R.id.my_custom_view);
final ViewTreeObserver obs = myCustomView.getViewTreeObserver();
obs.addOnPreDrawListener(new OnPreDrawListener () {
#Override
public boolean onPreDraw () {
//We only care the first time it happens, so remove it
obs.removeOnPreDrawListener(this);
//Post your animation here, then return true
return true;
}
});

TabHost inside a ScrollView forces it it to scroll to the bottom

My question is very similar to this unanswered one, with some small differences that I will explain:
TabHost inside of a Scrollview: always scrolls down when a Tab is clicked
My ScrollView initiates scrolled to the bottom, showing the TabHost content instead of the ones on top of it (you can see the screenshots in the linked question, it's very similar).
If I manually scroll up, clicking in different tabs doesn't affect the ScrollView, the problem is only in the first time it's shown. This is the difference between the other question.
Things I tried with no success:
Make the top components inside the ScrollView focusable, so they would get the focus instead of the tab.
Force the ScrollView to scroll to the top in onResume() method with sv.fullScroll(View.FOCUS_UP); or sv.scrollTo(0, 0);. Also, no luck in the initialization, but subsequent calls to onResume() effectively scrolls it to the top.
Any ideas on why this is happening? Tips on how to further investigate are also very welcome.
Probably too late to help you Pedro, but I did figure out a solution that worked for me. I noticed in the TabHost source that it requests Focus if nothing else in the view has focus. So I made sure that the first component in the Scroll view was focusable and requested focus for it.
// Get the first component and make sure it is focusable. Note you have to use setFocusableInTouchMode and not setFocusable for this to work.
TextView v = (TextView) view.findViewById(R.id.first_component_in_view);
v.setFocusableInTouchMode(true);
v.requestFocus();
Hopefully this will help someone.
I have a similar problem and haven't solved it. However, to force the scroll view to scroll you need to update it's progress through a separate thread to post on the UI. e.g.
quickScroll.post(new Runnable() {
#Override
public void run() {
quickScroll.scrollTo(0, 54);
}
});
Where quickScroll is my ScrollView. I believe the reason for this is that you have diagrammatically defined your layout, or inflated it from a custom viewgroup. So setContentView doesn't hold a reference to the scrollView, so you have to force the UI to update off the variable allocated to the ScrollView.

Categories

Resources