我需要设计一个布局,让整个布局可以滚动,而在里面的布局中,我需要以Grid
形式显示相关内容,所以我决定使用GridView
。但问题在于,我无法在ScrollView
中使用GridView
。我已经阅读了文档(文档也指出我们不应该在ScrollView
中使用GridView
),但我必须这样做,请问有什么好的建议吗?谢谢。
我需要设计一个布局,让整个布局可以滚动,而在里面的布局中,我需要以Grid
形式显示相关内容,所以我决定使用GridView
。但问题在于,我无法在ScrollView
中使用GridView
。我已经阅读了文档(文档也指出我们不应该在ScrollView
中使用GridView
),但我必须这样做,请问有什么好的建议吗?谢谢。
GridView除了内置的滚动功能外,还有许多好处。例如,它可以提供一致的动态布局,根据传递给它的数据而展开或收缩单元格。因此,当有人说不应该渴望这样的功能时,我认为这是错误的,因为你可能希望在可滚动视图中放置包含其他元素的网格视图,但希望整个滚动视图包含的不仅仅是网格单元格。
现在,这里是如何实现这一点的方法。请查看此处的答案。这是一个可扩展高度的GridView,您需要将其导入/创建到项目中。基本上这意味着随着GridView添加更多的项,它将会自动扩展其高度,而不是保持其高度设置并使用滚动条。这正是您所需要的。
一旦您在项目中拥有ExpandableHeightGridView,则可以转到您想要放置GridView的XML布局中。然后您可以像这样操作(简述):
<ScrollView ...>
<RelativeLayout ...>
<com.example.ExpandableHeightGridView ... />
<other view items />
</RelativeLayout>
</ScrollView>
接着,在你设置GridView适配器的Activity中,你需要确保将其设置为可以扩展。因此:
ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
你需要这个可扩展的GridView,因为标准的GridView不会自动扩展,这就导致它会出现滚动条。它会固定一定的高度,然后当更多的项目填充它的视图范围时,它就会变得可滚动。有了这个可扩展的GridView,它将始终扩展其高度以适应其中的内容,从而永远不会进入滚动模式。这使你可以在ScrollView中使用它,并在ScrollView中使用其他视图元素放置在它上面或下面,这些元素都可以滚动。这应该会给你想要的结果。如果你有任何问题,请告诉我。GridView
失去意义。您的应用可能会耗尽内存,性能也会大受影响。解决方案是使用头部或尾部视图,就像普通的ListView
一样。原生的GridView
可能不支持头部或尾部视图,但是有像这个的自定义实现。使用其中一个可以获得相同的效果,而且不会损失视图回收功能。您提出的类似hack的解决方法可以解决问题,但日后只会带来更严重的问题。 - Xaver Kapeller //将ScrollLayout移回顶部,因为扩展GridView会将ScrollView滚动到底部
ScrollView mainScrollView = (ScrollView) rootView.findViewById (R.id.scrollView);
mainScrollView.smoothScrollTo(0,0);
就可以把所有东西放在正确的位置。希望能对某些人有所帮助! - PayToPwn我知道我来晚了,但是我有另外一个解决方案必须分享,而且它可以完美地运行。在这里,该方法根据GridView包含的项目数量计算GridView高度,并在运行时将高度设置为GridView。
public void setGridViewHeightBasedOnChildren(GridView gridView, int columns) {
ListAdapter listAdapter = gridView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int items = listAdapter.getCount();
int rows = 0;
View listItem = listAdapter.getView(0, null, gridView);
listItem.measure(0, 0);
totalHeight = listItem.getMeasuredHeight();
float x = 1;
if( items > columns ){
x = items/columns;
rows = (int) (x + 1);
totalHeight *= rows;
}
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight;
gridView.setLayoutParams(params);
}
在你的GridView上调用了setAdapter
之后,只需调用
setGridViewHeightBasedOnChildren( <yourGridView> , <no of grid view columns> )
然后它就会工作。
您可以像往常一样在xml中定义gridview
让代码来处理它。 :)
我还尝试在NestedScrollView
内部使GridView
可滚动。
这个问题的另一个答案对我有所帮助:https://stackoverflow.com/a/38612612
Enable your GridView Property as
android:nestedScrollingEnabled="true"
Original poster: Droid_Dev
我找到了一种方法来使GridView在ScrollView内部有固定的大小,同时启用滚动。这样可以让您查看整个ScrollView,而不必滚动所有GridView的元素,对我来说这比使用ExpandableHeightGridView更有意义。
为此,您需要实现一个新类来扩展GridView,并覆盖onTouchEvent()以调用requestDisallowInterceptTouchEvent(true)。因此,父视图将离开Grid拦截触摸事件。
GridViewScrollable.java:
package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.GridView;
public class GridViewScrollable extends GridView {
public GridViewAdjuntos(Context context) {
super(context);
}
public GridViewAdjuntos(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent ev){
// Called when a child does not want this parent and its ancestors to intercept touch events.
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
}
}
在ScrollView中添加具有您想要的特性和边距的布局:将其添加到ScrollView中,具有您想要的特性和边距的布局:
```<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="true" >
<com.example.GridViewScrollable
android:id="@+id/myGVS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth" />
</ScrollView>
只需要在您的活动中获取它:
GridViewScrollable myGridView = (GridViewScrollable) findViewById(R.id.myGVS);
希望能帮到你 =)
在 Kotlin 中:
class GridViewScrollable @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : GridView(context, attrs, defStyleAttr) {
override fun onTouchEvent(ev: MotionEvent?): Boolean {
// Called when a child does not want this parent and its ancestors to intercept touch events.
requestDisallowInterceptTouchEvent(true)
return super.onTouchEvent(ev)
}
}
有一个令人讨厌的警告:“Custom view GridViewScrollable覆盖了onTouchEvent但没有performClick”。如果你想的话,请自己解决。
GridViewAdjuntos
? - Ivan如果您使用了dennisdrew的答案,并且在网格上方有内容,在打开视图时会被隐藏,只需添加以下最后一行即可
ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
gridView.setFocusable(false);
最好在scrollview
内使用ExpandableHeightlistView
或ExpandableHeightGridView
。
逻辑
通过提供非常大的高度提示来计算整个高度。但不要使用该整数的最高2位;它们保留用于MeasureSpec模式。
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
如需更多信息,请查看下面的示例和演示
相信这个解决方案对我有用!
gridview中的上述代码使gridview可以滚动,并设置宽度和高度 android:nestedScrollingEnabled="true" android:layout_width="match_parent" android:layout_height="200sp"
即使在scrollview中也可以使用此方法。感谢之前的答案,我从中找到了这个方法。感谢他们。
如果你想在 ScrollView
/ RecyclerView
内部使用 GridView
,有两种情况:
如果你想要所有行都可见的 GridView
,请参见 https://dev59.com/G2oy5IYBdhLWcg3wieq6#63724794。
如果你想要只有一行可见的 GridView
,但仍然能够滚动(以显示其他行),请参见 https://dev59.com/A2cs5IYBdhLWcg3wcDeZ#26852498。