How to get a non scrollable ListView?
Asked Answered
C

7

14

I should want a non scrollable ListView, and show the entire ListView. It's because my entire screen is a ScrollView, and I dispatch widgets with a RelativeLayout, so I don't need the ListView scroll.

I set my ui with code, not with xml.

I've used listView.setScrollContainer(false), but it's not work, I don't understand why.

Thanks.

Chickamauga answered 2/12, 2010 at 17:57 Comment(0)
R
12

Don't put a listview in a scrollview, it doesn't work. If you want a list of items that doesn't scroll, it's called a linearlayout.

Rapacious answered 2/12, 2010 at 18:3 Comment(5)
Yes, I do that, thanks. But after how I do the same as ListView on clic on a line ? (sorry i'm an android newby.)Chickamauga
@Istao: You can bind an OnClickListener or OnTouchListener to a view which will fire when it is clicked or touched.Glutathione
What if you want other features from a ListView, like selecting items, CursorAdapters and so on?Radiothermy
How can I setup an adaptor (Lazy Loader) to a Linearlayout?Perish
@Timmmm, you probably only want a cursor adapter if your data is changing. Otherwise, just iterate on the results of the cursor. However, it probably wouldn't be that difficult to build a wrapper around any list adapter, which would register a DataSetObserver on the adapter.If
P
16

I found a very simple solution for this. Just get the adapter of the listview and calculate its size when all items are shown. The advantage is that this solution also works inside a ScrollView.

Example:

public void justifyListViewHeightBasedOnChildren (ListView listView) {

    ListAdapter adapter = listView.getAdapter();

    if (adapter == null) {
        return;
    }
    ViewGroup vg = listView;
    int totalHeight = 0;
    for (int i = 0; i < adapter.getCount(); i++) {
        View listItem = adapter.getView(i, null, vg);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams par = listView.getLayoutParams();
    par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
    listView.setLayoutParams(par);
    listView.requestLayout();
}

Call this function passing over your ListView object:

justifyListViewHeightBasedOnChildren(myListview);

The function shown above is a modification of a post in: Disable scrolling in listview

Please note to call this function after you have set the adapter to the listview. If the size of entries in the adapter has changed, you need to call this function as well.

Purify answered 7/1, 2015 at 11:43 Comment(1)
Thank you. Your answer is great. There should be a away to just let the list view know that THIS is exactly what we want (I kinda need a scrollview with a small listview inside it and as I'm re-using the fragment with the list view I don't want to change and use a LinearLayout). I failed to find a better way to do this, so your answer is pretty much the best I could find. Hope it gets more upvotes. It deserves them.Icbm
O
13

The correct answer is here.

Just assign this listener to your ListView:

    listView.setOnTouchListener(new OnTouchListener() {

    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            return true; // Indicates that this has been handled by you and will not be forwarded further.
        }
        return false;
    }
});
Olpe answered 7/2, 2014 at 14:28 Comment(0)
R
12

Don't put a listview in a scrollview, it doesn't work. If you want a list of items that doesn't scroll, it's called a linearlayout.

Rapacious answered 2/12, 2010 at 18:3 Comment(5)
Yes, I do that, thanks. But after how I do the same as ListView on clic on a line ? (sorry i'm an android newby.)Chickamauga
@Istao: You can bind an OnClickListener or OnTouchListener to a view which will fire when it is clicked or touched.Glutathione
What if you want other features from a ListView, like selecting items, CursorAdapters and so on?Radiothermy
How can I setup an adaptor (Lazy Loader) to a Linearlayout?Perish
@Timmmm, you probably only want a cursor adapter if your data is changing. Otherwise, just iterate on the results of the cursor. However, it probably wouldn't be that difficult to build a wrapper around any list adapter, which would register a DataSetObserver on the adapter.If
R
5

Depending on what exactly you are trying to do, you may be able to solve your problem by ditching the ScrollView and instead using ListView's addHeaderView(View) and addFooterView(View).

Radiothermy answered 22/10, 2012 at 10:3 Comment(0)
U
0

I came up with BaseAdapterUnscrollable. Basically it just adds views to ViewGroup container. Implementation is a bit like BaseAdapter. It’s pretty convenient if you use a few non-scrollable lists like that in you project.

In onCreate:

 PeopleAdapter peopleAdapter = new PeopleAdapter(this, personList, containerPeopleLinearLayout);
 peopleAdapter.setOnItemClickListener(this);
 peopleAdapter.drawItems();

Your specific adapter:

public class PeopleAdapter extends BaseAdapterNonScrollable<Person> {

public PeopleAdapter(Context context, List<Person> items, LinearLayout container) {
    super(context, items, container);
}

@Override
public View getView(View container, Person person) {
    TextView textView = (TextView) LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, null);
    textView.setText(person.getName());
    return textView;
}

}

BaseAdapterNonScrollable (just copy):

public abstract class BaseAdapterNonScrollable<T> implements NonScrollable, OnItemClick {

public Context context;
private ViewGroup containerViewGroup;
private List<T> itemObjectList;
private OnItemClick itemClickListener;

public BaseAdapterNonScrollable(Context context, List<T> items, ViewGroup containerViewGroup) {
    this.context = context;
    this.itemObjectList = items;
    this.containerViewGroup = containerViewGroup;
}

@Override
public void drawItems() {
    if (containerViewGroup == null || itemObjectList.size() == 0) {
        return;
    }

    if (containerViewGroup.getChildCount() > 0) {
        containerViewGroup.removeAllViews();
    }

    //draw all items
    for (int i = 0; i < itemObjectList.size(); i++) {
        final int position = i;
        final View itemView = getView(containerViewGroup, itemObjectList.get(i));
        if (itemView != null) {
            containerViewGroup.addView(itemView);
            //handle item click event
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (itemClickListener != null) {
                        itemClickListener.onItemClick(itemObjectList, position);
                    }
                }
            });
        }
    }
}

public void setOnItemClickListener(OnItemClick onItemClick) {
    this.itemClickListener = onItemClick;
}

public abstract View getView(View container, T itemObject);

@Override
public void onItemClick(List<?> itemList, int position) {
}

}

Interfaces

public interface NonScrollable {
    void drawItems();
}

public interface OnItemClick {
    void onItemClick(List<?> itemList, int position);
}
Undenominational answered 11/8, 2015 at 8:9 Comment(0)
C
0

to disable scrolling you can use listview.setEnabled(false)

This also disables row selections.

Cornew answered 29/4, 2017 at 10:23 Comment(1)
It will disable everything. OP wants only scroll to disableWheeze
C
0

I have achieve this by passing in physics property into the ListView:

ListView.builder(
  --->  physics: ScrollPhysics(), <-----
        shrinkWrap: true,
        itemCount: items.length,
        itemBuilder: (context, index) {
          return //ListTile or whatever

Note: This ListView is inside of a column with other widgets, and the column is wrapped in SingleChildScrollView

Coactive answered 21/4, 2021 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.