📅  最后修改于: 2023-12-03 14:58:47.930000             🧑  作者: Mango
当我们使用 GridView 来展示数据时,通常会设置一个固定的高度,以限制显示的行数。但如果我们将垂直视口(即 GridView 内容的容器)设置为无限高度,同时在 GridView 内部加入一个能够自适应高度的子控件,那么就可以达到颤动效果。
首先,我们需要将 GridView 的垂直视口高度设置为无限。
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="3"
android:verticalSpacing="8dp"
android:horizontalSpacing="8dp"
android:stretchMode="columnWidth"
android:clipToPadding="false"
android:padding="8dp"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="vertical"
android:overScrollMode="never"
android:layout_marginTop="8dp" />
注意,我们需要设置 android:layout_height="wrap_content"
,而非具体的数值。
接着,我们需要加入一个能够自适应高度的子控件,例如 LinearLayout。
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="3"
android:verticalSpacing="8dp"
android:horizontalSpacing="8dp"
android:stretchMode="columnWidth"
android:clipToPadding="false"
android:padding="8dp"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="vertical"
android:overScrollMode="never"
android:layout_marginTop="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- GridItem -->
</LinearLayout>
</GridView>
注意,我们需要将 LinearLayout 的高度设置为 wrap_content。
接下来,在 GridView 的 Adapter 中,我们需要在 getView 方法中获取 LinearLayout,然后根据子视图数量以及列数来动态设置 LinearLayout 的高度。具体方法如下:
public View getView(int position, View convertView, ViewGroup parent) {
// 省略其他代码...
LinearLayout linearLayout = convertView.findViewById(R.id.layoutGridItem);
linearLayout.removeAllViews();
// 往 LinearLayout 中添加子视图...
int columnCount = 3; // 列数
int rowCount = (int) Math.ceil((double) data.size() / columnCount); // 行数
int verticalSpacing = (int) getResources().getDimension(R.dimen.grid_spacing_vertical);
int totalHeight = (gridView.getWidth() - gridView.getPaddingLeft() - gridView.getPaddingRight()) / columnCount * rowCount + verticalSpacing * (rowCount - 1);
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, totalHeight);
linearLayout.setLayoutParams(layoutParams);
return convertView;
}
需要注意的是,在计算 totalHeight 时,我们需要先得到 GridView 的宽度,并减去左右 padding 的值,再计算出每个格子的宽度,从而得到整个 GridView 的总高度。
最后,我们可以在 GridView 上覆盖一个与其高度相等、背景透明的 View,从而达到颤动效果。
<View
android:id="@+id/shimmerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/gridView"
android:layout_alignParentBottom="true"
android:background="@android:color/transparent" />
以上便是如何实现颤动 GridView 的方法,通过设置无限高度,以及动态设置子视图的宽高,我们可以轻松实现这一效果。