android listview display all available items without scroll with static header
Solution 1
The solution I used is to replace ListView with LinearLayout. You can create all your items inside LinearLayout, they will all be displayed. So there's really no need to use ListView.
LinearLayout list = (LinearLayout)findViewById(R.id.list_recycled_parts);
for (int i=0; i<products.size(); i++) {
Product product = products.get(i);
View vi = inflater.inflate(R.layout.product_item, null);
list.addView(vi);
}
Solution 2
As @Alex noted in the accepted answer that LinearLayout is hardly a replacement. I had a problem where LinearLayout was not an option, that's when i came across this blog. I will put the code here for reference purposes. Hope it helps someone out there!
public class UIUtils {
/**
* Sets ListView height dynamically based on the height of the items.
*
* @param listView to be resized
* @return true if the listView is successfully resized, false otherwise
*/
public static boolean setListViewHeightBasedOnItems(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
item.measure(0, 0);
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
}
Usage:
//initializing the adapter
listView.setAdapter(adapter);
UIUtils.setListViewHeightBasedOnItems(listView);
//whenever the data changes
adapter.notifyDataSetChanged();
UIUtils.setListViewHeightBasedOnItems(listView);
Solution 3
You can make your own customlistview. (It can extends ListView/ExpandableListView/GridView) and override the onMeasure method with this. With this you'll never need to call a function or anything. Just use it in your xml.
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
Solution 4
I had a ListView
in my layout and wanted to use a library which can't handle a ListView
here because it wraps it into a ScrollView
. The best solution for me is based on Fedor´s answer.
Since I already got an ArrayAdapter
for the ListView
I wanted to re-use it:
LinearLayout listViewReplacement = (LinearLayout) findViewById(R.id.listViewReplacement);
NamesRowItemAdapter adapter = new NamesRowItemAdapter(this, namesInList);
for (int i = 0; i < adapter.getCount(); i++) {
View view = adapter.getView(i, null, listViewReplacement);
listViewReplacement.addView(view);
}
For me this works fine because I just need to display dynamic data varying from 1 to 5 elements. I just had to add my own divider.
Solution 5
If someone still has the problem then you can make customList and add onMesure()
method just like I implemented it:
public class ScrolleDisabledListView extends ListView {
private int mPosition;
public ScrolleDisabledListView(Context context) {
super(context);
}
public ScrolleDisabledListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrolleDisabledListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Record the position the list the touch landed on
mPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
return super.dispatchTouchEvent(ev);
}
if (actionMasked == MotionEvent.ACTION_MOVE) {
// Ignore move events
return true;
}
if (actionMasked == MotionEvent.ACTION_UP) {
// Check if we are still within the same view
if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) {
super.dispatchTouchEvent(ev);
} else {
// Clear pressed state, cancel the action
setPressed(false);
invalidate();
return true;
}
}
return super.dispatchTouchEvent(ev);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Comments
-
d-man about 3 years
I'm having a little difficulties while trying to get a certain layout to work: I want to have list. List does not have to be scrollable, but should be shown completely. But the page itself should be able to scroll (with the lists in it), if the total content ist higher than the screen.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linear_layout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="#ff181818" > <Textview android:id="@+id/my_text" text="header contents goes here" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Textview android:id="@+id/headertext" text="header contents goes here" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <ListView android:id="@+id/my_list1" android:layout_height="wrap_content" android:layout_width="fill_parent" /> </LinearLayout> </ScrollView>
it only uses a small part of the screen (about 2 lines per list), instead of filling the available height, and the lists themselves can be scrolled. How can I change the layout to always show the whole lists but have the screen be scrollalbe?
-
dierre about 12 yearsShouldn't you pass the object to inflate?
-
Ken over 11 yearswhat is R.layout.product_item??
-
Alex about 11 yearsLinear layout is hardly a replacement. List view has built-in adapter (to fill the item views), dividers between items, item states, item click event.
-
Admin about 10 yearsBut how can we handle OnItemClick?
-
Justin over 9 yearsNot to mention, listview has performance benefits in reusing the row views. If you have a large number of rows then linear layout isn't going to work, scrolling will be extremely choppy.
-
Aritz over 9 yearsWhat about
ListView
's benefits? Are they all gone because of the scroll? -
Behnam over 9 yearsThis is a roundabout at best, not real solution.
-
Ivan over 9 yearslistview has advantage of using adapter.using linear layout doesn't implement this convenient feature.
-
Ivan over 9 yearsyou can make it with listview not only linear layout
-
Fire about 9 yearsThis is bad approach, because ListView can use Adapter, and LinearLayout can't.
-
Micah Montoya almost 8 yearsI know everyone says this is a bad approach but a ListView shouldnt be placed inside of a ScrollView. This approach would allow such if you don't need click ability and are only showing a few things. FYI. For those wondering you can populate using the "vi" view as it is your layout for the row. Just my 2 cents.
-
Wackaloon almost 8 yearsthis is the best idea to make a static list with all visible items
-
AITAALI_ABDERRAHMANE over 7 yearsThe best solution for this issue :)
-
Hibbem over 7 yearsWorks like a charm, but shouldn't UIUtils.setListViewHeightBasedOnItems(adapter); be UIUtils.setListViewHeightBasedOnItems(listView); ?
-
hBrent over 7 yearsSeems to work. Pretty much the same as stackoverflow.com/a/27818661/1493426, I think.
-
Gautham C. about 7 yearsThis is a much better answer as it is an extensible and clean approach.
-
anhtuannd almost 7 yearsIt looks very clean. I wonder with this one can we place listview inside scrollview?
-
Francisco almost 7 years@anhtuannd I haven't try that... But the only thing that change is the onMeasure method, all the scroll methods of the ListView are still working but with nothing to scroll. So if the listview is inside the scrollview I think it will still override those methods. I would look for another approach to do that.
-
ARR.s over 6 yearsif text in item in listview have more than one line it's not work ,How to fix it
-
Naveed Ahmad about 6 yearsOh man, love you. You are awesome, it worked as required. @d-man this should be the accepted answer
-
Rafael Moreno almost 6 yearsThis worked great! Minor modification when you use relative inflated layouts: Before measure: v.setLayoutParams(new ViewGroup.LayoutParams(0,0));
-
Akhtar Khan about 5 yearsYou can follow this answer: stackoverflow.com/questions/40861136/…
-
Nikita Vishwakarma almost 5 yearsThe best solution.. Thank you
-
Геннадий Курбесов over 3 yearsThis is exactly what I was looking for! I have a ListView, it contains 3-4 items. I cannot use static elements as I need all the functionality of the ListView and that solved my problem when I put it in the ScrollView!