Dou*_*ugW 347 android android-listview android-scrollview
我一直在寻找这个问题的解决方案,我能找到的唯一答案似乎是" 不要将ListView放入ScrollView ".我还没有看到任何真正的解释为什么.我似乎找到的唯一原因是Google认为你不应该这样做.好吧,我做了,所以我做到了.
所以问题是,如何将ListView放入ScrollView而不将其折叠到最小高度?
Dou*_*ugW 260
这是我的解决方案.我是Android平台的新手,我确信这有点hackish,特别是关于直接调用.measure并直接设置LayoutParams.height
属性的部分,但它确实有效.
您所要做的就是打电话Utility.setListViewHeightBasedOnChildren(yourListView)
,它将被调整大小以准确容纳其物品的高度.
public class Utility {
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
}
Run Code Online (Sandbox Code Playgroud)
Rom*_*Guy 195
使用a ListView
使其不滚动是非常昂贵的,并且违背了整个目的ListView
.你应该不这样做.只需使用一个LinearLayout
.
Atu*_*waj 89
这肯定会工作............
你只需更换你的<ScrollView ></ScrollView>
这个布局XML文件Custom ScrollView
像 <com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >
package com.tmd.utils;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false" );
return false;
default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action ); break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 25
把它放在ListView
里面ScrollView
,我们可以ListView
用作ScrollView
.必须进入的东西ListView
可以放在里面ListView
.ListView
可以通过向页眉和页脚添加布局来放置顶部和底部的其他布局ListView
.所以整个ListView
会给你一个滚动的体验.
dju*_*nod 21
在很多情况下,在ScrollView中使用ListView非常有意义.
这里的代码基于DougW的建议......在片段中工作,占用更少的内存.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
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.WRAP_CONTENT));
}
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Run Code Online (Sandbox Code Playgroud)
在每个嵌入式列表视图上调用setListViewHeightBasedOnChildren(listview).
Jas*_*n Y 17
ListView实际上已经能够测量自身足够高以显示所有项目,但是当您只是指定wrap_content(MeasureSpec.UNSPECIFIED)时它不会这样做.当使用MeasureSpec.AT_MOST给出高度时,它将执行此操作.有了这些知识,您可以创建一个非常简单的子类来解决这个问题,它比上面发布的任何解决方案都要好得多.你应该仍然在这个子类中使用wrap_content.
public class ListViewForEmbeddingInScrollView extends ListView {
public ListViewForEmbeddingInScrollView(Context context) {
super(context);
}
public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 4, MeasureSpec.AT_MOST));
}
}
Run Code Online (Sandbox Code Playgroud)
将heightMeasureSpec操作为具有非常大的AT_MOST(Integer.MAX_VALUE >> 4)会导致ListView测量其所有子节点到达给定(非常大)的高度并相应地设置其高度.
由于以下几个原因,这比其他解决方案效果更好:
在缺点方面,您可能会认为这样做依赖于SDK中可能发生变化的无证行为.另一方面,您可能会认为这就是wrap_content应该如何与ListView一起使用,并且当前的wrap_content行为刚刚被破坏.
如果你担心将来会改变这种行为,你应该简单地将onMeasure函数和相关函数从ListView.java中复制到你自己的子类中,然后通过onMeasure使AT_MOST路径运行for UNSPECIFIED.
顺便说一下,我相信当你处理少量列表项时,这是一种非常有效的方法.与LinearLayout相比,它可能效率低,但当项目数量较少时,使用LinearLayout是不必要的优化,因此不必要的复杂性.
Tal*_*tle 13
有一个内置的设置.在ScrollView上:
android:fillViewport="true"
Run Code Online (Sandbox Code Playgroud)
在Java中
mScrollView.setFillViewport(true);
Run Code Online (Sandbox Code Playgroud)
Romain Guy在这里深入解释:http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
我们不能使用两个滚动simulteniuosly.我们将获得ListView的总长度并使用总高度扩展listview.然后我们可以直接在ScrollView中添加ListView或使用LinearLayout,因为ScrollView直接有一个子节点.在代码中复制setListViewHeightBasedOnChildren(lv)方法并展开listview,然后可以在scrollview中使用listview.\ layout xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#1D1D1D"
android:orientation="vertical"
android:scrollbars="none" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#1D1D1D"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="40dip"
android:background="#333"
android:gravity="center_vertical"
android:paddingLeft="8dip"
android:text="First ListView"
android:textColor="#C7C7C7"
android:textSize="20sp" />
<ListView
android:id="@+id/first_listview"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:divider="#00000000"
android:listSelector="#ff0000"
android:scrollbars="none" />
<TextView
android:layout_width="fill_parent"
android:layout_height="40dip"
android:background="#333"
android:gravity="center_vertical"
android:paddingLeft="8dip"
android:text="Second ListView"
android:textColor="#C7C7C7"
android:textSize="20sp" />
<ListView
android:id="@+id/secondList"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:divider="#00000000"
android:listSelector="#ffcc00"
android:scrollbars="none" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
Activity类中的onCreate方法:
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_inside_scrollview);
ListView list_first=(ListView) findViewById(R.id.first_listview);
ListView list_second=(ListView) findViewById(R.id.secondList);
ArrayList<String> list=new ArrayList<String>();
for(int x=0;x<30;x++)
{
list.add("Item "+x);
}
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,list);
list_first.setAdapter(adapter);
setListViewHeightBasedOnChildren(list_first);
list_second.setAdapter(adapter);
setListViewHeightBasedOnChildren(list_second);
}
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
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);
}
Run Code Online (Sandbox Code Playgroud)
您创建不可滚动的自定义ListView
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();
}
}
Run Code Online (Sandbox Code Playgroud)
在您的布局资源文件中
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- com.Example Changed with your Package name -->
<com.Example.NonScrollListView
android:id="@+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/lv_nonscroll_list" >
<!-- Your another layout in scroll view -->
</RelativeLayout>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
在Java文件中
创建customListview的对象而不是ListView,如:NonScrollListView non_scroll_list =(NonScrollListView)findViewById(R.id.lv_nonscroll_list);
小智 6
这是唯一对我有用的东西:
在棒棒糖上你可以使用
yourtListView.setNestedScrollingEnabled(true);
Run Code Online (Sandbox Code Playgroud)
如果您需要向后兼容旧版本的操作系统,这将启用或禁用此视图的嵌套滚动,您将不得不使用 RecyclerView。
归档时间: |
|
查看次数: |
238278 次 |
最近记录: |