滚动视图中的 Android 列表视图
Posted
技术标签:
【中文标题】滚动视图中的 Android 列表视图【英文标题】:Android list view inside a scroll view 【发布时间】:2013-08-24 10:06:10 【问题描述】:我有一个 android 布局,其中有一个 scrollView
,其中包含许多元素。在scrollView
的底部,我有一个listView
,然后由适配器填充。
我遇到的问题是,android 将listView
从scrollView
中排除,因为scrollView
已经具有可滚动功能。我希望 listView
与内容一样长,并且主滚动视图可以滚动。
我怎样才能实现这种行为?
这是我的主要布局:
<ScrollView
android:id="@+id/scrollView1"
android:layout_
android:layout_
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="@+id/foodItemActvity_linearLayout_fragments"
android:layout_
android:layout_
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
然后我以编程方式将我的组件添加到带有 id 的线性布局中:foodItemActvity_linearLayout_fragments
。下面是加载到该线性布局中的视图之一。这是卷轴给我带来麻烦的那个。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<TextView
android:id="@+id/fragment_dds_review_textView_label"
android:layout_
android:layout_
android:text="Reviews:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="@+id/fragment_dds_review_listView"
android:layout_
android:layout_>
</ListView>
</LinearLayout>
然后我的适配器会填满这个列表视图。
当我点击主滚动视图时,这是来自 android 层次结构查看器的图像:
如您所见,它不包括评论列表视图。
我应该能够向下滚动页面并看到 8 条评论,但它只显示这 3 条评论,我可以滚动评论所在的小部分。我想要一个全局页面滚动
【问题讨论】:
***.com/questions/18813296/… 试试这个 我得到了解决方案:androidhub4you.com/2012/12/… 在这里。您可以找到完整的描述信息:***.com/questions/20116381/… 这个RecycleView代表ListView非常好用 我希望它对你有用***.com/a/62011087/11554604 【参考方案1】:让任何子视图在 ScrollView 内滚动。任何类似 ListView、RecyclerView 等的东西。您只需在当前 xml 中将 ScrollView 替换为 androidx.core.widget.NestedScrollView然后魔法发生了。
下面是一个示例 xml 代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_
android:layout_
android:orientation="vertical"
android:padding="16dp"
android:paddingBottom="20dp">
<TextView
android:layout_
android:layout_
android:text="Recycler View inside a Scroll View"
android:textColor="@color/black"
android:textSize="@dimen/_20sp"
android:textStyle="bold" />
<TextView
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:text="Below is a Recycler View as an example."
android:textSize="16sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_
android:layout_
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@id/et_damaged_qty" />
<TextView
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:text="This textview automatically goes below the Recycler View."
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView>
现在您可以摆脱嵌套滚动的所有丑陋技巧。
【讨论】:
@JeetenParmar 已经指定了这个问题,我不得不再说一遍 - 这是一个很好的技巧,但是当 TextView 中有多行时它不起作用。 Arshu - 你后来对 Jeeten 的解决方案也不起作用(Jeeten 已经指定)。如果您找到任何解决方案,请在此处发布。我非常需要一个解决方案。 我发现这个解决方案非常适合我的情况,即支持可变高度的列表项 - ***.com/a/17503823/1433187 请删除多余的requestLayout()
- setLayoutParams 方法已经做到了。
修复测量view.measure(MeasureSpec.makeMeasureSpec(desiredWidth, MeasureSpec.AT_MOST),MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
我需要对 gridview 做同样的事情。有什么建议吗?【参考方案2】:
答案很简单,我很惊讶这里还没有答案。
在列表本身上使用Header View
或/和Footer View
。
不要将ScrollView
与ListView
或任何可以滚动的东西混合使用。它旨在与页眉和页脚一起使用:)
本质上,获取 ListView 上方的所有内容,将其作为布局放入另一个 .xml 文件中,然后在代码中对其进行膨胀并将其作为标题视图添加到列表中。
即
View header = getLayoutInflater().inflate(R.layout.header, null);
View footer = getLayoutInflater().inflate(R.layout.footer, null);
listView.addHeaderView(header);
listView.addFooterView(footer);
【讨论】:
@ericosg,但我不希望这就是我寻找解决方案的原因。 如果添加标题视图,onListItemClick 中的位置 int 参数将为 +1。所以你必须处理它。 (列表中的第一项将具有位置 1,而不是 0) 我希望 ViewPager 有一个标题。 我希望 GridView 有一个标题 这种方法运行良好,除非您需要在标题中编辑文本。出现在列表视图中时,Edittext 不保留焦点【参考方案3】:我知道已经很久了,但我也遇到了这个问题,尝试了这个解决方案并且它正在工作。所以我想它也可以帮助其他人。
我在滚动视图的布局 xml 上添加了 android:fillViewport="true"。 所以总的来说我的 ScrollView 会是这样的。
<ScrollView
android:layout_
android:layout_
android:id="@+id/scrollView6"
android:fillViewport="true">
它对我来说就像魔术一样。 位于我的 ScrollView 内的 ListView 再次扩大到它的大小。
这里是 ScrollView 和 ListView 的完整示例代码。
<ScrollView
android:layout_
android:layout_
android:id="@+id/scrollView6" android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_
android:layout_>
....
<ListView
android:layout_
android:layout_
android:id="@+id/lv_transList" android:layout_gravity="top"
android:layout_marginTop="5dp"/>
....
</LinearLayout>
</ScrollView>
【讨论】:
它禁用 ListView 滚动行为,因此如果项目大于屏幕大小,您将无法滚动列表视图。 它禁用了 ScrollView 的滚动功能 此解决方案不起作用,因为如果列表视图占据整个屏幕,则列表视图下方的元素将无法访问【参考方案4】:您创建不可滚动的自定义 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();
在您的布局资源文件中
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:fadingEdgeLength="0dp"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none" >
<RelativeLayout
android:layout_
android:layout_ >
<!-- com.Example Changed with your Package name -->
<com.Example.NonScrollListView
android:id="@+id/lv_nonscroll_list"
android:layout_
android:layout_ >
</com.Example.NonScrollListView>
<RelativeLayout
android:layout_
android:layout_
android:layout_below="@+id/lv_nonscroll_list" >
<!-- Your another layout in scroll view -->
</RelativeLayout>
</RelativeLayout>
</ScrollView>
在 Java 文件中 创建你的 customListview 的对象,而不是 ListView 像: NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);
【讨论】:
或者你可以只分享链接 这会强制滚动视图在列表视图的顶部滚动。意外行为【参考方案5】: public static void setListViewHeightBasedOnChildren(ListView listView)
// 获取ListView对应的Adapter
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) // listAdapter.getCount()返回数据项的数目
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0); // 计算子项View 的宽高
totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
listView.setLayoutParams(params);
您可以将此代码用于滚动视图中的列表视图
【讨论】:
这会禁用滚动内置的列表视图吗? 这也适用于ListView
内的 RecyclerView
以显示超过第一个元素。
谢谢,这个答案很有帮助。我的问题是我在 ScrollView 中有一个 ListView,当我更新 ListView 中的元素时,ScrollView 仍然具有相同的高度。这意味着即使 ListView 的行数较少,用户也可以向下滚动。
对于那些花费大量时间弄清楚如何将 ListView 放在 ScrollView 中的人(不建议),因为使用线性布局会杀死你的 UI,那么这很好,但建议你动态添加线性视图中的项目【参考方案6】:
不要在 Parent ScrollView 中做任何事情。仅对子 ListView 执行此操作。一切都会完美运行。
mListView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
mScrollView.requestDisallowInterceptTouchEvent(true);
int action = event.getActionMasked();
switch (action)
case MotionEvent.ACTION_UP:
mScrollView.requestDisallowInterceptTouchEvent(false);
break;
return false;
);
【讨论】:
这应该是一个可以接受的答案。它简单而智能。只需在您触摸列表视图时禁用滚动视图,并在您抬起手指时再次启用它【参考方案7】:如果您在代码中仅实现了一个 ListView,此代码将解决您的问题。
如果您使用 RelativeLayout 作为 ListView 子项,则此代码会在此处返回 NullPointerException listItem.measure(0, 0);,因为 RelativeLayout.And 解决方案是将您的 Relativelayout 放在 LinearLayout 中并且它会正常工作的。
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);
listView.requestLayout();
【讨论】:
如果您的列表视图中有填充,那么您也应该添加:- int padding = listView.getPaddingTop() + listView.getPaddingBottom(); 是的,相对布局在计算高度时会产生问题。感谢您解释相对布局问题【参考方案8】:您可以通过在 ScrollView 中添加 android:fillViewport="true"
来解决此问题。
<ScrollView
android:layout_
android:layout_
android:background="@color/white"
android:fillViewport="true"
android:scrollbars="vertical">
<ListView
android:id="@+id/statusList"
android:layout_
android:layout_
android:animationCache="false"
android:divider="@null"
android:scrollingCache="false"
android:smoothScrollbar="true" />
</ScrollView>
在使用该属性之前,我的列表视图中只有一个子视图可见。使用后,列表的所有行或子项都可见。
【讨论】:
Android:scrollingCache="false" 不再支持 v8 以上的新 Android 版本。【参考方案9】:我会把它留在这里,以防有人遇到同样的问题。我必须在 ScrollView 中放置一个 ListView。由于多种原因,带有标题的 ListView 不是一个选项。也不是使用 LinearLayout 代替 ListView 的选项。所以我遵循了接受的解决方案,但它不起作用,因为列表中的项目具有多行的复杂布局,并且每个列表视图项目的高度可变。高度测量不正确。解决方案是测量 ListView Adapter 的 getView() 方法中的每个项目。
@Override
public View getView(int position, View view, ViewGroup parent)
ViewHolder holder;
if (view == null)
. . .
view.setTag(holder);
else holder = (ViewHolder)view.getTag();
. . .
// measure ListView item (to solve 'ListView inside ScrollView' problem)
view.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
return view;
【讨论】:
【参考方案10】:您可以轻松地将 ListView 放入 ScrollView 中! 只需要以编程方式改变ListView的高度,像这样:
ViewGroup.LayoutParams listViewParams = (ViewGroup.LayoutParams)listView.getLayoutParams();
listViewParams.height = 400;
listView.requestLayout();
这很好用!
【讨论】:
这就是the accepted answer 所做的,但它不是神奇地确定它是 400,而是计算确切的高度。这样您就不必猜测了。【参考方案11】:经过大量研发后完成:
fragment_one.xml 应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@+id/scrollViewParent"
android:orientation="vertical" >
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical" >
<RelativeLayout
android:layout_
android:layout_ >
<ListView
android:id="@+id/listView"
android:layout_
android:layout_ />
<View
android:id="@+id/customView"
android:layout_
android:layout_
android:background="@android:color/transparent" />
</RelativeLayout>
<!-- Your other elements are here -->
</LinearLayout>
</ScrollView>
FragmentOne.java 的 Java 类如下所示:
private ListView listView;
private View customView
onCreateView
listView = (ListView) rootView.findViewById(R.id.listView);
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);
customView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
int action = event.getAction();
switch (action)
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(true);
// Disable touch on transparent view
return false;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(false);
return true;
case MotionEvent.ACTION_MOVE:
scrollViewParent.requestDisallowInterceptTouchEvent(true);
return false;
default:
return true;
);
【讨论】:
【参考方案12】:我的要求是在 ScrollView 中包含大小相等的项目的 ListView。我尝试了此处列出的其他一些解决方案,但似乎都没有正确调整 ListView 的大小(空间太小或太多)。这对我有用:
public static void expandListViewHeight(ListView listView)
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
ViewGroup.LayoutParams params = listView.getLayoutParams();
listView.measure(0, 0);
params.height = listView.getMeasuredHeight() * listAdapter.getCount() + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
希望这对某人有所帮助。
【讨论】:
【参考方案13】:我遇到了与原始海报提出的问题类似的问题 - 如何使列表视图在滚动视图内滚动 - 这个答案解决了我的问题。 Disable scrolling of a ListView contained within a ScrollView
我没有像 OP 那样将新片段调用到现有布局或类似的东西中,所以我的代码看起来像这样:
<ScrollView
android:id="@+id/scrollView1"
android:layout_
android:layout_
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="@+id/foodItemActvity_linearLayout_fragments"
android:layout_
android:layout_
android:orientation="vertical" >
<TextView
android:id="@+id/fragment_dds_review_textView_label"
android:layout_
android:layout_
android:text="Reviews:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="@+id/my_listView"
android:layout_
android:layout_>
</ListView>
</LinearLayout>
</ScrollView>
基本上,我正在做的是在调用列表视图之前检查它的长度,当我调用它时,我会将其设置为该长度。在你的 java 类中使用这个函数:
public static 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();
然后像这样调用函数:
justifyListViewHeightBasedOnChildren(listView);
结果是一个没有滚动条的列表视图,整个列表视图的长度被显示,随着滚动视图的滚动条滚动。
【讨论】:
【参考方案14】:正如其他人已经提到的,不要在 ScrollView 中使用 ListView。
要解决此问题,您可以使用 LinearLayout,但仍要保持整洁 - 使用 Adapter 填充 LinearLayout,就像使用 ListView 一样
您可以将此类用作支持适配器的 LinearLayout 替代品
import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
public class AdaptableLinearLayout extends LinearLayout
private BaseAdapter mAdapter;
private int mItemCount = 0;
private boolean mDisableChildrenWhenDisabled = false;
private int mWidthMeasureSpec;
private int mHeightMeasureSpec;
public AdaptableLinearLayout(Context context, AttributeSet attrs)
super(context, attrs);
// TODO Auto-generated constructor stub
public BaseAdapter getAdapter()
return mAdapter;
public void setAdapter(BaseAdapter adapter)
mAdapter = adapter;
adapter.registerDataSetObserver(new DataSetObserver()
@Override
public void onChanged()
updateLayout();
super.onChanged();
@Override
public void onInvalidated()
updateLayout();
super.onInvalidated();
);
updateLayout();
private void updateLayout()
mItemCount = mAdapter.getCount();
requestLayout();
invalidate();
/**
* set size for the current View
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidthMeasureSpec = widthMeasureSpec;
mHeightMeasureSpec = heightMeasureSpec;
removeAllViewsInLayout();
for (int i = 0; i < mItemCount; i++)
makeAndAddView(i);
private View makeAndAddView(int position)
View child;
// Nothing found in the recycler -- ask the adapter for a view
child = mAdapter.getView(position, null, this);
// Position the view
setUpChild(child, position);
return child;
private void setUpChild(View child, int position)
ViewGroup.LayoutParams lp = child.getLayoutParams();
if (lp == null)
lp = generateDefaultLayoutParams();
addViewInLayout(child, position, lp);
// Get measure specs
int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), lp.height);
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);
// Measure child
child.measure(childWidthSpec, childHeightSpec);
int childLeft;
int childRight;
// Position vertically based on gravity setting
int childTop = getPaddingTop() + ((getMeasuredHeight() - getPaddingBottom() - getPaddingTop() - child.getMeasuredHeight()) / 2);
int childBottom = childTop + child.getMeasuredHeight();
int width = child.getMeasuredWidth();
childLeft = 0;
childRight = childLeft + width;
child.layout(childLeft, childTop, childRight, childBottom);
if (mDisableChildrenWhenDisabled)
child.setEnabled(isEnabled());
【讨论】:
这是否管理回收?还是适配器负责回收视图? 我很久以前就实现了这个类,所以我认为出于 dev.speed 的目的,我没有添加回收支持。正如我现在在代码中看到的那样,类假定回收器是空的【参考方案15】:您可以将所有内容放入线性布局中。也就是说,创建线性布局,它将有 2 个孩子,滚动视图和另一个线性布局。给他们布局权重,然后就可以了:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<ScrollView
android:layout_
android:layout_ android:layout_weight="0.8">
<LinearLayout
android:id="@+id/seTaskActivityRoot"
android:layout_
android:layout_
android:background="@color/white"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_
android:layout_
android:layout_weight="1"
android:text="@string/taskName" />
<Spinner
android:id="@+id/seTaskPrioritiesSP"
android:layout_
android:layout_
android:layout_weight="1" />
<TextView
android:id="@+id/textView4"
android:layout_
android:layout_
android:layout_weight="1"
android:text="@string/taskTargetInNumeric" />
<Spinner
android:id="@+id/seTaskUnitsSP"
android:layout_
android:layout_
android:layout_weight="1" />
<TextView
android:id="@+id/textView6"
android:layout_
android:layout_
android:layout_weight="1"
android:text="@string/newTaskCurrentStatus" />
<EditText
android:layout_
android:layout_
android:layout_weight="1"
android:ems="10"
android:hint="@string/addTaskCurrentStatus"
android:inputType="numberDecimal" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical" android:layout_weight="0.2">
<TextView
android:id="@+id/textView8"
android:layout_
android:layout_
android:text="TextView" />
<ListView
android:id="@+id/logList"
android:layout_
android:layout_ >
</ListView>
</LinearLayout>
【讨论】:
这意味着ListView
不会随着其余内容滚动。无论用户是向上还是向下滚动,它都会一直占据屏幕的一部分【参考方案16】:
您永远不应该将 ScrollView 与 ListView 一起使用,因为 ListView 负责自己的垂直滚动。最重要的是,这样做会破坏 ListView 中处理大型列表的所有重要优化,因为它有效地强制 ListView 显示其整个项目列表以填充 ScrollView 提供的无限容器。
http://developer.android.com/reference/android/widget/ScrollView.html
【讨论】:
【参考方案17】:切勿将ListView
放在ScrollView
中!您可以在Google 上找到有关该主题的更多信息。在您的情况下,请使用 LinearLayout
而不是 ListView
并以编程方式添加元素。
【讨论】:
哦好的我明白了,我还能用适配器的类似概念来填充线性布局吗?【参考方案18】:更新
<ScrollView
android:id="@+id/scrollView1"
android:layout_
android:layout_
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="@+id/foodItemActvity_linearLayout_fragments"
android:layout_
android:layout_
android:orientation="vertical" >
</LinearLayout>
到
<ScrollView
android:id="@+id/scrollView1"
android:layout_
android:layout_
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="@+id/foodItemActvity_linearLayout_fragments"
android:layout_
android:layout_
android:orientation="vertical" >
</LinearLayout>
这里的重点是您尝试将高度设置为 0dp(固定)
【讨论】:
这样权重才会生效。 你想让产品图片和左上角的文本视图可以滚动吗?如果是这样,您应该在 Scroll 视图中删除这两项,因为我目前可以看到它们不是 它们当前位于滚动视图内,因为我以编程方式将它们添加到滚动视图内的线性布局中。如果我的逻辑是正确的,则线性布局子级也应该与滚动视图一起使用。【参考方案19】:找到了scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> 动态列表视图的解决方案,但我不是作者。有一些错误,但至少它可以工作
public class CustomPager extends ViewPager
private View mCurrentView;
public CustomPager(Context context)
super(context);
public CustomPager(Context context, AttributeSet attrs)
super(context, attrs);
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
if (mCurrentView == null)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
public void measureCurrentView(View currentView)
mCurrentView = currentView;
this.post(new Runnable()
@Override
public void run()
requestLayout();
);
public int measureFragment(View view)
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
public class MyPagerAdapter extends FragmentPagerAdapter
private List<Fragment> fragments;
private int mCurrentPosition = -1;
public MyPagerAdapter(FragmentManager fm)
super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
this.fragments = new ArrayList<Fragment>();
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
fragments.add(new FourthFragment());
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition)
Fragment fragment = (Fragment) object;
CustomPager pager = (CustomPager) container;
if (fragment != null && fragment.getView() != null)
mCurrentPosition = position;
pager.measureCurrentView(fragment.getView());
@Override
public Fragment getItem(int position)
return fragments.get(position);
@Override
public int getCount()
return fragments.size();
片段布局可以是任何东西
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_
android:orientation="vertical"
android:layout_ tools:context="nevet.me.wcviewpagersample.FirstFragment">
<ListView
android:id="@+id/lv1"
android:layout_
android:layout_
android:background="#991199"/>
</LinearLayout>
然后在某个地方
lv = (ListView) view.findViewById(R.id.lv1);
lv.setAdapter(arrayAdapter);
setListViewHeightBasedOnChildren(lv);
public static void setListViewHeightBasedOnChildren(ListView 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,
LinearLayout.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();
【讨论】:
【参考方案20】:使用这个 ListView 为我工作
package net.londatiga.android.widget;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
import android.content.Context;
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;
在xml中
<com.pakagename.ExpandableHeightListView
android:id="@+id/expandableHeightListView"
android:layout_
android:layout_ >
</com.Example.ExpandableHeightListView>
在 MainActivity 中
ExpandableHeightListView listView = new ExpandableHeightListView(this);
listview=(ExpandableHeightListView)findViewById(R.id.expandableHeightListView);
listView.setAdapter(adapter); //set your adaper
listView.setExpanded(true);
Refer This 文章了解更多信息以及如何将 gridview 保持在滚动视图中
【讨论】:
【参考方案21】: 无法在 List-view 中使用 Scroll-view,因为 List-view 已经具有滚动属性。要在滚动视图中使用列表视图,您可以按照这些对我有用的步骤:
1) 创建 NonScrollListView java 文件,禁用列表视图的默认滚动属性。代码如下
package your-package-structure;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.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();
2) 现在创建包含NestedScrollView
的xml 文件,并在其中使用NonScrollListView
列出您的项目。这将使您的整个屏幕与所有视图一起滚动。
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="vertical">
<ViewFlipper
android:id="@+id/v_flipper"
android:layout_
android:layout_>
</ViewFlipper>
<TextView
android:layout_
android:layout_
android:text="SHOP"
android:textSize="15dp"
android:textStyle="bold"
android:gravity="center"
android:padding="5dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"/>
<View
android:layout_
android:layout_
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#ddd"/>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:layout_weight="1"
>
<com.abc.xyz.NonScrollListView
android:id="@+id/listview"
android:divider="@null"
android:layout_
android:layout_marginBottom="10dp"
android:layout_
android:padding="8dp">
</com.abc.xyz.NonScrollListView>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:gravity="bottom">
<include layout="@layout/footer" />
</LinearLayout>
</LinearLayout>
3) 现在在 java 类,即 home.java 中定义 NonScrollListView
而不是 Listview
。
package comabc.xyz.landscapeapp;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.Toolbar;
import android.widget.ViewFlipper;
公共类主页扩展片段 整数位置 = 0; ViewFlipper v_flipper;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View view = inflater.inflate(R.layout.activity_home, container, false);
return view;
@Override
public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState)
NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
customAdapter customAdapter = new customAdapter(getActivity());
listView.setAdapter(customAdapter);
listView.setFocusable(false);
customAdapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
Log.d("listview click", "onItemClick: ");
/* FragmentTransaction fr = getFragmentManager().beginTransaction().replace(R.id.fragment_container, new productdisplay());
fr.putExtra("Position", position);
fr.addToBackStack("tag");
fr.commit();*/
Intent intent = new Intent(getActivity(), productdisplay.class);
intent.putExtra("Position", position);
startActivity(intent);
);
//image slider
int images[] = R.drawable.slide1, R.drawable.slide2, R.drawable.slide3;
v_flipper = view.findViewById(R.id.v_flipper);
for (int image : images)
flipperImages(image);
private void flipperImages(int image)
ImageView imageView = new ImageView(getActivity());
imageView.setBackgroundResource(image);
v_flipper.addView(imageView);
v_flipper.setFlipInterval(4000);
v_flipper.setAutoStart(true);
v_flipper.setInAnimation(getActivity(), android.R.anim.slide_in_left);
v_flipper.setOutAnimation(getActivity(), android.R.anim.slide_out_right);
注意:我在这里使用了Fragments
。
【讨论】:
【参考方案22】:好的,这是我的答案。固定 ListView 高度的方法已经足够封闭,但并不完美。如果大多数物品的高度相同,那效果很好。但如果不是这样,那就有大问题了。我试过很多次,当我把listItem.getMeasureHeight和listItem.getMeasuerWidth的值放到日志中时,我看到宽度值变化很大,这不是预期的,因为同一个ListView中的所有项目都应该具有相同的宽度。还有错误:
有些人使用了 measure(0 ,0),这实际上使视图在两个方向和宽度上都不受约束。有的尝试获取listView的宽度,然后返回0,没有意义。
当我进一步阅读 android 如何渲染视图时,我意识到所有这些尝试都无法达到我搜索的答案,除非这些函数在视图渲染后运行。
这次我在我想固定高度的ListView上使用getViewTreeObserver,然后addOnGlobalLayoutListener。在这个方法中,我声明了一个新的 OnGlobalLayoutListener,这一次,getWidth 返回 ListView 的实际宽度。
private void getLayoutWidth(final ListView lv, final int pad)
//final ArrayList<Integer> width = new ArrayList<Integer>();
ViewTreeObserver vto = lv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
lv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//width.add(layout.getMeasuredWidth());
int width = lv.getMeasuredWidth();
ListUtils.setDynamicHeight(lv, width, pad);
);
public static class ListUtils
//private static final int UNBOUNDED = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
public static void setDynamicHeight(ListView mListView, int width, int pad)
ListAdapter mListAdapter = mListView.getAdapter();
mListView.getParent();
if (mListAdapter == null)
// when adapter is null
return;
int height = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(width - 2*pad, View.MeasureSpec.EXACTLY);
for (int i = 0; i < mListAdapter.getCount(); i++)
View listItem = mListAdapter.getView(i, null, mListView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
//listItem.measure(UNBOUNDED, UNBOUNDED);
height += listItem.getMeasuredHeight() + 2*pad;
Log.v("ViewHeight :", mListAdapter.getClass().toString() + " " + listItem.getMeasuredHeight() + "--" + listItem.getMeasuredWidth());
ViewGroup.LayoutParams params = mListView.getLayoutParams();
params.height = height + (mListView.getDividerHeight() * (mListAdapter.getCount() - 1));
mListView.setLayoutParams(params);
mListView.requestLayout();
值填充,是我在 ListView 布局中设置的填充。
【讨论】:
【参考方案23】:如果由于某种原因您不想使用 addHeaderView
和 addFooterView
,例如当您有多个列表时,一个好主意是重用ListAdapter
来填充一个简单的LinearLayout
,这样就没有滚动功能。
如果您已经有一个从ListFragment
派生的完整片段,并且希望将其转换为具有简单LinearLayout
的类似片段而不滚动(例如,将其放入ScrollView),您可以实现这样的适配器片段:
// converts listFragment to linearLayout (no scrolling)
// please call init() after fragment is inflated to set listFragment to convert
public class ListAsArrayFragment extends Fragment
public ListAsArrayFragment()
private ListFragment mListFragment;
private LinearLayout mRootView;
// please call me!
public void init(Activity activity, ListFragment listFragment)
mListFragment = listFragment;
mListFragment.onAttach(activity);
mListFragment.getListAdapter().registerDataSetObserver(new DataSetObserver()
@Override
public void onChanged()
super.onChanged();
refreshView();
);
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
// create an empty vertical LinearLayout as the root view of this fragment
mRootView = new LinearLayout(getActivity());
mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mRootView.setOrientation(LinearLayout.VERTICAL);
return mRootView;
// reusing views for performance
// todo: support for more than one view type
ArrayList<View> mViewsToReuse = new ArrayList<>();
ArrayList<View> mCurrentViews = new ArrayList<>();
// re-add views to linearLayout
void refreshView()
// remove old views from linearLayout and move them to mViewsToReuse
mRootView.removeAllViews();
mViewsToReuse.addAll(mCurrentViews);
mCurrentViews.clear();
// create new views
for(int i=0; i<mListFragment.getListAdapter().getCount(); ++i)
View viewToReuse = null;
if(!mViewsToReuse.isEmpty())
viewToReuse = mViewsToReuse.get(mViewsToReuse.size()-1);
mViewsToReuse.remove(mViewsToReuse.size()-1);
final View view = mListFragment.getListAdapter().getView(i, viewToReuse, mRootView);
ViewGroup.LayoutParams oldParams = view.getLayoutParams();
view.setLayoutParams(new LinearLayout.LayoutParams(oldParams.width, oldParams.height));
final int finalI = i;
// pass click events to listFragment
view.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
mListFragment.onListItemClick(null, view, finalI, finalI);
);
mRootView.addView(view);
mCurrentViews.add(view);
您可能还想根据您的需要将onCreate
、onPause
、onResume
等转发到原始片段或尝试继承而不是组合(但覆盖某些方法,以便原始片段实际上不附加到布局层次结构);但我想尽可能地隔离原始片段,因为我们只需要提取它的ListAdapter
。如果你在onAttach
中调用原始片段的setListAdapter
,那可能就够了。
以下是如何使用ListAsArrayFragment
来包含OriginalListFragment
而无需滚动。在父活动的onCreate
:
ListAsArrayFragment fragment = (ListAsArrayFragment) getFragmentManager().findFragmentById(R.id.someFragmentId);
OriginalListFragment originalFragment = new OriginalListFragment();
fragment.init(this, originalFragment);
// now access originalFragment.getListAdapter() to modify list entries
// and remember to call notifyDatasetChanged()
【讨论】:
【参考方案24】:找到了scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> 动态列表视图的解决方案,但我不是作者。
public class CustomPager extends ViewPager
private View mCurrentView;
public CustomPager(Context context)
super(context);
public CustomPager(Context context, AttributeSet attrs)
super(context, attrs);
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
if (mCurrentView == null)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
public void measureCurrentView(View currentView)
mCurrentView = currentView;
this.post(new Runnable()
@Override
public void run()
requestLayout();
);
public int measureFragment(View view)
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
public class MyPagerAdapter extends FragmentPagerAdapter
private List<Fragment> fragments;
private int mCurrentPosition = -1;
public MyPagerAdapter(FragmentManager fm)
super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
this.fragments = new ArrayList<Fragment>();
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
fragments.add(new FourthFragment());
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition)
Fragment fragment = (Fragment) object;
CustomPager pager = (CustomPager) container;
if (fragment != null && fragment.getView() != null)
mCurrentPosition = position;
pager.measureCurrentView(fragment.getView());
@Override
public Fragment getItem(int position)
return fragments.get(position);
@Override
public int getCount()
return fragments.size();
片段布局可以是任何东西
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_
android:orientation="vertical"
android:layout_ tools:context="nevet.me.wcviewpagersample.FirstFragment">
<ListView
android:id="@+id/lv1"
android:layout_
android:layout_
android:background="#991199"/>
</LinearLayout>
然后在某个地方
lv = (ListView) view.findViewById(R.id.lv1);
lv.setAdapter(arrayAdapter);
setListViewHeightBasedOnChildren(lv);
public static void setListViewHeightBasedOnChildren(ListView 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,
LinearLayout.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();
【讨论】:
【参考方案25】:在xml中:
<com.example.util.NestedListView
android:layout_marginTop="10dp"
android:id="@+id/listview"
android:layout_
android:layout_
android:divider="@null"
android:layout_below="@+id/rl_delivery_type" >
</com.example.util.NestedListView>
在 Java 中:
public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener
private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;
public NestedListView(Context context, AttributeSet attrs)
super(context, attrs);
listViewTouchAction = -1;
setOnScrollListener(this);
setOnTouchListener(this);
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE)
if (listViewTouchAction == MotionEvent.ACTION_MOVE)
scrollBy(0, -1);
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY)
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty())
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++)
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup)
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
newHeight += getDividerHeight() * listPosition;
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize))
if (newHeight > heightSize)
newHeight = heightSize;
else
newHeight = getMeasuredHeight();
setMeasuredDimension(getMeasuredWidth(), newHeight);
@Override
public boolean onTouch(View v, MotionEvent event)
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE)
if (listViewTouchAction == MotionEvent.ACTION_MOVE)
scrollBy(0, 1);
return false;
【讨论】:
【参考方案26】:将适配器分配给列表视图后调用此函数
public static void setListViewHeightBasedOnChildren
(ListView 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();
【讨论】:
【参考方案27】:最好的解决方案是在子滚动中添加这个android:nestedScrollingEnabled="true"
属性,例如我已经在我的ListView
中插入了这个属性,它是ScrollView
的子级。我希望这个方法对你有用:-
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_
android:layout_
android:gravity="center"
android:text="TextView"/>
<ListView
android:nestedScrollingEnabled="true" //add this only
android:id="@+id/listView"
android:layout_
android:layout_/>
</LinearLayout>
</ScrollView>
【讨论】:
带有滚动视图的列表视图的最佳解决方案你应该是最好的答案......谢谢【参考方案28】:如果你在 ScrollView 内的 listView 中显示所有项目,请使用此代码
val params: ViewGroup.LayoutParams = listView!!.layoutParams
params.height = useitemsList.size * 200 //add static height
listView!!.layoutParams = params
listView!!.requestLayout()
【讨论】:
【参考方案29】:只需在父滚动视图内的列表视图高度属性中设置所需高度的值。它将与其他父子项一起滚动。
【讨论】:
【参考方案30】:这对我有用(link1,link2):
您创建不可滚动的自定义 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 = View.MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
在您的布局文件中
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:fillViewport="true">
<RelativeLayout
android:layout_
android:layout_ >
<!-- com.Example Changed with your Package name -->
<com.thedeveloperworldisyours.view.NonScrollListView
android:id="@+id/lv_nonscroll_list"
android:layout_
android:layout_ >
</com.thedeveloperworldisyours.view.NonScrollListView>
<RelativeLayout
android:layout_
android:layout_
android:layout_below="@+id/lv_nonscroll_list" >
<!-- Your another layout in scroll view -->
</RelativeLayout>
</RelativeLayout>
</ScrollView>
创建一个你的 customListview 对象而不是 ListView 像:
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);
【讨论】:
以上是关于滚动视图中的 Android 列表视图的主要内容,如果未能解决你的问题,请参考以下文章
使用 Phonegap 将字母滚动条添加到 Android 应用程序中的列表视图