Reputation: 3563
I have created an activity with a header image. This header image is originally created int the Activity's layout xml using an ImageView where the scaleType is set to centerCrop. This does what I want, it centers the image, clipping it left and right in portrait mode, showing all in landscape mode.
<LinearLayout 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"
android:paddingTop="30dp"
android:paddingBottom="6dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:background="#919EAC"
android:orientation="vertical" >
<ImageView
android:id="@+id/header_image"
android:layout_width="match_parent"
android:layout_height="120dp"
android:contentDescription="@string/header_description"
android:scaleType="centerCrop"
android:src="@drawable/header" />
.... <other views> ...
I'd like to replace this with a background drawable so that I can use the header image space to display data, and it saves me repeating the same layout in the different activities.
For this reason I have created a drawable that I can refer to in the android:background attribute:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#919EAC" />
</shape>
</item>
<item>
<bitmap
android:antialias="true"
android:gravity="top|center_horizontal"
android:src="@drawable/header" />
</item>
</layer-list>
This drawable defines the colored background that otherwise the layout would define and it defines a header image that otherwise would be included in the layout as an ImageView.
However now my image is scaled, while I would like it to be cropped.
Checking the Android documentation I tried other gravity modes such as
android:gravity="top|clip_horizontal"
But it still seems to display/scale differently than the image view.
What would be the correct definition of the background drawable?
Upvotes: 42
Views: 14737
Reputation: 5190
I solved this problem with a decorator which maintains the aspect ratio of the underlying drawable: https://gist.github.com/rudchenkos/e33dc0d6669a61dde9d6548f6c3e0e7e
Unfortunately, there is no way to apply it from XML so I do that at the very beginning of my splash Activity:
public class SplashActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Drawable bg = getResources().getDrawable(R.drawable.screen);
getWindow().setBackgroundDrawable(new CenterCropDrawable(bg));
...
}
}
That is roughly equivalent to specifying the drawable as android:windowBackground
in the Activity theme
Upvotes: 3
Reputation: 1119
To center crop a bitmap in code do this:
public static Bitmap cropCenter(Bitmap bmp) {
int dimension = Math.min(bmp.getWidth(), bmp.getHeight());
return ThumbnailUtils.extractThumbnail(bmp, dimension, dimension);
}
I don't know of any other way to centerCrop a bitmap xml wise.
Hope it helps anyone.
I found this solution from this post: Android Crop Center of Bitmap
Upvotes: 3
Reputation: 305
I don't know how to do it with the background. You can try other solutions though:
1) Easiest solution to displaying something on top of image is to put them both in some layout so that they overlap. For example, you can use a RelativeLayout with the dimensions of the ImageView, the ImageView is match_parent in both dimensions and a TextView in center.
2) You can save the Imageview in a different layout, say, header.xml, and use it by include header.xml everywhere you need it.
3) If the layout to be displayed on top of ImageView is same everywhere then you can create a custom layout with an ImageView and say, a TextView in center, and use that layout everywhere. You can set the TextView string on this custom layout then. You can read more on custom layouts, they are easy.
Upvotes: -1
Reputation: 34301
Using scaleType = "centerCrop"
you were achieving a result which you desired, cropping the edges of image and show center portion whichever fits to that size.
For ImageView :
ImageView
have scaleType
attribute which works only for the Image that is set to it as source to display. i.e. as if it were TextView
then Text
is it's source.
Even you might have noticed that scaleType doesn't work for image that's set as background that only works with image that's supplied as source either in XML of at runtime.
For Layout
Layout
can show background images, but there is no any attribute given for layout which can process the background images and scale it as per the attribute's value.
So you should stop asking the facility of ImageView
from Layout
, because It doesn't have it.
2 different Solutions to Your Problem
1) Keep proper Images for background header in different drawable folder and use it, this way you don't require to scale it runtime as you already developed image for the size differently.
2) You need to just redesign your XML, like below sample
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:background="@drawable/subway"
android:scaleType="centerCrop" />
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
/>
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
Upvotes: -6