简体   繁体   中英

set recyclerView item height wrap_content

I'm loading images into recyclerview item(imageview) from firebase. All images are of different dimensions.

I want my imageview to scale its height according the image i'm loading.

Main layout.xml

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimaryDark"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/RecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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


</android.support.constraint.ConstraintLayout>

row.xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    >


        <ImageView
            android:id="@+id/ImageView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />


</LinearLayout>

In java i'm doing.

RecyclerView.setHasFixedSize(true);
       RecyclerView.setLayoutManager(new LinearLayoutManager(mctx));

Also when I scroll recyclerview it changes the image height

output

then I scrolled up and down, and see the height. Scrolled up/down output

third time, again scrolled and worst output

Please help me.. Thanks a lot..

Set adjustViewBounds to true in Image view that you are using in row.xml like this:

<ImageView
    android:id="@+id/ImageView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:src="@drawable/img"/>

By adding adjustViewBounds and leaving the layout_height as wrap_content we are keeping the aspect ratio of the image while keeping the width to match parent but letting the height change accordingly, so we are still able to control the size of the image (kind of) and maintaining the aspect ratio at the same time.

You can also set staggered grid layout manager in recyler view to have different item size.

recyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, 1)); //First param to set span count and second for orientation

try this below code

        <?xml version="1.0" encoding="utf-8"?>
        <android.support.constraint.ConstraintLayout  
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/rootLayout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         xmlns:tools="http://schemas.android.com/tools">


                <ImageView
                    android:id="@+id/ImageView"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintDimensionRatio="H,16:5" />


        </android.support.constraint.ConstraintLayout >

If you set

app:layout_constraintDimensionRatio="H,16:5"

then it means width will be first computed from other constraints and then height will be adjusted according to the aspect ratio.To constraint one specific side based on the dimensions of another , we can preappend W or H (to the ratio separated by a comma), to constraint the width or height respectively. For example, If one dimension is constrained by two targets (eg width is 0dp and centered on parent) you can indicate which side should be constrained, by adding the letter W(for constraining the width) or H(for constraining the height) in front of the ratio, separated by a comma.

  • 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" />

both will solve your problem but both of them are only recommend if you have small amount of data to populate, these tricks are not recommended for thousands of images, as this will calculate and set height of each item at run time which means this will run on main thread and for thousands of images this will create a laggy scrolling and may result in ANR on low end devices.

There is another work around to minimize this lag.

You can get the width of the imageView at runtime in onBindViewHolder and set the height equals to width or any multiple of width to attain your desired ratio.

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

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

Getting the width at background thread will take the load off of Main thread which ultimately results in smooth scrolling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM