Setting ListView Height with ScrollView - android

I have created List view with in Scroll View for that I have created one method to set the height of list view. like below - This method is working fine in API 22 but not in API 18(got null pointer Exception while running in API 18). please give me solution thanks
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter mAdapter = listView.getAdapter();
int totalHeight = 0;
System.out.println("Adapter "+mAdapter);
for (int i = 0; i < mAdapter.getCount(); i++) {
View mView = mAdapter.getView(i, null, listView);
System.out.println("M View "+mView);
mView.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalHeight += mView.getMeasuredHeight();
Log.w("HEIGHT" + i, String.valueOf(totalHeight));
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (mAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}

You should not put a ListView inside ScrollView.
Just refer the below results.
ListView inside ScrollView is not scrolling on Android
Android list view inside a scroll view

There is no need to put your listview inside the scrollview .By default listview has scrollview .

I have had this error like you. And my solution is following as:
1. Create a custom listview which is non scrollable
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
2. Use above custom class for xml file
<com.Example.NonScrollListView
android:id="#+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
It worked well on all OS-version for me.
Hope best for you.

Related

Android - NestedScrollView which contains ExpandableListView doesn't scroll when expanded

I have an ExpandableListView inside a NestedScrollView (yes I know, it is not good to have a scrolling view inside another scrolling view but I don't know what else to do, please do tell me if anybody knows a better approach).
The size of the content in NestedScrollView is still within the screen so it won't scroll, but when ExpandableListView is expanded, the content will leak outside the screen but the NestedScrollView still won't scroll.. Why is this so?
Here's my NestedScrollView layout :
<NestedScrollView>
<LinearLayout>
<LinearLayout></LinearLayout>
... // About 3 of the LinearLayouts
<ExpandableListView/>
</LinearLayout>
</NestedScrollView>
You can use NonScrollExpandableListView you can achieve non-scroll property of any Lisview or GridView or ExpandableListView by overriding following method.
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
So for using NonScrollExpandableListView you need to make one custom class.
public class NonScrollExpandableListView extends ExpandableListView {
public NonScrollExpandableListView(Context context) {
super(context);
}
public NonScrollExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollExpandableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
And use it like.
<com.example.extraclasses.NonScrollExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Happy coding.
Add android:nestedScrollingEnabled="true" to your ExpandalbleListView layout.
The answer from V-rund Puro-hit is what worked for me. But it took some modifications to work with Kotlin supporting API >19. So for the purpose of saving someone time, here it is:
Create a new class file NonScrollExpandableListView:
import android.content.Context
import android.util.AttributeSet
import android.widget.ExpandableListAdapter
import android.widget.ExpandableListView
class NonScrollExpandableListView : ExpandableListView {
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}
override fun setAdapter(adapter: ExpandableListAdapter?) {
super.setAdapter(adapter)
}
override fun setOnChildClickListener(onChildClickListener: OnChildClickListener) {
super.setOnChildClickListener(onChildClickListener)
}
override fun expandGroup(groupPos: Int) : Boolean {
return super.expandGroup(groupPos)
}
override fun expandGroup(groupPos: Int, animate: Boolean) : Boolean {
return super.expandGroup(groupPos, animate)
}
override fun isGroupExpanded(groupPosition: Int): Boolean {
return super.isGroupExpanded(groupPosition)
}
public override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE shr 2, MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom)
val params = layoutParams
params.height = measuredHeight
}
}
...and I use it like so:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<com.example.you.kotlinlistview.NonScrollExpandableListView
android:id="#+id/expandableCategories"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="#+id/add_new_feed"
android:drawableStart="#drawable/ic_add"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Add new feed"
/>
<Button
android:id="#+id/settings_button"
android:drawableStart="#drawable/ic_settings"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Settings"
/>
<Button
android:id="#+id/logout_button"
android:drawableStart="#drawable/ic_exit"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Log Out"
/>
</LinearLayout>
</ScrollView>
As a result, I can comfortably add buttons and other elements to NavigationView side drawer) and it all works nicely in one common ScrollView. Main usage here is when you need to combine multiple ListViews and ExpandableListViews inside the one common ScrollView which would take care of scrolling.
Use this method this will calculate the ExpendableListSize at run time.
private void setListViewHeight(ExpandableListView listView,
int group) {
ExpandableListAdapter listAdapter = (ExpandableListAdapter) listView.getExpandableListAdapter();
int totalHeight = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.EXACTLY);
for (int i = 0; i < listAdapter.getGroupCount(); i++) {
View groupItem = listAdapter.getGroupView(i, false, null, listView);
groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += groupItem.getMeasuredHeight();
if (((listView.isGroupExpanded(i)) && (i != group))
|| ((!listView.isGroupExpanded(i)) && (i == group))) {
for (int j = 0; j < listAdapter.getChildrenCount(i); j++) {
View listItem = listAdapter.getChildView(i, j, false, null,
listView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
}
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
int height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getGroupCount() - 1));
if (height < 10)
height = 200;
params.height = height;
listView.setLayoutParams(params);
listView.requestLayout();
}
An call this method in your setOnGroupClickListener.like below
mExpandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
setListViewHeight(parent, groupPosition);
return false;
}
});
We can't use listview, gridview or expandable listview inside scrollview. If you wan't to use expandable listview inside scrollview then you have to give some fixed height to your expandable listview.

Android 1 Parent ScrollView, 3 TextView with vertical scrolling

I have a question with the android programming.
I have a parent scrollview for whole activity, and there are three textviews with scrolling function. However, when I used the following code it seems to be not working at all. Only the parent scrolling is available.
final View view = inflater.inflate(R.layout.activity_register_terms_fragment, container, false);
TextView basicTermView = (TextView) view.findViewById(R.id.register_terms_basic_info);
TextView purposeTermView = (TextView) view.findViewById(R.id.register_terms_purpose_info);
TextView provideTermView = (TextView) view.findViewById(R.id.register_terms_provide_info);
TextView previous = (TextView) view.findViewById(R.id.register_terms_pre);
TextView next = (TextView) view.findViewById(R.id.register_terms_next);
basicTermView.setMovementMethod(new ScrollingMovementMethod());
purposeTermView.setMovementMethod(new ScrollingMovementMethod());
provideTermView.setMovementMethod(new ScrollingMovementMethod());
How should I change the codes?
Thank you for helping me!
You can't have a scrollable View, like TextView or ListView or RecyclerView, inside a ScrollView. So use your simple TextView inside a normal layout and add android:scrollbars property to it or you can use view's customised class which will calculate view's width/height programatically and use ScrollView as it's parent.
As an example, to use Listview inside scrollview, we need to use following customised class of Listview which will calculate list items height and set it.
public class ExpandedListView extends ListView {
private ViewGroup.LayoutParams params;
private int old_count = 0;
public ExpandedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandedListView(Context context) {
super(context);
}
public ExpandedListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
#Override
protected void onDraw(Canvas canvas) {
if (getCount() != old_count) {
this.setScrollContainer(false);
old_count = getCount();
params = getLayoutParams();
params.height = getCount()
* (old_count > 0 ? getChildAt(0).getHeight() : 0);
setLayoutParams(params);
}
super.onDraw(canvas);
}
}

Custom Expandable ListView is triggering scroll on ScrollView

I have a custom ExpandableScrollView (nothing to do with the stock one):
public class ExpandableListView extends ListView
{
public ExpandableListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
expand();
}
public void expand() {
ListAdapter mAdapter = getAdapter();
int totalHeight = 0;
for (int i = 0; i < mAdapter.getCount(); i++) {
View mView = mAdapter.getView(i, null, this);
mView.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
totalHeight += mView.getMeasuredHeight();
}
ViewGroup.LayoutParams params = getLayoutParams();
params.height = totalHeight
+ (getDividerHeight() * (mAdapter.getCount() - 1));
setLayoutParams(params);
requestLayout();
}
}
I have an instance of this view inside a ScrollView. The problem is that when the layout is inflated and attached to the window, the ScrollView scrolls to the bottom.
I'm trying to figure out if it is a problem with the ScrollView or with the ExpandableScrollView. Maybe should I expand the list on another cycle?
Thanks

Get all height at listview with custom adapter and scrollview

I'd like to use listview with custom adapter and it dynamically changing.
There is that i want (element above ListView must be scrolled):
I found two main ways to do it:
use ScrollView and code with listView.measure(0,0); to dynamically set up the listview height (but it doesn't work, listview is cropped);
For example: listView have 3 items, but it height is for 2 items (1 item is hidden);
don't use ScrollView, use a setHeaderView (but it doesn't work too, ListView don't have a scrolling)
Any idea?
Use custom ListView ExpandableHeightListView here
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
use
list.setExpanded(true);
in onCreate() method.
i have a fragment in one of my apps who looks pretty much the same..
and I had the same problem as you, what I did in my case was set up the size for each of my list view cells at a fixed size. and measure the height by that logic.
not sure if that's considered the best way to achieve that, but it worked for me.
filterListView.getLayoutParams().height = (searchLabelsList.size() * (int) (43 * getScale() + 0.5f)) + (filterListView.getDividerHeight() * (searchLabelsList.size() - 1));
filterListView.setAdapter(searchLabelsAdapter);
and in the formula, 43 is the height for each cell, in dp's of course.
getScale is a method I wrote to get the scale of the screen size of the current user phone:
private float scale;
private float getScale() {
if (scale == 0) {
if (getActivity() != null) {
scale = getActivity().getResources().getDisplayMetrics().density;
}
}
return scale;
}
hope this will help, any question feel free to ask :)
good luck
You can try this:
First : In your xml put all other views inside ScrollView including ListView
<ScrollView
android:id="#+id/scrollViewId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
// Add your other views over here....
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
Second : In your java file,
Just use this custom method setListViewHeightBasedOnChildren(listview)
How ??
list = (ListView) findViewById(R.id.listview);
list.setAdapter(YOUR CUSTOM ADAPTER);
setListViewHeightBasedOnChildren(list);
Here is your custom method.
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
int totalHeight=0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++)
{
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
LayoutParams.MATCH_PARENT));
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + ((listView.getDividerHeight()) * (listAdapter.getCount()));
listView.setLayoutParams(params);
listView.requestLayout();
}
Hope this helps you somehow.

android listview display all available items without scroll with static header

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?
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);
}
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);
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);
}
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.
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);
}
}
Check this out:
ListView ignoring wrap_content
Using android:layout_height and android:layout_weight solved it for me:
<ListView
android:layout_height="0dp"
android:layout_weight="1"
/>
I just did it using setting params of ListView
public static void setListViewHeightBasedOnChildren(ListView listView) {
//this comes from value from xml tag of each item
final int HEIGHT_LARGE=75;
final int HEIGHT_LARGE=50;
final int HEIGHT_LARGE=35;
ViewGroup.LayoutParams params = listView.getLayoutParams();
int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
switch(screenSize) {
case Configuration.SCREENLAYOUT_SIZE_LARGE:
params.height =(int) (HEIGHT_LARGE*size);
break;
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
params.height =(int) (HEIGHT_NORMAL*size);
break;
case Configuration.SCREENLAYOUT_SIZE_SMALL:
params.height =(int) (HEIGHT_SMALL*size);
break;
}
listView.setLayoutParams(params);
}
I don't have a static header, but using HussoM's post as a clue, here is what I was able to get to work. In my scenario, the height of the items in the list was non-uniform, due to variable text sentences in each of the items, and I am using wrap_content for the height and match_parent for the width.
public class NonScrollableListView extends ListView {
public NonScrollableListView(Context context) {
super(context);
}
public NonScrollableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollableListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public NonScrollableListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
/**
* Measure the height of all the items in the list and set that to be the height of this
* view, so it appears as full size and doesn't need to scroll.
* #param widthMeasureSpec
* #param heightMeasureSpec
*/
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
ListAdapter adapter = this.getAdapter();
if (adapter == null) {
// we don't have an adapter yet, so probably initializing.
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int totalHeight = 0;
// compute the height of all the items
int itemCount = adapter.getCount();
for (int index=0; index<itemCount; index++) {
View item = adapter.getView(index, null, this);
// set the width so it can figure out the height
item.measure(widthMeasureSpec, 0);
totalHeight += item.getMeasuredHeight();
}
// add any dividers to the height
if (this.getDividerHeight() > 0) {
totalHeight += this.getDividerHeight() * Math.max(0, itemCount - 1);
}
// make it so
this.setMeasuredDimension(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(totalHeight, MeasureSpec.EXACTLY));
}
}
If all items has the same height
int totalItemsHeight = baseDictionaries.size() * item.getMeasuredHeight();
int totalDividersHeight = listView.getDividerHeight() * (baseDictionaries.size() - 1);
int totalPadding = listView.getPaddingBottom() + listView.getPaddingTop();
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) listTranslationWords.getLayoutParams();
lp.height = totalItemsHeight + totalDividersHeight + totalPadding;
listTranslationWords.setLayoutParams(lp);
Iam supprised no one see this.U cant have two scrolls on the same layout. 1st u have a scrollview and then u have a list, i bet u are killing some android good practices there.
If you want a simple solution to this problem without extending ListView class, this is a solution for you.
mListView.post(new Runnable() {
#Override
public void run() {
int height = 0;
for(int i = 0; i < mListView.getChildCount();i++)
height += mListView.getChildAt(i).getHeight();
ViewGroup.LayoutParams lParams = mListView.getLayoutParams();
lParams.height = height;
mListView.setLayoutParams(lParams);
}
});
In my case, I had ListView inside ScrollView and scrollview was shrinking listview by default. So I just add this in my ScrollView and it worked for me
android:fillViewport="true"
Set android:layout_height="fill_parent" in your LinearLayout

Categories

Resources