我正在尝试创建一个包含文字和图片的屏幕。我希望图像像网格一样布局,如下所示,但我希望它们没有周围ScrollView提供的滚动功能。
图片最能说明我的问题:
<ScrollView>
<LinearLayout>
<ImageView />
<TextView />
<GridView />
<TextView />
</LinearLayout>
</ScrollView>
显示不同数量图像的网格的最佳方法是什么,网格没有滚动功能?
请注意,禁用GridView的滚动功能不起作用,因为这只会禁用滚动条但不会显示所有项目。
更新: 下图显示了在GridView中禁用滚动条的情况。
答案 0 :(得分:186)
尽管如此,你可以解决这个问题,或者创建自己的布局以满足您的需求,而不会有太多困难。我能想到两个可能性:
在我自己的应用程序中,我在ScrollView中嵌入了ListView。我通过明确告诉ListView与其内容完全一样高来完成此操作。我是通过在ListView.onMeasure()
方法中更改布局参数来实现的,如下所示:
public class ExpandableListView extends ListView {
boolean expanded = false;
public ExpandableListView(Context context, AttributeSet attrs, int defaultStyle) {
super(context, attrs, defaultStyle);
}
public boolean isExpanded() {
return expanded;
}
public void setExpanded(boolean expanded) {
this.expanded = 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.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
这是有效的,因为当您为ListView提供AT_MOST
模式时,它会在onMeasure
方法内部为您创建并测量其所有子项(我通过浏览源代码发现了这一点) )。希望GridView的行为相同,但如果没有,您仍然可以自己测量GridView的所有内容。但如果你能欺骗GridView为你做这件事会更容易。
现在,您必须记住,此解决方案将完全禁用视图回收,使GridView如此高效,并且即使它们不可见,所有这些ImageView也将在内存中。我的下一个解决方案也是如此。
另一种可能性是抛弃GridView并创建自己的布局。您可以延长AbsoluteLayout
或RelativeLayout
。例如,如果您展开RelativeLayout
,则可以将每个图像LEFT_OF
放在前一个图像上,跟踪每个图像的宽度,直到该行用完房间,然后开始下一行通过将新行BELOW
的第一张图像放在最后一行的最高图像上。要使图像水平居中或在等间距列中,您将不得不经历更多的痛苦。也许AbsoluteLayout更好。无论哪种方式,都是一种痛苦。
答案 1 :(得分:4)
可以使用带有页眉和页脚的GridView,而不是尝试在ScrollView中嵌入GridView。页眉和页脚可以是任何内容 - 文本,图像,列表等。有一个带页眉和页脚的GridView示例:https://github.com/SergeyBurish/HFGridView
答案 2 :(得分:3)
你有两个解决方案:
编写自己的自定义布局。这将是更难的解决方案(但可能被认为是正确的解决方案)。
在代码中设置GridView
的实际高度。例如:
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) myGridView.getLayoutParams(); // lp.setMargins(0, 0, 10, 10); // if you have layout margins, you have to set them too lp.height = measureRealHeight(...); myGridView.setLayoutParams(lp);
measureRealHeight()
方法看起来应该是这样的(希望我做对了):
private int measureRealHeight(...)
{
final int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
final double screenDensity = getResources().getDisplayMetrics().density;
final int paddingLeft = (int) (X * screenDensity + 0.5f); // where X is your desired padding
final int paddingRight = ...;
final int horizontalSpacing = (int) (X * screenDensity + 0.5f); // the spacing between your columns
final int verticalSpacing = ...; // the spacing between your rows
final int columnWidth = (int) (X * screenDensity + 0.5f);
final int columnsCount = (screenWidth - paddingLeft - paddingRight + horizontalSpacing - myGridView.getVerticalScrollbarWidth()) / (columnWidth + horizontalSpacing);
final int rowsCount = picsCount / columnsCount + (picsCount % columnsCount == 0 ? 0 : 1);
return columnWidth * rowsCount + verticalSpacing * (rowsCount - 1);
}
以上代码应该适用于Android 1.5 +。
答案 3 :(得分:2)
创建一个不可滚动的列表视图,如下所示:
public class ExpandableListView extends ListView{
public ExpandableListView(Context context) {
super(context);
}
public ExpandableListView(Context context, AttributeSet attrs, int defaultStyle) {
super(context, attrs, defaultStyle);
}
public ExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@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();
}
}
在你的布局文件中创建一个这样的元素:
<com.example.ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
这应该有用。
答案 4 :(得分:1)
我找到了一种在ScrollView中为GridView提供固定大小的方法,并可以滚动它。
为此,您必须实现一个扩展GridView的新类,并重写onTouchEvent()以调用requestDisallowInterceptTouchEvent(true)。 因此,父视图将使网格拦截触摸事件。
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 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:clickable="true"
android:numColumns="auto_fit"
android:columnWidth="100dp"
android:stretchMode="columnWidth" />
</ScrollView>
只需在您的活动中获取并设置适配器,例如 ArrayAdapter&lt;&gt; :
GridViewScrollable mGridView = (GridViewScrollable) findViewById(R.id.myGVS);
mGridView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{"one", "two", "three", "four", "five"}));
我希望它有帮助=)
答案 5 :(得分:0)
试试这个
public interface UserRepository extends CrudRepository<User,Integer>
答案 6 :(得分:0)
对于GridView与保存ScrollView内的其他View以使其全部滚动,请转到此链接:http://www.londatiga.net/it/programming/android/make-android-listview-gridview-expandable-inside-scrollview/#comment-3967742。这是有帮助的,并节省了我的时间,我只花了5分钟,当我从来不知道它。
更新
从链接我自定义ExpandedGridView:
public class ExpandedGridView extends GridView {
boolean expanded = false;
public ExpandedGridView(Context context) {
super(context);
}
public ExpandedGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandedGridView(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从GridView更改为已定制的ExpandedGridView。
<com.your.package.ExpandedGridView
android:id="@+id/home_screen_list_goals"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2" />
用法:
在您的活动中调用它。如果在片段中使用contentView.findViewById(...)
。哪个contentView是您定义的整个布局。
ExpandedGridView gridView = (ExpandedGridView) findViewById(R.id.home_screen_list_goals);
//set data into grid view
gridView.setAdapter(YOUR_ADAPTER_OBJECT);
gridView.setExpanded(true);