I am developing a chat Android application. Inside the chatRecyclerView i want to show Images along with all other views. However, since i dont know the size of each image i cannot pre-define inside the xml the width-height of the img. If i define those with wrap_content, wrap_content, this makes the recycler scroll without smoothness and also the image to show very big or very small.
I came up with a solution like the below.
<ImageView
android:id="#+id/img_rcv_msg_image_landscape"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="32dp"
android:adjustViewBounds="true"
android:maxWidth="320dp"
android:maxHeight="320dp"
android:minWidth="150dp"
android:minHeight="150dp"
android:scaleType="centerCrop"
android:src="#drawable/error_image"
app:layout_constraintBottom_toBottomOf="#+id/img_frame"
app:layout_constraintEnd_toEndOf="#+id/img_frame"
app:layout_constraintStart_toStartOf="#+id/img_frame"
app:layout_constraintTop_toBottomOf="#+id/img_rcvName"
tools:ignore="ContentDescription" />
<ImageView
android:id="#+id/img_rcv_msg_image_portrait"
android:layout_width="wrap_content"
android:layout_height="280dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="32dp"
android:adjustViewBounds="true"
android:maxWidth="320dp"
android:maxHeight="320dp"
android:minWidth="150dp"
android:minHeight="150dp"
android:scaleType="centerCrop"
android:src="#drawable/error_image"
app:layout_constraintBottom_toBottomOf="#+id/img_frame"
app:layout_constraintEnd_toEndOf="#+id/img_frame"
app:layout_constraintStart_toStartOf="#+id/img_frame"
app:layout_constraintTop_toBottomOf="#+id/img_rcvName"
tools:ignore="ContentDescription" />
I have 2 imageViews. One for the LandScape and one for the Portrait mode. The only data that i have in the ViewHolder is the File of the Image and i dont know which one is the proper image to show.
val file = messageItem.messageItemToFile(itemView.context, it) ?: return#let
//Hide both
imageViewLand.visibility = View.GONE
imageViewPortrait.visibility = View.GONE
Glide
.with(itemView.context)
.load(file)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(
if (file_width > file_height) imageViewLand else imgeViewPortrait)
)
Is there a better solution to come up with??
Related
I have a chat application like whatsapp. I want to show several images that i have in the internal storage. So the only thing that i know for that image is the path that i can find it.
However, in the xml layout of the image_item i must set the width and height of the imageView.
<ImageView
android:id="#+id/rcvImage"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="32dp"
android:adjustViewBounds="true"
android:maxWidth="320dp"
android:maxHeight="320dp"
android:minWidth="150dp"
android:minHeight="150dp"
android:scaleType="centerCrop"
android:src="#drawable/default_img"
tools:ignore="ContentDescription" />
How can i set the values so i can have portrait and landscape images, but without making lags in the recyclerview scrolling
You can set wrap_content and also adjustViewBounds
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/test"/>
Also, scaleType can help with the image resize
android:scaleType="fitStart"
https://developer.android.com/reference/android/widget/ImageView.ScaleType
I've been able to greatly improve my app's performance using Glide, but it means I've had to remove the srcCompat line from the ImageView in the layout xml.
However, this makes designing much harder, because now I can't reference anything in my Design tab when arranging my xml.
Does anyone have a solution to this? Working without being able to see the image in the xml is extremely inconvenient.
Example:
Before using Glide:
in my activity_main.xml:
<ImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:adjustViewBounds="true"
app:layout_constraintEnd_toStartOf="#id/rightNarrowGuideline"
app:layout_constraintStart_toEndOf="#id/leftNarrowGuideline"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/money_coins" />
<Button
android:id="#+id/example"
style="#style/BigRedButton"
android:layout_width="0dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="50dp"
android:text="EXAMPLE"
app:layout_constraintEnd_toEndOf="#id/rightNarrowGuideline"
app:layout_constraintStart_toStartOf="#id/leftNarrowGuideline"
app:layout_constraintTop_toBottomOf="#+id/image" />
and it looks like this in the Design tab.
After using Glide:
Now I load the image in my MainActivity.java with
ImageView mainImage = findViewById(R.id.image);
Glide.with(this).load(R.drawable.money_coins).into(mainImage);
and I've removed this line:
app:srcCompat="#drawable/money_coins"
from my activity_main.xml, so I'm left with this:
<ImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:adjustViewBounds="true"
app:layout_constraintEnd_toStartOf="#id/rightNarrowGuideline"
app:layout_constraintStart_toEndOf="#id/leftNarrowGuideline"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/example"
style="#style/BigRedButton"
android:layout_width="0dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="50dp"
android:text="EXAMPLE"
app:layout_constraintEnd_toEndOf="#id/rightNarrowGuideline"
app:layout_constraintStart_toStartOf="#id/leftNarrowGuideline"
app:layout_constraintTop_toBottomOf="#+id/image" />
And now my Design tab looks like this.
If I understand correctly you want to see your image on preview. Well I guess you could set tools:srcCompat="#drawable/money_coins", which basically sets a "placeholder" image for preview. But by doing this you would need to update drawable on two places.
Dunno exactly if you're also changing your image, but for static image use, directly assigning src in layout should be fine performance wise. Unless your drawable image is like huge. If that is the case you should properly resize it or even better, use vector drawable resource. I'm guessing glide downsamples image for you, hence making it load faster.
Glide's behavior is unpredectable sometimes, while using the app sometimes the ImageView looks like this:
Just going back (to the parent activity) and come back, without restarting the app, to the same movie result, it appears fixed (supposed appearance) like this:
I don't why I have this behavior, here the xml code for the image view:
<ImageView
android:elevation="4dp"
android:src="#drawable/poster_sample"
android:id="#+id/poster_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="24dp"
android:layout_marginStart="14dp"
android:scaleType="centerCrop"/>
Glide code:
Glide
.with(getContext())
.load(mMovieValues.get(MovieContract.MovieEntry.COL_POSTER_URL))
.centerCrop()
.into(mPoster);
Where is the problem? and how to fix that?
You should give a fixed height and width to your ImageView and no need to use centerCrop
<ImageView
android:elevation="4dp"
android:src="#drawable/poster_sample"
android:id="#+id/poster_image"
android:layout_width="250dp"
android:layout_height="150dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="24dp"
android:layout_marginStart="14dp"/>
and remove CenterCrop from here too
Glide
.with(getContext())
.load(mMovieValues.get(MovieContract.MovieEntry.COL_POSTER_URL))
.into(mPoster);
I have to take a picture in my App. After take it , I have to show it in a ImageView, so I decided to use Glide as library to handle it.
I have set the code like this:
Glide.with(this)
.load(mLastPhoto)
.fitCenter()
.centerCrop()
.into(iv_circ_image);
and the xml file looks like:
<ImageView
android:id="#+id/circ_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bTakePicture"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="12dp"
android:src="#drawable/ab_background_textured_" />
But when the phot has been taken, the image is shown like this:
How I have to set the Glide code or the XML to show all the image?
Add the android:adjustViewBounds="true" attribute to your ImageView. Set this to true if you want the ImageView to adjust its bounds to preserve the aspect ratio of its drawable (from API-Documentation http://developer.android.com/reference/android/widget/ImageView.html).
<ImageView
android:adjustViewBounds="true"
android:id="#+id/circ_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bTakePicture"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="12dp"
android:src="#drawable/ab_background_textured_" />
In the xml you have android:layout_height="wrap_content" and android:layout_marginTop="12dp"
Then in the java you have .fitCenter().centerCrop().
So basically you have a 12dp image view that Glide is filling. I suggest you set the height of the image view (ie 200dp) or have the buttons stick to the bottom of the screen and have the imageview fill the available space between them.
I have an image picker application that selects images from gallery. If the image doesn't have a particular width/height ratio I display a small warning symbol on top of the image.
In my XML View File I have two ImageView views. It is below:
view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp" >
<ImageView
android:id="#+id/imgQueue"
android:layout_width="70dp"
android:layout_height="70dp"
android:scaleType="centerCrop" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:id="#+id/wrongimagesign"
android:src="#drawable/error"
android:layout_alignTop="#+id/imgQueue"
android:layout_alignRight="#+id/imgQueue"
android:layout_alignEnd="#+id/imgQueue"
android:visibility="invisible"/>
</RelativeLayout>
The images are displayed in a gridview so in my adapter i have this code:
ImageLoader.getInstance().displayImage("file://" + image.cardPath, imgQueue);
**Bitmap bitmap = ImageLoader.getInstance().loadImageSync("file://" + image.cardPath, Utility.displayImageOptions);**
wrongImageSign.setVisibility(imageRatioIsBad(bitmap) ? View.VISIBLE : View.INVISIBLE);
The problem is that since i am loading the bitmap the performance is very slow (it takes too long to load the image and display the warning sign). Is there a way to improve the performance.