I have Scrollview is being filled pragmatically, with large number of textview with background Bitmap loaded from Assets folder. they are being filled as rows. each row has different number of columns, when i have large number of these textviews it scrolling stops to be smooth, i cant use adapter because i have multiple cases and each textview should have a seperate actions, how to make this scrolling more smooth?
I used Overidden text view and overided the :
#Override
public void requestLayout() {
/*
* Do nothing here
*/
}
but in the 1st load it still so slow, any ideas?
You can add the android:hardwareAccelerated="false" for a specific activity. http://developer.android.com/guide/topics/graphics/hardware-accel.html
I'd still go with the adapter and ListView design as you can inflate different layouts for each row just as you're doing already. The only difference is that the ListView will handle destroying and creating these views as they are required.
There's no need to make use of the convertView in the getView() method of the adapter if you will have many different types of view. But it should still scroll much smoother.
Related
I was wondering if I want to create a simple list of buttons, a recycler view will be needed or if I can make do with a listview. Thank you
The simplest method would be to create the buttons and add them the view. I strongly recommend you to not do it the following example is for demonstratiom purpose:
onCreate...
LinearLayout root = findViewBy...
for (item: dataList) {
Button btn = newn Button(this);
btn.setText(item.text);
root.addView(btn);
}
In this example Im using a linear with vertical orientation, that should be inside a scrollview.
That is bad because every view is in memory at the same time. If you have just 2 or 3 buttons then there is no problem but if the number raise to hundreds then there will be memory usage problems.
This is why ListView got deprecated, because every row was rendered. Large data set made the UI slow. Instead RecyclerView literally recyle the views as the name implies. In memory there is only the view on the screen and a bit extra, so when a view leaves the window is available to be reused by the incoming row.
By the comments I can see you are also confused with views and viewgroups. A TextView is a View it can not have another View inside. If you only need to have a click, then TextViews can use a setOnClickListener, other is the case if you need the appearance of a button. Anyway, when you create an adapter you can add any layout you want.
A list of buttons can be achieved in both the ways. But ListView is outdated. So better use RecyclerView
I'm having a issue where my ListView is displaying only one row even though ArrayList containing data has 2 items in it.
For clarification, YES, I'm using ListView inside a ScrollView but to balance it out I'm using custom ExpandableHeightListView (retrieved from one of the answers on SO) which is useful for exactly this purpose. This ListView is not scrollable. It has fixed height.
Also, within the same ScrollView, couple of other ListView are working fine but this one ListView is not working properly.
Going further, when I logged the position variable value inside getView() method, it's always 0 for this ListView while for other ListView, it's increasing sequentially.
I've compared both Adapter's code and they are identical but still current ListView is not working.
I tried with overriding getView() method, but to no avail.
Any help appreciated.
EDIT
If I give fixed height to ListView like 250dp, both the rows are getting displayed but it shows only 1 row with height set to wrap_content
As I know that ListView within a scrollView does not worked properly.
Because both widget has scroll so they does not worked well.
So I recommend to delete the ScrollView
Thanks..
I know this is not what you want to hear, but seriously, whatever you are programming, consider displaying it on tabs or similar, such that you don't need the scrollview.
If you really must have so much data on one screen, consider using something like a LinearLayout with an adapter to display your data.
Listviews are not designed to work inside a scrollview because they are scrollable themselves. You can "hack" your way around it, but it's not nice. If you really need the features that listviews provide, consider splitting up your screens into tabs, displaying a listview or two in each tab.
This solution worked for me and also adjusts the layout automatically. On the top-level ListView adapter, inside the getView() method, you will create a view that references a layout with another ListView. Assuming that "inner" ListView is declared as "listView" with its adapter called "adapter", try using the code below. Also, ensure that the inner ListView layout is set to WRAP_CONTENT, so that even if the height is correct, it is not being overridden by the layout constraints.
listView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
listView.getLayoutParams().height = adapter.getCount() * {whatever your list item height is} OR do something else to add up all of the heights;
listView.requestLayout();
listView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
);
Regarding the lisview recycle, I'm reusing the views with viewholder, but now I need to add a number of Views(ImageViews and textviews) not clearcut( the number of views isnt always the same).
How can I add these items, without create a new view on every getView() method and without affecting the performance of the list?
No way to create different layouts without overriding getView(). You can reuse as much view types as you want, read this answer.
If you have perfomance issue, try a new widjet RecyclerView, available at Support-V7 library.
my strategy to implement what you described without creating new view every time getView() is called, is:
let's say you have at the most 10 image views. your view xml will contain 10 ImageView items,
but when getView() been called - you'll set the visibility of the un-needed elements to View.GONE, and the only ones you needed to View.Visible.
working great for me, and that's the only why not to create new view...
I have a listview with custom rows and that extends SimpleAdapter.
Each row consist of two linear layouts : 1st having two textviews of which one is hidden in horizontal orientation, second having two textviews in horizontal orientation.
Now depending on the value in hidden textview , I want to setcolor for the remaining items for the row.
To put it as simple:
each listview item has some custom colors the value of which comes from the hidden field.
I have done this by overriding getview() for the simpleadapter and returning view for each, but this makes list very slow to render (and that I think is obvious as so much of work for each view before showing it).
Can I do this in some more efficient way ? like making views and then add up to list instead of using xml layout maybe one solution OR any other ? Any help ? Thanks.
If you use convertView in your adapter, I would not expect you to have any particular speed issues. Creating and garbage collecting rows is expensive -- setting some colors on a set of TextViews is not. So, make sure you are using the convertView parameter to recycle your rows.
Here is a free excerpt from one of my books that covers row recycling.
I have a RelativeLayout with different elements. I was planning to have two ListViews on it, but I have noticed there are some problems with scrolling. Since each ListView only shows a maximum of 5 rows should I try to make some kind of custom adapter to merge those ListViews? Or is it better to replace the ListView with a LinearLayout/RelativeLayout and add the rows as I get them manually? (like the first answer in here: android listview display all available items without scroll with static header ).
Which should be the proper way on doing this? or is there another way? Also, each row will have an OnClickListener.
There's two solutions if you'd like to keep your list... list-y, without having to prerender all the row Views like the above solution suggests (which can be slow to render, eats RAM and doesn't scale nicely to more than a screen or two of Views, but is a fine quick solution for smaller lists, though I'd just use a bunch of Views in a LinearLayout in a ScrollView rather than a ListView in that case).
Write a custom ListAdapter, overriding getItemViewType, getViewTypeCount and GetView to inflate the proper kind of view and recycle appropriately for your two types of views. You'll also either need to override getItem to contain custom logic for figuring out which set of source data to look in and to map the data accordingly, or mush the data down into one list of Objects (if you're using an arrayadapter) and cast in the getView method (probably a bit slower than handling it in the getItem without casting).
Just use cwac-merge, a view-and-adapter wrapping adapter. You can put two ListAdapters into a MergeAdapter and set that as your single ListView's adapter.
I had problems with scrolling. I never figured out how to have the ListView share vertical space with a different View, and have a single scrollbar for them both.
I worked around it by having everything that needs to scroll on the layout a row in the ListView.
Adding views as rows to a LinearLayout may have problems scaling up, but I think you'll be OK if you only have 10 rows in total. On 1st gen Android devices it'll probably start to get sluggish around 20 items (depends on Layout complexity obviously). ListView scales up by only inflating views as they come on screen.
So in answer to your question either of the two alternatives you suggest will be OK, but the LinearLayout option will be the easiest to code.