I have a simple layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/button_background"
android:text="Button"
android:gravity="center"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
and this is the output:
But I want the button with the background to stay the same size as it would without an image as a background (the right one). Basically, I want to "place" the button over the image so that the center of the image is on the button background, but the button doesn't resize to fit the whole background.
I have tried android:scaleType="centerCrop" on the Button but it didn't change anything. Any help is appreciated, thanks
Edit The size of the button needs to wrap_content because the text is dynamic
The button width and height are set to wrap_content. In this case, the background Image is a content, too.
Simply change width and height to the value you want:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/button5"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#drawable/button_background"
android:text="Button"
android:gravity="center"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/button6"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
If you want all buttons to have the same size, consider creating a dimen value:
Dimen
<resources>
<dimen name="button_width">100dp</dimen>
<dimen name="button_height">50dp</dimen>
</resources>
Layout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/button5"
android:layout_width="#dimen/button_with"
android:layout_height="#dimen/button_height"
android:layout_weight="1"
android:background="#drawable/button_background"
android:text="Button"
android:gravity="center"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/button6"
android:layout_width="#dimen/button_with"
android:layout_height="#dimen/button_height"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
Also, consider using a ImageButton for your purpose.
ImageButton
EDIT
Try this out:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/your_background"
android:layout_alignStart="#+id/buttonId"
android:layout_alignEnd="#+id/buttonId"
android:layout_alignTop="#+id/buttonId"
android:layout_alignBottom="#+id/buttonId"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonId"/>
</RelativeLayout>
Additionally, add a scaleType to the ImageView to make it centered, streched, whatever...
android:scaleType="center"
EDIT 2
adding padding to the button works for me:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/icon_settings"
android:layout_alignStart="#+id/buttonId"
android:layout_alignEnd="#+id/buttonId"
android:layout_alignTop="#+id/buttonId"
android:layout_alignBottom="#+id/buttonId"
android:scaleType="center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:text="This is a button with a very long text that may take up multiple lines and stuff"
android:id="#+id/buttonId"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/icon_settings"
android:layout_alignStart="#+id/buttonId2"
android:layout_alignEnd="#+id/buttonId2"
android:layout_alignTop="#+id/buttonId2"
android:layout_alignBottom="#+id/buttonId2"
android:scaleType="center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a button with a very long text that may take up multiple lines and stuff"
android:id="#+id/buttonId2"/>
</RelativeLayout>
Note: You can't really see the paddingStart and paddingEnd in the screenshot, but it works just fine.
To expand on the nine-patch suggestion, Android supports the ability to use a nine-patch image to scale an image for a button/view group to any size. One caveat is that the image has to be one that fits the nine-patch requirement -- generally speaking, image where the corners are constant, and the middle/edges must be able to scale to any dimension. If your image is a photo for instance, it won't work. Most nine-patch images have a solid color center and 'simple' edges.
The first step is to create a nine-patch drawable in your drawable folder that references your nine-patch image. The nine-patch image should have a filename similar to *.9.png.
<?xml version="1.0" encoding="utf-8"?>
<nine-patch
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/button_image" />
Once this is done, you can add the background property to the Button and it should scale seamlessly with the content (the background property below should refer to the <nine-patch> XML resource you created above.
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_background"
android:text="My button"/>
I will note that your image in particular, with the horizontal lines, looks like a bad candidate for the nine-patch solution, but it might be worth a look if you're flexible on the image used.
Related
I have been often told to use 0dp on views while using weight in XML like this :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/a1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="1" />
</LinearLayout>
but there is a problem with this code which is when i use a view like Button, i can't force it to take the exact weight im giving to it.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/a1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="25"
android:text="1" />
<Button
android:id="#+id/a2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="2" />
</LinearLayout>
in the code written above, the 2nd button will never be exactly 1/26 because the button itself has some margin and padding by default.
but when i use match_parent for their height, it forces them to be exactly 1/26 and it works perfectly.
but i can't understand why the 1st button gets to be 1/26 and it seems like they exchange their weight, and it gets more complicated when i use 3 views.
is there a better way of achieving this goal ?
and why weight acts different while using match_parent ?
the spacing in the Button is not padding or margin, but it was a background.
if you want to remove the spacing you should change the background of the Button
it is recommended to use android:layout_height="0dp"
because the docs of layout_weight said :
Indicates how much of the extra space in the LinearLayout is allocated to the view associated with these LayoutParams.
It said "extra space" not "space". So the right height should be 0dp + "extra space calculated"
here some sample code
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="6"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="#+id/a1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/red"
android:text="1" />
<Button
android:id="#+id/a2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="2"
android:background="#color/blue"
android:text="2" />
<Button
android:id="#+id/a3"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/yellow"
android:text="3" />
</LinearLayout>
and the result
I got such issue with my RecyclerView
I need to present to user images that I downloaded with help of picasso lib from web to my RecyclerView. Eventually it looks like this
As you can see I need to scratch my images, but in proper aspect ratio of course.
I went to my XML file and set attribute in my ImageView android:scaleType="fitXY"
now my ImageView looks like this
<ImageView
android:id="#+id/imageViewMainCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
/>
and here is result that I got
as you can see now image fill all available space, but them doesn't scratch with propriety aspect ratio. Images scratch width more than height and does't looks nice...
Also here is my XML file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:paddingBottom="3dp"
android:paddingEnd="3dp"
android:paddingStart="3dp"
android:paddingTop="3dp"
>
<LinearLayout
android:id="#+id/cardMainActivityLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.balysv.materialripple.MaterialRippleLayout
android:id="#+id/rippleInbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:mrl_rippleColor="#color/ntz_background_light_grey"
app:mrl_rippleOverlay="true"
>
<ImageView
android:id="#+id/imageViewMainCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
/>
</com.balysv.materialripple.MaterialRippleLayout>
<RelativeLayout
android:id="#+id/rlCardMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:padding="4dp"
>
<TextView
android:id="#+id/tvBrandName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:textColor="#color/black_color"
android:textSize="10dp"
/>
<TextView
android:id="#+id/tvItemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tvBrandName"
android:textColor="#color/black_color"
android:textSize="10dp"
/>
<TextView
android:id="#+id/tvPreviousPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tvItemName"
android:textColor="#color/black_color"
android:textSize="10dp"
/>
<TextView
android:id="#+id/tvDivider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/tvPreviousPrice"
android:layout_toEndOf="#+id/tvPreviousPrice"
android:text=" / "
android:textSize="10dp"
android:visibility="gone"
/>
<TextView
android:id="#+id/tvPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/tvDivider"
android:layout_toEndOf="#+id/tvDivider"
android:textColor="#color/black_color"
android:textSize="10dp"
/>
<Button
android:id="#+id/bAction"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:textSize="8dp"
/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
What am I doing wrong?
Edit1
There is a result of android:scaleType="centerCrop" attributes
It is also not so nice when women don't have head))
Edit2
There is result of android:scaleType="centerInside"
To answer your question, please use centerCrop to center the image absolute to it's parent. Also add this attribute, android:adjustViewBounds="true". With this the aspect ratio of the image will be preserved.
fitXY uses FILL which is described as "Scale in X and Y independently, so that src matches dst exactly. This may change the aspect ratio of the src" in the Android Documentation.
You should use centerInside to center, fit and scale while keeping the aspect ratio
Alright the problem is that your layout does not respect the bounds of your image.To remedy this, wrap the image-view in a separate parent layout , add a parent weight to the layout it self with layout_weight="1".Then set the width relative to the layout with android:layout_width="0px", to avoid tearing and proper bounds coordination set android:adjustViewBounds="true". To center and crop the image at it's center use android:scaleType="centerCrop".
Ok this is something I can do in iOS in like five minutes.. but I can't seem to get it for android:
i simply want to show a progress bar ontop of a button. I managed to render the progress bar just fine beside the button like so
using this code
<RelativeLayout
android:id="#+id/readBookContainer"
android:layout_below="#+id/image"
android:layout_marginLeft="#dimen/margin_medium"
android:layout_alignRight="#+id/ratingBar"
android:gravity="center"
android:layout_width="300dp"
android:layout_height="40dp">
<Button
android:id="#+id/readBook"
android:background="#drawable/button_read_now"
android:elevation="#dimen/margin_xsmall"
android:singleLine="true"
android:textSize="14sp"
android:text="#string/download"
android:layout_width="200dp"
android:gravity="left"
android:layout_height="match_parent"
android:textColor="#color/book_item_bg" />
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/read_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
android:tint="#000000"
android:layout_toLeftOf="#id/readBook"
android:layout_marginRight="20dp"
style="#style/Widget.MaterialProgressBar.ProgressBar.Small" />
however i can't seem to be able to do this:
i tried stuff like this (framelayout, relative layout)..
<FrameLayout
android:id="#+id/readBookContainer"
android:layout_below="#+id/image"
android:layout_marginLeft="#dimen/margin_medium"
android:layout_alignRight="#+id/ratingBar"
android:gravity="center"
android:layout_width="100dp"
android:layout_height="40dp">
<android.support.v4.widget.ContentLoadingProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/read_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
android:tint="#000000"
android:layout_gravity="right|center"
style="#style/Widget.MaterialProgressBar.ProgressBar.Small" />
<Button
android:id="#+id/readBook"
android:background="#drawable/button_read_now"
android:elevation="#dimen/margin_xsmall"
android:singleLine="true"
android:textSize="14sp"
android:text="#string/download"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#color/book_item_bg" />
but it doesn't work.. (i tried substituting the library progress bar with android's but no luck).. ideas?
update
this is what the final thing looks like (based on the correct answer below):
<LinearLayout
android:id="#+id/readBook"
android:background="#drawable/button_read_now"
style="#style/Widget.AppCompat.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:text="#string/download"
android:textAppearance="#style/TextAppearance.AppCompat.Button" android:textColor="#FFFFFF"/>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/read_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:indeterminate="true"
android:visibility="invisible"
android:tint="#ffffff"
style="#style/Widget.MaterialProgressBar.ProgressBar.Small" />
</LinearLayout>
Starting from API level 21, a default Button (which is called a raised button in Material Design) has a resting elevation and a pressed elevation.
For example in API level 23 The values are 2dp and 6dp respectively.
Your ProgressBar is in the correct position, however it's below the Button because its elevation is 0.
So by simply adding an elevation greater than 6dp to your ProgressBar you can make it appear above the button.
android:elevation="7dp"
Alternatively, you can create a layout to mimic a button and give it a button style:
<LinearLayout
style="#style/Widget.AppCompat.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Button"
android:textAppearance="#style/TextAppearance.AppCompat.Button"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
The second approach is more forward compatible since the elevation might change in a future release.
For example in API level 21 the values were 1dp and 3dp
<!-- Elevation when button is pressed -->
<dimen name="button_elevation_material">1dp</dimen>
<!-- Z translation to apply when button is pressed -->
<dimen name="button_pressed_z_material">2dp</dimen>
This is API level 23
<!-- Elevation when button is pressed -->
<dimen name="button_elevation_material">2dp</dimen>
<!-- Z translation to apply when button is pressed -->
<dimen name="button_pressed_z_material">4dp</dimen>
You can wrap it to the RelativeLayout.
create parent RelativeLayout having background same as of your button.
Using Buttons will add the borders to view so you can use Textview with selector.xml which will work as Button. check here.
place Textview inside the RelativeLayout and align the ProgressBar to the Right of Textview.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_read_now"
>
<TextView
android:id="#+id/readBook"
android:gravity="center"
android:clickable="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:background="#drawable/selector"
android:singleLine="true"
android:textSize="14sp"
android:text="download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white" />
<android.support.v4.widget.ContentLoadingProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/readBook"
style="?android:attr/progressBarStyleSmall"
android:visibility="visible"/>
</RelativeLayout>
The problem is in Button style. You can find more information in this answer https://stackoverflow.com/a/32898915/1554094
Remove following
android:layout_toLeftOf="#id/readBook"
from
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/read_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="visible"
android:tint="#000000"
android:layout_toLeftOf="#id/readBook"// remove this
android:layout_marginRight="20dp"
style="#style/Widget.MaterialProgressBar.ProgressBar.Small" />
android:layout_toLeftOf="#id/readBook"
I am trying to have a button that has a small icon and text inside the button, the icon is sitting way to the left of the button, how can I move it closer to the text which is centered?
This is my XML for the button:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/home_icon"
android:text="BACK"
android:id="#+id/button"
android:width="160dp"
android:height="70dp"
android:textStyle="bold" />
Unfortunately it is not possible to do with drawableLeft attribute. This attribute positions the image to the far left position (no matter where your text is).
You need to create your own button for this:
<LinearLayout
android:id="#+id/button"
style="?android:attr/buttonStyle"
android:layout_width="160dip"
android:layout_height="70dip"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/home_icon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BACK"
android:textColor="#android:color/black" />
</LinearLayout>
You can't move it closer. Your only option if you want to have them closer together is building your own button:
<RelativeLayout
android:id="#+id/rlButton"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_text"/>
<ImageView
android:id="#+id/ivLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/home_icon"
android:layout_toLeftOf="#id/tvText"/>
</RelativeLayout>
You can use a margin to control the distance between the TextView and ImageView. You can use it pretty much the same as a button:
RelativeLayour rlButton = (RelativeLayout) view.findViewById(R.id.rlButton);
rlButton.setOnClickListener(new OnClickListener() {
....
});
But of course you have to apply your button style to the RelativeLayout so it looks the same as a button.
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#android:drawable/btn_star_big_on"
android:text="Drawable left"/>
Please have a look at the following code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#373734"
android:orientation="horizontal" >
<ImageView
android:id="#+id/backToLanguageSelectionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="15dp"
android:paddingTop="5dp"
android:src="#drawable/thunderbolt" />
<ImageView
android:id="#+id/internetButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="#drawable/globe_small_2" />
<Button
android:id="#+id/giveUpButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="350dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Button" />
</LinearLayout>
This is a common layout code which I am using for all the android activities. The problem is the button, I want it to move to the most right corner. Margin thing not seems to work properly because in different devices the button is in different places.
How can I move this to the most right corner which will be displayed same in all the devices?
I believe you could add a view between your second ImageView and your button, and set it to layout_width="0dp", layout_weight="1".
And remove the left margin of your button.
User Relative layout instead. And apply android:layout_alignParentRight="true" to your Button.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#373734"
android:orientation="horizontal" >
<ImageView
android:id="#+id/backToLanguageSelectionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="15dp"
android:paddingTop="5dp"
android:src="#drawable/social_share" />
<ImageView
android:id="#+id/internetButton"
android:layout_toRightOf="#+id/backToLanguageSelectionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="#drawable/social_share" />
<Button
android:id="#+id/giveUpButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Button" />
have you tried android:layout_gravity="right"?
Use RelativeLayout and set its height to be as small as you want. This way a small part of your screen will be filled. When you use RelativeLayout, you can use android:layout_alignParentRight="true" to put any item at right. Now, instead of button, you can use image and set its android:scaleType="centerInside" if there are problems with the buttons scaling.
I was having the same problem as you and I sove it using RelativeLayout.
It can be done with RelativeLayout
<Button
android:id="#+id/giveUpButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="350dp"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:text="Button"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />