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 have an image in my ConstraintLayout that I want to resize according to different screen sizes.
It is fine with large screens, but not with small ones.
Here is my image view
<ImageView
android:id="#+id/iv_app_image_start_screen_fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:src="#drawable/my_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
Try with the following property of Imageview
android:scaleType="fitXY"
They key to do that is to use percentages instead of defined widths or height. So that as per different screen sizes, it can adjust.
The property for that is app:layout_constraintDimensionRatio, so you will have to modify your current layout as follows
<ImageView
android:id="#+id/iv_app_image_start_screen_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:layout_marginTop="32dp"
app:layout_constraintDimensionRatio="1"
android:src="#drawable/my_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
Note we have made both width and height as 0dp and as you can see the dimension ratio is 1 which mean for now width is equal to height.
You can adjust the dimension ratio as per your need and can read more about it here.
I have the following layout:
As you can see, the image is constraint and has the scale type fitXY. I've customized his size using percentage as you can see on the following code:
<ImageView
app:layout_constraintHeight_percent="0.3" app:layout_constraintWidth_percent="0.3"
android:layout_width="0dp"
android:layout_height="0dp" tools:src="#tools:sample/avatars"
android:id="#+id/book_image"
app:srcCompat="#mipmap/ic_launcher_round" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="16dp" app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="16dp"
android:contentDescription="#string/text_view_default" android:scaleType="fitXY"/>
But this is the result that I obtain when executing:
Why is changing the size?
EDIT:
I've seen that in some books the text of the description exceeds the limit of the screen, so you can scroll and I understand that the percentage I'm setting is for the whole view, not just the visible piece.
How can I fix it?
That's happening because you are setting your layout_height and layout_width properties to be 0dp. Doing this will tell the view that it should stretch as much as it can. You should be using wrap_content or even a fixed size if all of your images should look the same (dimensions).
Is it possible to achieve negative margin on constraint layout to achieve overlap?
I am trying to have a image centered on the layout and have a Text view such that it overlaps a by x dp. I tried setting negative margin value but no luck.
It would be great if there is a way to achieve this.
Update
ConstraintLayout now supports negative margins with version 2.1.0-alpha2. Simply state
android:layout_marginTop="-25dp"
for a negative 25dp margin. (This will only work if the top of the view is constrained. A margin has no effect in ConstraintLayout if the margin's side is not constrained.)
Clarification: The answer below remains valid, but I want to clarify a couple of things. The original solution will place a view with a de facto negative offset with respect to another view as stated and will appear in the layout as shown.
Another solution is to use the translationY property as suggested by Amir Khorsandi here. I prefer that solution as simpler with one caveat: The translation occurs post-layout, so views that are constrained to the displaced view will not follow the translation.
For example, the following XML displays two TextViews immediately below the image. Each view is constrained top-to-bottom with the view that appears immediately above it.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="150dp"
android:layout_height="150dp"
android:tint="#388E3C"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_action_droid" />
<TextView
android:id="#+id/sayName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say my name."
android:textAppearance="#style/TextAppearance.AppCompat.Large"
app:layout_constraintTop_toBottomOf="#+id/imageView"
app:layout_constraintEnd_toEndOf="#+id/imageView"
app:layout_constraintStart_toStartOf="#+id/imageView" />
<TextView
android:id="#+id/sayIt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say it."
android:textAppearance="#style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="#+id/sayName"
app:layout_constraintStart_toStartOf="#+id/sayName"
app:layout_constraintTop_toBottomOf="#id/sayName" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now, let's translate the "Say my name" TextView up by 50dp by specifying
android:translationY="-50dp"
This produces the following:
The "Say my name" TextView has shifted up as expected, but the "Say it" TextView has not followed it up as we might expect. This is because the translation occurs post-layout. Although the view moves post-layout, it can still be made clickable in the new position.
So, IMO, go with translationX and translationY for negative margins in ConstraintLayout if the caveat above doesn't affect your layout; otherwise, go with the space widget as outlined below.
Another caveat: As stated by Salam El-Banna in a comment to another answer, translationX will not be a good solution for RTL layouts since the sign of the translation will dictate the direction of the shift (left/right) regardless of the RTL or LTR nature of the layout.
Original answer
Although it doesn't appear that negative margins will be supported in ConstraintLayout, there is a way to accomplish the effect using the tools that are available and supported. Here is an image where the image title is overlapped 22dp from the bottom of the image - effectively a -22dp margin:
This was accomplished by using a Space widget with a bottom margin equal to the offset that you want. The Space widget then has its bottom constrained to the bottom of the ImageView. Now all you need to do is to constrain the top of the TextView with the image title to the bottom of the Space widget. The TextView will be positioned at the bottom of the Space view ignoring the margin that was set.
The following is the XML that accomplishes this effect. I will note that I use Space because it is lightweight and intended for this type of use, but I could have used another type of View and made it invisible. (You will probably need to make adjustments, though.) You could also define a View with zero margins and the height of the inset margin you want, and constrain the top of the TextView to the top of the inset View.
Yet another approach would be to overlay the TextView on top of the ImageView by aligning tops/bottoms/lefts/right and make suitable adjustments to margins/padding. The benefit of the approach demonstrated below is that a negative margin can be created without a lot of computation. That is all to say that there are several ways to approach this.
Update: For a quick discussion and demo of this technique, see the Google Developers Medium blog post.
Negative Margin for ConstraintLayout XML
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<android.support.v4.widget.Space
android:id="#+id/marginSpacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="22dp"
app:layout_constraintBottom_toBottomOf="#+id/imageView"
app:layout_constraintLeft_toLeftOf="#id/imageView"
app:layout_constraintRight_toRightOf="#id/imageView" />
<TextView
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say my name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/marginSpacer" />
</android.support.constraint.ConstraintLayout>
Another way is using translationX or translationY like this:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:translationX="25dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
it will work like android:layout_marginRight="-25dp"
Negative margins have never been officially supported in RelativeLayout. Negative margins will not be supported in ConstraintLayout. [...]
-- Romain Guy on Jun 8, 2016
Follow these two issues:
https://code.google.com/p/android/issues/detail?id=212499
https://code.google.com/p/android/issues/detail?id=234866
This is what I figured out after hours of trying to find a solution.
Let us consider two images, image1 and image2. Image2 is to be placed on top of image1 positioned to the bottom-right side.
Overlapping Views Example
We can use Space widget for overlapping views.
Constraint the Space widget's four sides with the four sides of the image1 respectively. For this example, constraint the image2's left side with the Space widget's right side and the image2's top side with the Space widget's bottom side. This will tie image2 with the Space widget and since the Space widget is constrained from all the sides, we can define required horizontal or vertical bias which will move image2 as required.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Player">
<ImageView
android:id="#+id/image1"
android:layout_width="250dp"
android:layout_height="167dp"
android:src="#android:color/holo_green_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Space
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#+id/image1"
app:layout_constraintEnd_toEndOf="#+id/image1"
app:layout_constraintHorizontal_bias="0.82"
app:layout_constraintStart_toStartOf="#+id/image1"
app:layout_constraintTop_toTopOf="#+id/image1"
app:layout_constraintVertical_bias="0.62" />
<ImageView
android:id="#+id/image2"
android:layout_width="82dp"
android:layout_height="108dp"
android:src="#android:color/holo_green_light"
app:layout_constraintStart_toEndOf="#+id/space"
app:layout_constraintTop_toBottomOf="#+id/space" />
</android.support.constraint.ConstraintLayout>
Additionally, to position image2 on the center-bottom of image1, we can constraint image2's left and right sides with Space widget's left and right sides respectively. Similarly, we can place image2 anywhere by changing image2's constraints with Space widget.
I found a way to do it much simpler.
Basically have the ImageView, then on the Text View add top constraint to match the top constraint of the image and just add the margin top of the TextView to match to achieve the -ve margin type behavior.
This will help many
In my case i want my design like this:
Means i want my image is display half of their width so the basically i need negative margin of half of the actual image width but my whole layout in constraint layout and constraint layout does not allowed negative margin so i achieved this with below code
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/ic_launcher_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="50dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
So that ImageView will end at the starting of the guideline. and the effect is same as like negative margin at the start of 50dp.
And also if your view's width is not fixed and it's in percentage so that you can place guideline with percentage and achieve whatever effect you want
Happy Coding:)
You only need to use Space widget in your layout
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Space
android:id="#+id/negative_margin"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="parent"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Widget who needs negative margin"
app:layout_constraintTop_toBottomOf="#+id/negative_margin"
app:layout_constraintLeft_toLeftOf="#+id/negative_margin" />
Place Background View Behind Subject View
I wanted to use negative margin to add a view behind a subject view that is proportionally bigger than the subject view. The solution I found was to scale android:scaleX="1.2" and android:scaleY="1.2" the background view while constraining it to all sides of the subject.
<View
android:id="#+id/subjectBackground"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleY="1.2"
android:scaleX="1.2"
app:layout_constraintBottom_toBottomOf="#+id/subjectView"
app:layout_constraintEnd_toEndOf="#+id/subjectView"
app:layout_constraintStart_toStartOf="#+id/subjectView"
app:layout_constraintTop_toTopOf="#+id/subjectView" />
This is an old question yet very much asked, the fastest way to achieve this is by constraining the top and bottom to the side of the view you want to anchor to, like so:
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="55dp"
android:layout_height="55dp"
app:layout_constraintBottom_toBottomOf="#+id/parent_view_id"
app:layout_constraintTop_toBottomOf="#+id/parent_view_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
This will center it in the bottom line of the view, centered horizontally.
One can try this way, this is much simpler
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MyProfileFragment">
<ImageView
android:id="#+id/imageViewUserPic"
android:layout_width="#dimen/dp60"
android:src="#mipmap/ic_launcher"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_margin="20dp"
android:layout_height="wrap_content">
</ImageView>
<ImageView
android:id="#+id/imageViewEdit"
app:layout_constraintBottom_toBottomOf="#+id/imageViewUserPic"
android:src="#drawable/ic_edit_red_round"
app:layout_constraintEnd_toEndOf="#+id/imageViewUserPic"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>
The layout will be like this..
this is my soluation
<com.oven.test.avatar
android:id="#+id/imageview_a"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginTop="28dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.oven.test.smallicon
android:id="#+id/small_icon_overlap_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/imageview_a"
app:layout_constraintTop_toTopOf="#+id/imageview_a"
app:layout_constraintVertical_bias="1"
android:layout_marginBottom="20dp"/>
Using translationX and translationY may works for your situation.
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
android:translationX="-15dp"
android:translationY="10dp"
app:layout_constraintEnd_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="#+id/imageView" />
A Simple Way.
I'm not sure best way.
Just wrap using LinearLayout
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<View
android:layout_width="wrap_content"
android:layout_marginLeft="-20dp"
android:layout_height="wrap_content"/>
</LinearLayout>
I have an ImageView which needs to have a maximum height of 150dp and a width that matches the parent. However, what I need is for the actual image to be cropped, so the picture is as wide as the ImageView, but centered and cropped so the top and bottom of the picture aren't visible (sort of a preview). What I have currently:
<ImageView
android:adjustViewBounds="true"
android:background="#fafafa"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxHeight="150dp"
android:id="#+id/articlepreviewimage"
android:src="#mipmap/ic_launcher"
android:layout_below="#+id/naslovclanka"
android:layout_centerHorizontal="true"
/>
Also, it's crucial that the image stays in its' original proportions, so no putting it as background, no scaling etc. I just need it to fill up the width of the ImageView and show the center of the picture in that ImageView.
The way its' currently done, it scales the image so it fits into the height or width, but doesn't cut away anything. How to do this?
take a look at android:scaleType="centerCrop"
There are also a lot of other scale types that might fit what you what.
Try doing the following:
<ImageView
android:id="#+id/yourimageId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:adjustViewBounds="true"
android:layout_gravity="center_vertical"
android:clickable="true"
android:scaleType="fitXY"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:maxHeight="150dp"/>