Reputation: 159
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
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..
Upvotes: 2
Views: 4212
Reputation: 469
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.
Upvotes: 0
Reputation: 397
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 (e.g. 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.
Upvotes: 1
Reputation: 548
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
Upvotes: 4