GridView - 有时候行顶部对齐,有时候行底部对齐!

24

我正在使用GridView,每列有四个项目。每个元素由以下布局组成:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="vertical">

  <ImageView
    android:layout_width="32dip"
    android:layout_height="32dip"/>

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="11dip"
    android:paddingTop="2dip" />
</LinearLayout>

因此,每个元素都是一个带有一些文本的小图像。布局在第一次通过时效果很好。然而,如果某个项目的文本很长,则会换行成两行。这还可以,直到你将其滚动进入和滚动出视图。默认情况下,一行中的所有图像都是顶部对齐的。当你将一行滚动到屏幕外,然后再次滚动回屏幕上时,你会看到该行以某种方式变为底部对齐。它看起来像:

第一个布局:

[image]   [image]   [image]  
[text]    [text]    [text
                     wrap]

即使第三个元素有2行文本,它们的顶部对齐,这很完美。如果我将此行滚动到屏幕外,然后再次滚动回来,它看起来像这样:

                    [image]
[image]   [image]   [text
[text]    [text]     wrap]

所以在这里行底部对齐了。我不确定这是否是GridView中的一个错误,或者是否有某种控制布局始终顶部对齐行的方法。我尝试将元素布局的重力设置为"top",但没用。似乎也没有任何GridView特有的设置来控制这个问题。有什么建议吗?

谢谢


我现在能想到的做法就是将所有字符串添加空格,使其长度等于数据集中最长的字符串。由于字体是等宽的(我认为),所以一切应该再次正确地顶部对齐。这真是疯狂! - user291701
请分享答案,如果您已经找到的话。 - PiyushMishra
@user291701,你有没有找到答案?我自己也很苦恼这个问题。 - Russ Wheeler
4个回答

14

GridView中的项目高度必须相同。您有2或3个选择。

  1. 给TextView设置高度
  2. 使用android:singleLine="true"使TextView单行显示
  3. 如果某些项目必须包含2行,则使所有项目都包含2行,可以使用android:minLines="2"

谢谢。很好的解释。对我帮助很大。 - Roger Garzon Nieto
@RogerGarzonNieto,你最终采取了什么措施?我真的不想每次都强制我的TextView有两行。我相信让GridView中的每个子项都顶部对齐应该很简单。 - Russ Wheeler
1
您也可以简单地使用android:lines="2"。这将防止可能出现的问题,如果其中一个项目超过2行(将被截断,但这是另一个问题!)。 - SMBiggs
minLines = 2 不起作用。我明白你说的,但它不起作用。 - M. Usman Khan
即使对于2行,固定高度也会导致不对齐。 - M. Usman Khan
最小行数应该只在TextView上可用。您是否正在使用TextView? - tasomaniac

0

有些设备与样式不兼容。

    grid.setColumnWidth(90);
    grid.setNumColumns(GridView.AUTO_FIT);
    grid.setVerticalSpacing(10);
    grid.setHorizontalSpacing(10);
    grid.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
    grid.setGravity(Gravity.CENTER);
    grid.setOnItemClickListener(this);

<style name="GridViewStyle" parent="@android:style/Widget.GridView">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">fill_parent</item>
        <item name="android:columnWidth">90dp</item>
        <item name="android:numColumns">auto_fit</item>
        <item name="android:verticalSpacing">10dp</item>
        <item name="android:horizontalSpacing">10dp</item>
        <item name="android:stretchMode">columnWidth</item>
        <item name="android:gravity">center</item>
    </style>

// 看看我的适配器如何返回TextView
// 我遇到了一些问题,你只需要刷新适配器(在onResume或方向更改时)

public View getView(final int position, View convertView, ViewGroup parent) {
        if (convertView!=null) return convertView;

        Intent intent = (Intent) getItem(position);
        TextView tv = new TextView(mContext);
        tv.setGravity(Gravity.CENTER_HORIZONTAL);
        tv.setText(intent.getStringExtra("text"));

        try {
            tv.setCompoundDrawablesWithIntrinsicBounds(null, mContext.getPackageManager().getActivityIcon(intent), null, null);
        } catch (NameNotFoundException e) {
            tv.setCompoundDrawablesWithIntrinsicBounds(0, android.R.drawable.ic_secure, 0, 0);
        }

        return tv;
    }

0
如果您正在使用 getview 方法,您可以动态设置其高度/宽度,无需将所有元素设置为相同大小。它会自动从中心动态裁剪图像。
 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView = new ImageView(mContext);
        imageView.setImageResource(mThumbIds[position]);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); //it will crop the image from center
        imageView.setLayoutParams(new GridView.LayoutParams(70, 70));
        return imageView;
    }

同时设置您在 XML 中想要的列数

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/grid_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:numColumns="2"          // set the number of coloums
    android:columnWidth="90dp"
    android:horizontalSpacing="10dp"
    android:verticalSpacing="10dp"
    android:gravity="center"
    android:stretchMode="columnWidth" >  
</GridView>

0
尝试在你的LinearLayout中使用android:layout_gravity="top"。
此外,如果您手动填充单元格的布局,请确保使用以GridView作为第二个参数并将第三个参数设置为false的inflate()版本。

啊,两种方法都没成功。当滚动回到视图时,该行仍然底部对齐。 - user291701
另一件事是,当向上或向下滚动时,滚动条的计算会出现问题 - GridView 突然会让你无限滚动,所以最终你只能看到一个空白画布。在那个点尝试向后滚动会失败。这真的是一种奇怪的行为,我认为这是 GridView 内部的一个 bug。 - user291701
如果您认为这是一个错误,请创建一个演示该行为的示例项目,并在http://b.android.com上发布带有说明的内容。如果您想到了,可以在此处添加问题链接。 - CommonsWare
4
好的,我会翻译。目前我只是将textview::lines设置为2。这样可以使每个元素具有相同的高度,似乎很有效。 - user291701
我也遇到了你提到的屏幕在向上/向下滚动时变空白的问题。我通过在网格适配器中添加一个视图持有者来修复它。 - omega
我认为每当一个GridView的视图中textView有x行文本,而右侧的视图中textView只有x-1行文本时,就会出现这种情况。它能够正常工作的原因是你已经设置了确切的行数。 - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接