Question

I have few contents follwed by Expandable listview.I am not able to scroll the entire layout. I have been searching for appropriate answer more than a week..Suggest some answers.

Was it helpful?

Solution 4

Firstly I suppose you are not using more than one child layout inside a scroll view, as a scroll view can have only one direct child.

Secondly you should not use any scrolling component like expandable list, inside a scroll view here's why ListView inside ScrollView is not scrolling on Android.

OTHER TIPS

This solution worked for me, when i used custom layout inside navigation view having scroll view with LinearLayout which has Expandable listview.

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header">
    <ScrollView
            android:fillViewport="true"
            android:layout_marginTop="130dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <LinearLayout
                    android:id="@+id/homeLayout"
                    android:clickable="true"
                    android:gravity="center_vertical"
                    android:background="@drawable/layout_click_effect"
                    android:layout_width="match_parent"
                    android:layout_height="45dp">

                    <ImageView
                        android:id="@+id/homeIv"
                        android:layout_width="45dp"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_home_black_24dp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Home" />
                </LinearLayout>
                <View
                    android:background="@android:color/darker_gray"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"/>

                <ExpandableListView
                    android:id="@+id/topCatgExpLv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="start"
                    android:groupIndicator="@null"
                    android:dividerHeight="1dp" />
        </ScrollView>


    </android.support.design.widget.NavigationView>

In your onCreate

mListView = (ExpandableListView) findViewById(R.id.activity_expandable_list_view);
    MyExpandableListAdapter adapter = new MyExpandableListAdapter(this,
            mGroups);
    mListView.setAdapter(adapter);
    mListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {

        @Override
        public boolean onGroupClick(ExpandableListView parent, View v,
                                    int groupPosition, long id) {
            setListViewHeight(parent, groupPosition);
            return false;
        }
    });

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();

            }
            //Add Divider Height
            totalHeight += listView.getDividerHeight() * (listAdapter.getChildrenCount(i) - 1);
        }
    }
    //Add Divider Height
    totalHeight += listView.getDividerHeight() * (listAdapter.getGroupCount() - 1);

    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();
}

you can do this very simple . set your height of scroll view to wrap_content. set your height of root view inside scroll view as wrap_content (such as linear layout) and set your expandable list view to wrap_content. after that set OnGroupExpandListener and OnGroupCollapseListener for your expandable list view and set height for that as long as child of expandable list view. like this code : your layout :

<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollViewDrawer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@color/mainGray"
    >
 <ExpandableListView
    android:id="@+id/expandableListCategory"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
                />
 </LinearLayout>
 </ScrollView>

and this is your fragment: (or in your activity)

public class DrawerFragment extends Fragment implements, OnGroupExpandListener, OnGroupCollapseListener{
ScrollView scrollView;
ExpandableListView expListView;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
view rootView = inflater.inflate(R.layout.fragment_layout, container, false);
scrollView = (ScrollView) rootView.findViewById(R.id.scrollViewDrawer);
expListView = (ExpandableListView) rootView.findViewById(R.id.expandableListCategory);
....
}
@Override
public void onGroupExpand(int groupPosition) {
    LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) expListView.getLayoutParams();
    param.height = (childCount * expListView.getHeight());
    expListView.setLayoutParams(param);
    expListView.refreshDrawableState();
    scrollView.refreshDrawableState();
}

@Override
public void onGroupCollapse(int groupPosition) {
    LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) expListView.getLayoutParams();
    param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
    expListView.setLayoutParams(param);
    expListView.refreshDrawableState();
    scrollView.refreshDrawableState();
}

I know the question is pretty old, but may be it will be helpful for someone. Basically my answer is some what a combination of the answers of Amit Tumkur and user2141833. After a lot of trial and error, the following code is working for me:

First calculating the initial height of the Expandable list view i.e. when the whole thing is collapsed

    for (Integer i = 0; i < mAdapter.getGroupCount(); i++) {
        View groupItem = mAdapter.getGroupView(i, false, null, mExpandableListView);
        groupItem.measure(mExpandableListView.getWidth(), View.MeasureSpec.UNSPECIFIED);
        mInitialHeight += groupItem.getMeasuredHeight();
    }

Then when the group is clicked set the height of the Expandable List view to Wrap Content

    mExpandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
        @Override
        public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
            //Other Expansion/Collapsing Logic
            setListHeightToWrap();
            return true;
        }
    });

setListHeightToWrap is a different method:

private void setListHeightToWrap() {
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mExpandableListView.getLayoutParams();
    params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    mExpandableListView.setLayoutParams(params);
    mExpandableListView.refreshDrawableState();
    mScrollView.refreshDrawableState();
}

Then in OnGroupExpandListener set the height of the Expandable List View as:

    mExpandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
        @Override
        public void onGroupExpand(int groupPosition) {
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mStitchingWorksListView.getLayoutParams();
            //The Logic here will change as per your requirements and the height of each of the children in the group
            if (mAdapter.getRealChildrenCount(groupPosition) > 6) {
                params.height = 9 * mInitialHeight;
            } else {
                params.height = 6 * mInitialHeight;
            }
            //For Last Group in the list and the number of children were less as compared to other groups
            if (groupPosition == mAdapter.getGroupCount() - 1) {
                params.height = 3 * mInitialHeight;
            }
            mExpandableListView.setLayoutParams(params);
            mExpandableListView.refreshDrawableState();
        }
    });

Also the layout was ExpandableListView inside LinearLayout inside ScrollView.

Hope this helps someone. :)

For users who are looking for expandable listview into scrollview, use views instead of expandable list follow the below link & code-

enter image description here

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/linear_listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

</ScrollView>

And In Java Class some thing like this-

for (int i = 0; i < pProductArrayList.size(); i++) {

            LayoutInflater inflater = null;
            inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View mLinearView = inflater.inflate(R.layout.row_first, null);

            final TextView mProductName = (TextView) mLinearView.findViewById(R.id.textViewName);
            final RelativeLayout mLinearFirstArrow=(RelativeLayout)mLinearView.findViewById(R.id.linearFirst);
            final ImageView mImageArrowFirst=(ImageView)mLinearView.findViewById(R.id.imageFirstArrow);
            final LinearLayout mLinearScrollSecond=(LinearLayout)mLinearView.findViewById(R.id.linear_scroll);

            if(isFirstViewClick==false){
            mLinearScrollSecond.setVisibility(View.GONE);
            mImageArrowFirst.setBackgroundResource(R.drawable.arw_lt);
            }
            else{
                mLinearScrollSecond.setVisibility(View.VISIBLE);
                mImageArrowFirst.setBackgroundResource(R.drawable.arw_down);
            }

            mLinearFirstArrow.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {

                    if(isFirstViewClick==false){
                        isFirstViewClick=true;
                        mImageArrowFirst.setBackgroundResource(R.drawable.arw_down);
                        mLinearScrollSecond.setVisibility(View.VISIBLE);

                    }else{
                        isFirstViewClick=false;
                        mImageArrowFirst.setBackgroundResource(R.drawable.arw_lt);
                        mLinearScrollSecond.setVisibility(View.GONE);   
                    }
                    return false;
                } 
            });

Enter the code below adapteSet

enter code hereListAdapter listAdapter = listView.getAdapter();
 int totalHeight = 0;
 for (int i = 0; i < listAdapter.getCount(); i++) {
      View listItem = listAdapter.getView(i, null, listView);
      listItem.measure(0, 0);
      totalHeight += listItem.getMeasuredHeight();
 }

 ViewGroup.LayoutParams params = listView.getLayoutParams();
 params.height = totalHeight
      + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
 listView.setLayoutParams(params);
 listView.requestLayout();

Plese, try this once.

1) Add this line setExpandableListViewHeight(expandableListViewCategories) right after setting your adapter.

 expandableListCategoriesAdapter = new ExpandableListCategoriesAdapter(getActivity(), listDataHeader, listDataChild); 
 expandableListViewCategories.setAdapter(expandableListCategoriesAdapter);
 expandableListCategoriesAdapter.notifyDataSetChanged();
 setExpandableListViewHeight(expandableListView);

2) Coppy the bellow content and past it in to setExpandableListViewHeight() method.

private void setExpandableListViewHeight(ExpandableListView listView) {
        try {
            ExpandableListAdapter listAdapter = (ExpandableListAdapter) listView.getExpandableListAdapter();
            int totalHeight = 0;
            for (int i = 0; i < listAdapter.getGroupCount(); i++) {
                View listItem = listAdapter.getGroupView(i, false, null, listView);
                listItem.measure(0, 0);
                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();
            scrollBody.post(new Runnable() {
                public void run() {           
                    scrollBody.fullScroll(ScrollView.FOCUS_UP);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Note: This will automatically bring down your ExpandableListView and you can scroll with full view.

After trying too many solutions,i had combined two solutions any it's work properly menuHeight is important.

  expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
    @Override
    public void onGroupExpand(int groupPosition) {
        LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) 
        expandableListView.getLayoutParams();
        param.height = (2 * menuHeight); //adjust 2 according to you
        expandableListView.setLayoutParams(param);
        expandableListView.refreshDrawableState();
        findViewById(R.id.sv_menu).refreshDrawableState();

    }
});

static int menuHeight =0; // declare globally
public static void setListViewHeightBasedOnChildren(ExpandableListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
        View.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, ViewGroup.LayoutParams.WRAP_CONTENT));

    view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
    totalHeight += view.getMeasuredHeight();
}

ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();

menuHeight = totalHeight;}

Starting from API Level 21 (Lollipop) nested scroll containers are officially supported by Android SDK. There're a bunch of methods in View and ViewGroup classes which provide this functionality. To make nested scrolling work on the Lollipop you have to enable it for a child scroll view by adding android:nestedScrollingEnabled="true" to its XML declaration or by explicitly calling setNestedScrollingEnabled(true).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top