RecyclerView parameters stick around after re-drawing the list - android

So, I've got a RecyclerView with some textviews on the cards. One of these can turn red&bold, based on some parameters, using holder.DeviceTV.setTextColor(Color.RED); & holder.DeviceTV.setTypeface(null, Typeface.BOLD); This works perfectly fine, as you can see in the image below, above the black bar.
Later, I remove all the cards with the red&bold textview, and notify the adapter. This results in what you see below the black bar in the image, which should NOT be the case. I'm guessing this is because (duh) this is a RecyclerView, so the parameters I set on it before, have stayed around. I don't know why it chooses to use the cards with the red&bold text, but it does, every time.
What is the best way to fix this issue?

You would need to call holder.DeviceTV.setTextColor(Color.BLACK) and holder.DeviceTV.setTypeface(null); in the onBindViewHolder method to make sure everything is displayed as you want.
There might be a small overhead to that but it's definitely much faster than creating a new View from scratch.

Related

How to handle dynamic view created in Recycler View

Actually, I am working on RecyclerView that shows some details along with images and all data comes from a database.
In my RecyclerView, I have used three diffs layout and each layout is used according to data coming from the database that means if only one image comes from database then one_image.xml layout comes to play, if two then two_imag.xml layout comes to play and if more than three then the third layout I am using.
My apps working fine for some extents but when i am trying to scroll down further, it get crashed. I come to know that the problem is on OnCreateViewHolder, meaning it doesn't get called when I go down further in Recycler View.
I searched alots on google but nothing work for me. Is it possible to call OnCreateViewHolder every time or some other way to solve this problem?
Thanks in advance
Sounds like the best option would be to use one layout file that has all three image views but just default them to visibility "gone" so they dont take up space. Then when you need to use them, set them to visibility "visible" when you are creating your viewholder.
Without seeing any actual code it hard to be more specific.

Avoiding lag in displaying complex views with ScrollView

For the development of my app, I realized I needed a complicated view (let's call it foo), it contains three ImageButtons, a progress bar, and three TextViews, all of which are dynamically changed by interacting with the same view's elements. To make this work, I extended foo from RelativeLayout, dynamically created the sub-views then added them to foo (this.addView(...)).
What I planned to do next was add them dynamically to a ScrollView. I did this and put three foos for testing. The result was extreme lag. I'd press an ImageView (which should change its image on press), and it would take 2 seconds to do so.
My final aim would be to support 50 of these foos at a time and have them work smoothly, with the user having the option of loading more (without overwriting the previous ones) if he/she so chooses. All interactions will use the internet (I dunno if that's relevant), but the testing was done with all the network tasks commented out.
My questions are thus:
Is the strategy I was using (ScrollView & add foos to them) viable, and the lag is from some other issue (the specific code in question, in which case I'll provide some code)? Or is it really a bad idea to do that?
What would be the best way to reach my goal here (assuming 1 is bad)?
What I already know:
I've researched my problem a bit, and most online sources recommend using a ListView. I didn't read much into it but from what I got:
I'd have to redo the design using xml rather than dynamically
The different components and their values will be stored each on it's own array which is extremely unacceptable in my situation (changing the sub-view's values should be done very simply and should not appear in the main activity)
I can't (or it's difficult to) set OnClickListener's for the different sub-views (as only the main foo view will get one)
I also tried this method (ScrollView and add to Views) with another View and had 20 of them run at the same time seamlessly, but that one had been extended from View and only used canvas to draw text with no sub-views.
Thanks in advance.

Building an infinitely scrollable calendar-like view in Android

This is not a code problem, I interpret the guidelines as that being OK.
I've been researching a way of building an infinitely scrolling calendar-like view in Android, but I've reached an impasse.
Right now my dilemma is that most of the similar views available have their children placed relative each other in a recurring style. With this I mean:
item 4 comes after item 3, which comes after item 2, and there is constant padding/margin between all items.
What I need is a way to produce an infinitely long scrollable view that may, or may not, contain items. The items should be placed at variable positions within the view. The best way I can describe a similar looking view is a one-day calendar-like view that is infinitely scrollable.
So far my best two bets are using the new RecyclerView with a custom LayoutManager (this seems very complex and still not perfectly documented by Google though). I like this approach because, among other things, it is optimized for displaying large sets in a limited view.
My other solution would be to build a completely custom View. However, with that solution I loose the adapter unless I build a container view (which is probably more complex than building a layout manager).
How would you go about solving such a problem? Tips are appreciated, I don't need code examples, just ideas which path is the best to solve this problem.
Thanks.
Apologies if I've misunderstood the guidelines
Edit: How I resolved this problem
My first solution to use RecyclerView with a special Decorator seemed promising, but it remained a "hack" so we decided not to go for that solution since we were afraid of the complications that it would create down the line.
To solve the problem I went with a SurfaceView instead of an Adapter, this means having to rewrite all the adapter-functionality for my SurfaceView but it seemed to be the best way of solving this issue of very custom drawing and layout managing for my use-case.
It still would be nice to build a custom Viewgroup that can handle this kind of layout problems.
ListView and ListAdapter are based on a fixed list, so the current infinite-scrollers just keep adding more and more data to the end of the list.
But what you want is scroller similar to Google's Calendar app which has a bi-directional infinite scroller. The problem with using ListView and ListAdapter in this case is that if you add data to the front of the list, the index of any one item changes so that the list jumps.
If you really start thinking about this from the MVC perspective, you realize that ListAdapter does not provide a model that fits this need.
Instead of having absolute indexing (i.e. 1, 2, 3, 4, etc), what you really want is relative indexing, so instead of saying "Give me the item at index 42" you want to say "here's an item, give me the five items before it". Or you have something like a calendar date which is absolute; yet — unlike your device's memory — it has effectively no beginning or end, so what you really want here is a "window" into a section of that data.
A better data model for this would be a kind of double-ended queue that is partly a LRU cache. You place a limit on the number of items in the structure. Then as prior items are loaded (user is scrolling up) the items at back end are pushed off, and when subsequent items are added (user is scrolling down), items at the front are pushed off.
Also, you would have a threshold where if you got within a few items of of one edge of the structure, a "loadNext" or "loadPrevious" event would fire and invoke a callback that you set up to push more data onto the edge of the structure.
So once you've figured out that your model is completely different, you realize that even RecyclerView isn't going to help you here because it's tied to the absolute indexing model. You need some sort of custom ViewGroup subclass that recycles item views like a ListView, but can adapt to the double-ended queue. And when you search code repos for something like this, there's nothing out there.
Sounds like fun. I'll post a link when I get a project started. (Sadly, it won't be done in any timely manner to help you right now, sorry.)
Something that might help you a little sooner: look at Google's Calendar implementation and see how they did it: Google Calendar Git repo
What you may be searching for is a FragmentStatePagerAdapter , where you can implement a swiped view, meaning when the user (for example)swipes to the right, a completely new view is displayed.
Using a FragmentStatePagerAdapter , you can handle a huge amount of views without overflowing the memory, because this specific PagerAdapter only keeps the views' states and is explicitly meant to handle large sets of views.
Keeping your example of a calendar, you can implement swiped navigation between for example weeks and generate the week views on demand while only keeping for example the year and the week's number as identifiers.
There are plenty of online tutorials for Android, maybe you have a look at this one

Create a ListView like view in a ScrollView Android

So I did some research and testing of using a listview in a scrollview, and as a lot of people may know this is supposedly bad to do, since they both scroll. It also means I can't show the complete listview as it will wrap to be smaller.
I have seen places which re change the height of the listview to fix this problem but again most people say that it isn't preferred.
What I would like to know though is what is the preferred way of making a nonscrollable listview like view? Basically I want the exact same as the listview but obviously non scrolled and the height based on its contents. I would prefer to work with the layout in as much XML as possible, and I would like to be able to send my array list to it to view on screen. Unfortunately either my search skills are quite dull, as I haven't been able to find anywhere that really explains the preferred method so I thought I would ask here.
Thanks for your help.
<>Clarification Information
I thought I would put this here in case it will help, first off I basically want to show an image, with a list of comments (each one has an author and a text) below it, the comments themselves are obtained from an array and can change. I want the whole page to be scrollable though so I can either view more comments or go back up to the image.
Using a RecyclerView and an adapter supporting multiple item types you could make a list which shows an image on top and several comments below it. Generally you'd have to check what item corresponds to each position - in your case on position 0 you have an image and in every other position you'd have a comment. Then in your adapter's onCreateViewHolder and onBindViewHolder you would check the item type and handle them differently.
You could take a look at this answer for a short example.
Let me know if you'd need any other details and/ or sample codes to get the idea. :)

best practice for updating an adapter

I have an adapter that displays a grid of thumbnails with a text. These thumbnails are heavy to load, heavy to draw, etc.
The thumbnail gridview is constantly filled with new content, let's say, 1 new item every 2 seconds.
My adapter has a function that I call from outside to inject new items:
public void postNew(Item i) {
arrayStuff.put(i);
notifyDataSetChanged();
}
What happens is, with my current approach, when I insert a new element in the gridview, it refreshes everything, even if the added item is not going to be visible. The refresh process kind of breaks the experience, specially if the user is browsing the gridview and new content arrives.
How would you recommend improving this? is there a lighter 'notifyDataSetChanged()' or something like that?
I do not know of any lighter version of notify data set, but you can always use ListView.getFirstVisiblePosition and ListView.getLastVisiblePosition to determine whether your latest added position is visible, and only call notifyDataSetChanged if it is.
As for "heavy" bitmaps, as heavy as it is I think you should resample or scale it to the minimum size you need, using LruCache you can reduce the need of re-drawing on notify data set changed.
It sounds like you probably need to implement some form of caching, it's not very good memory management to have images which are not visible loaded into memory, ideally you would retrieve them from cache when they become (or are about to become) visible.
An alternative approach could be to add some form of visual indicator when new content arrives and then implement "pull down to refresh" or similar, then make a call to notifyDataSetChanged() on your adapter to refresh the content. I can imagine that refreshing every couple of seconds would not give a great UX because it would be hard to follow if the screen content is constantly changing.
You need create custom view(dynamic at runtime) that adds multiple imageview and appropriate textview, the container view should be LinearLayout, after that you can able to update a particular view or element.

Categories

Resources