How can I put a ListView into a ScrollView without it collapsing?

后端 未结 27 3254
轮回少年
轮回少年 2020-11-21 05:24

I\'ve searched around for solutions to this problem, and the only answer I can find seems to be \"don\'t put a ListView into a ScrollView\". I have yet to see any real expl

27条回答
  •  傲寒
    傲寒 (楼主)
    2020-11-21 05:48

    Although the suggested setListViewHeightBasedOnChildren() methods work in most of the cases, in some cases, specially with a lot of items, I noticed that the last elements are not displayed. So I decided to mimic a simple version of the ListView behavior in order to reuse any Adapter code, here it's the ListView alternative:

    import android.content.Context;
    import android.database.DataSetObserver;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.ListAdapter;
    
    public class StretchedListView extends LinearLayout {
    
    private final DataSetObserver dataSetObserver;
    private ListAdapter adapter;
    private OnItemClickListener onItemClickListener;
    
    public StretchedListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(LinearLayout.VERTICAL);
        this.dataSetObserver = new DataSetObserver() {
            @Override
            public void onChanged() {
                syncDataFromAdapter();
                super.onChanged();
            }
    
            @Override
            public void onInvalidated() {
                syncDataFromAdapter();
                super.onInvalidated();
            }
        };
    }
    
    public void setAdapter(ListAdapter adapter) {
        ensureDataSetObserverIsUnregistered();
    
        this.adapter = adapter;
        if (this.adapter != null) {
            this.adapter.registerDataSetObserver(dataSetObserver);
        }
        syncDataFromAdapter();
    }
    
    protected void ensureDataSetObserverIsUnregistered() {
        if (this.adapter != null) {
            this.adapter.unregisterDataSetObserver(dataSetObserver);
        }
    }
    
    public Object getItemAtPosition(int position) {
        return adapter != null ? adapter.getItem(position) : null;
    }
    
    public void setSelection(int i) {
        getChildAt(i).setSelected(true);
    }
    
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
    
    public ListAdapter getAdapter() {
        return adapter;
    }
    
    public int getCount() {
        return adapter != null ? adapter.getCount() : 0;
    }
    
    private void syncDataFromAdapter() {
        removeAllViews();
        if (adapter != null) {
            int count = adapter.getCount();
            for (int i = 0; i < count; i++) {
                View view = adapter.getView(i, null, this);
                boolean enabled = adapter.isEnabled(i);
                if (enabled) {
                    final int position = i;
                    final long id = adapter.getItemId(position);
                    view.setOnClickListener(new View.OnClickListener() {
    
                        @Override
                        public void onClick(View v) {
                            if (onItemClickListener != null) {
                                onItemClickListener.onItemClick(null, v, position, id);
                            }
                        }
                    });
                }
                addView(view);
    
            }
        }
    }
    }
    

提交回复
热议问题