RecyclerView项的高度和宽度如何在Android中动态更改

30

我刚刚接触安卓开发,正在开发一个应用程序,该应用程序从服务器下载图片并在网格视图中显示这些图片。但是,当在更大的屏幕手机上运行应用时,会出现一些额外的空白。以下是一些屏幕截图。我该如何解决?每个项目的模型都具有固定的高度和宽度,为110dp。

我的图片模型:

<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="110dp"
    android:layout_height="110dp"
    app:srcCompat="@drawable/post2"
    android:id="@+id/imageView2"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop"
    android:layout_margin="1.5dp" />

我的 RecyclerView:

<android.support.v7.widget.RecyclerView
                android:id="@+id/gallerygrid"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="4dp"
                android:numColumns="auto_fit"
                android:stretchMode="columnWidth"
                android:visibility="visible"
                android:layout_gravity="center">

            </android.support.v7.widget.RecyclerView>

小屏幕手机上的图像

大屏幕手机上的图像


展示你的 XML 文件。 - Piyush
1
需要为更大的屏幕手机创建一个XML布局。 - Dileep Patel
我刚刚发布了代码。 - Shakil Mahmud Shanto
如果您的高度是固定的,请同时计算保持宽高比或设置为全宽。 - Piyush
@ShakilMahmudShanto,请检查我下面的答案,它可以帮助你,并在所有设备上给出正确的结果。 - Zaki Pathan
4个回答

58

根据屏幕大小动态设置高度和宽度是获得完美结果的最佳方式。

DisplayMetrics displaymetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        //if you need three fix imageview in width
        int devicewidth = displaymetrics.widthPixels / 3;

        //if you need 4-5-6 anything fix imageview in height
        int deviceheight = displaymetrics.heightPixels / 4;

        holder.image_view.getLayoutParams().width = devicewidth;

        //if you need same height as width you can set devicewidth in holder.image_view.getLayoutParams().height
        holder.image_view.getLayoutParams().height = deviceheight;

尝试在适配器中使用getview,在所有设备上获得更好的结果。

EDIT: 或者,您可以像下面这样将设备宽度也设置为高度,以使高度与宽度相同:

holder.image_view.getLayoutParams().height = devicewidth;

如果您在上面的代码中遇到任何问题,请随时提问 :) :) - Zaki Pathan
我在两个活动中使用我的recyclerView来表示(垂直和水平)。我可以在活动中使用这段代码而不是适配器吗? - roghayeh hosseini
@ZakiPathan,您是不是想把这段代码放在onBindViewHolder而不是getView中? - makkhay gurung
如果RecyclerView不占据整个屏幕,那么它将无法正常工作。如果RecyclerView仅占据屏幕宽度的30%和屏幕高度的40%(例如),该怎么办? - Tapa Save

24

对于那些想在xml布局(recyclerView项目)文件中执行此操作的人,可以使用ConstraintLayout组合。

            android:layout_width="match_parent"
            android:layout_height="wrap_content"

以下是创建正方形元素的代码:

            app:layout_constraintDimensionRatio="4:4"

不要忘记提供所有的限制条件,这样你就可以设置。

            android:layout_width="0dp"
            android:layout_height="0dp"

因此,完整代码将如下所示。
<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="1dp"
        android:layout_marginEnd="1dp"
        >

        <ImageView
            android:id="@+id/img_view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="1dp"
            android:layout_marginBottom="1dp"
            app:layout_constraintDimensionRatio="4:4"
            app:srcCompat="@drawable/event_placeholder"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:scaleType="centerCrop"
            />
</androidx.constraintlayout.widget.ConstraintLayout>

1
谢谢,这在使用android.support.constraint.ConstraintLayout也可以正常工作。 - svenmeier

1

1
  • If you are using Constraint layout use constraint Dimens ratio as mentioned above.

    <ImageView
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     app:layout_constraintDimensionRatio="1:1"/>
    
  • else if you are using linear or relative layout.

    <ImageView
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:adjustViewBounds="true" />
    

两种方法都可以解决您的问题,但如果要填充大量数据,则不建议使用这些技巧,因为这将在运行时计算并设置每个项的高度,这意味着此过程将在主线程上运行,并且对于数千张图片,这将导致滚动变得缓慢并可能在低端设备上导致ANR。

还有另一种方法可以最小化这种滞后。

您可以在onBindViewHolder中在运行时获取imageView的宽度,并将高度设置为宽度或宽度的任何倍数,以达到所需的比例。

 CoroutineScope(Dispatchers.IO).launch {
      val width = holder.image.width

      withContext(Dispatchers.Main){
           holder.image.layoutParams.height = width
      }
  }

在后台线程获取宽度将减轻主线程的负担,从而实现平滑滚动。


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