Android Button not filling full space in RelativeLayout - android

I am trying to create a button, aligned to the bottom of the page. I want it to fill 100% space, from left, right and bottom. Whatever attributes I will choose, there are still very small non covered areas. Can you please help?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
tools:context="com.example.myapplication.MainActivity">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_margin="0dp"
android:padding="0dp"
android:text="search"
/>
</RelativeLayout>
Here is the screenshot, showing not filled areas

Create a file in drawable folder like this, say simple_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<!-- Normal color -->
<solid android:color="#android:color/white" />
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<!-- Color - when the view is pressed -->
<solid android:color="#android:color/black"/>
</shape>
</item>
</selector>
Now simply set the background as the above created drawable.
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:background="#drawable/simple_selector"
android:text="search"
/>
The above code can change color in both normal and pressed states of the button. You can change the colors as per your requirement.

The space you see is the shadow around the button in its background drawable. You need to create your own background drawable and it should then completely occupy the width.
Or, you could also just set the background to null.
android:background="#null"

Related

Ripple effect over imageview

To describe my problem i created small example.
I have linearlayout with imageview and textview. For linearlayout i've set ripple drawable as background. But when i click or long click on linearlayout ripple animation shows under imageview. How show animation over imageview ?
main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linear"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#drawable/ripple"
android:clickable="true"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:src="#mipmap/index" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is ripple test"
android:textColor="#FF00FF00" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
drawable-v21/ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#FFFF0000">
<item>
<shape android:shape="rectangle">
<solid android:color="#FF000000"/>
</shape>
</item>
</ripple>
drawable/ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FFFF0000" />
</shape>
</item>
<item android:state_focused="true">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FFFF0000" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#FF000000" />
</shape>
</item>
</selector>
screenshot how it looks now:
Add the ripple like this
android:foreground="?android:attr/selectableItemBackground"
based on this answer https://stackoverflow.com/a/35753159/2736039
Add android:background="#null" for the ImageView
If your app needs to run on API < 23, you won't be able to use the foreground attribute on views other than FrameLayout, which means adding another [useless] level in the view tree hierarchy.
Another solution is to wrap your image with a <ripple>, set it as your ImageView's background, and use tint and tintMode to "hide" the src image so the background image that has the ripple over it is visible.
<!-- In your layout file -->
<ImageView
android:adjustViewBounds="true"
android:background="#drawable/image_with_ripple"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/image"
android:tint="#android:color/transparent"
android:tintMode="src_in" />
<!-- drawable/image_with_ripple.xml -->
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?colorControlHighlight">
<item android:drawable="#drawable/image" />
</ripple>
Not only this works on API 21+ but if your image has rounded corners – or is another type of non-rectangle shape, like a star or a heart icon – the ripple will remain in its bounds instead of filling the view's rectangle bounds, which gives a better look in some cases.
See this Medium article for an animated GIF to see how this technique compares to using a <FrameLayout> or the foreground attribute.
Resolve for API < 21
<ImageView
android:id="#+id/favorite_season"
style="?android:attr/borderlessButtonStyle"
android:background="?android:attr/selectableItemBackground"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_margin="22dp"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_star"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
Simple use these two lines as attribute in that ImageView.
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"

Change spinner background color but keep arrow

I've read several thing about it but I can't find what I need.
I want to keep the grey arrow but I want to remove the horizontal bar from the default style and have a white background. Do you have any idea of how I can do this ?
Here is what I have now (default spinner style) :
Here is what I want :
I did a little modification based on #Mansur Khan 's answer.
We don't have to add an ImageView in this case because the spinner already has a triangle arrow. So check the code below:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:background="#FFFFFF">
<Spinner
style="#style/Widget.AppCompat.DropDownItem.Spinner"
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/sign_up_country"
/>
</RelativeLayout>
Here is the screenshot
Before:
After:
For the record, I found an easy solution : Wrap your spinner in a relative layout and add an image :
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/borderbottom_white"<!-- white background with bottom border -->
android:layout_marginTop="15dp" >
<Spinner
android:id="#+id/postfield_category"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:background="#null"
android:minHeight="0dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="#drawable/arrowspinner" />
</RelativeLayout>
A simple solution that doesn't require you to create your own drawable for the arrow is to wrap the spinner with a RelativeLayout, and set the background color in the RelativeLayout, not the spinner:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f00" >
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Use this:
yourspinner.setOnItemSelectedListener(this);
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
((TextView) yourspinner.getSelectedView()).setBackgroundColor(getResources()
.getColor(R.color.your_color));
}
and your class should implement OnItemSelectedListener.
Hi instead of wrapping Spinner component around Parent Layouts like LinearLayout, RelativeLayout etc which increases layout parsing simply create a drawable called spinner_bg.xml under drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<bitmap
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:src="#drawable/icn_dropdown_arw" />
</item>
</layer-list>
Set spinner_bg as the background of your spinner and it works like charm:
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#drawable/spinner_bg" />
I think the best way without doing complex layouts is this:
Use this xml for your spinner background and you are good to go!!!
<item android:state_pressed="true">
<shape>
<solid android:color="#color/materialBlueGray600" />
<corners android:radius="3dp" />
</shape>
</item>
<item android:state_selected="true">
<shape>
<solid android:color="#color/materialGray50" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<layer-list>
<item>
<shape>
<solid android:color="#color/materialGray50" />
<corners android:radius="3dp" />
</shape>
</item>
<item android:gravity="right">
<bitmap android:antialias="true" android:gravity="right" android:src="#drawable/ic_expand_small" />
</item>
</layer-list>
</item>
Here is the code of custom spinner. Please check it out and tell me. Not yet I tested this. So please inform me after checking this whether it solves your problem.
<Spinner
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/spinner_background"
android:gravity="center"
android:paddingRight="10dp"
android:spinnerMode="dropdown"
android:textColor="your text color"
android:textSize="your text size" />
Here is the drawable(spinner_background.xml) to create the background of spinner.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="border color" />
<corners android:radius="3dp" />
</shape>
</item>
<item
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp">
<shape android:shape="rectangle" >
<solid android:color="#android:color/white" />
<corners android:radius="3dp" />
</shape>
</item>
</layer-list>
Edit:
please check this link which gives you an idea to do.
Customize spinner background
OR
you can do something like this.
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="spinner background image">
<Spinner
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#null"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="arrow image" />
</RelativeLayout>
below layout will create a background in spinner with desire color drop down arrow
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".6"
android:background="#drawable/edit_text_rounded_shape"
android:gravity="center|center_vertical">
<Spinner
android:id="#+id/spinerComanyName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="4dp"
android:layout_weight=".6"
android:layout_gravity="center"
android:entries="#array/spinner_item"
android:spinnerMode="dropdown"
android:theme="#style/Spinner"
/>
</LinearLayout>
<style name="Spinner">
<!-- Used for the bottom line when not selected / focused -->
<item name="colorControlNormal">#color/black</item>
<item name="colorControlActivated">#color/colorPrimary</item>
<!-- colorControlActivated & colorControlHighlight use the colorAccent color by default -->
</style>
edit_text_rounded_shape which provide background color and rounded corner
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="#color/white"/>
<stroke android:color="#color/grey"/>
<corners
android:bottomRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:topLeftRadius="15dp"
android:topRightRadius="15dp"/>
</shape>
A good way to customise spinners and any other Android controls is to use the Android Asset Studio site and choose the Android Holo Colors Generator. This will create all the assets you might need, including the "underline". It also generates the XML files that implement the changes.
Once you download the ZIP file from that site, you just copy the images and XML files into your project.
You can then edit the required image files to remove the underline. They are 9-Patch files, called:
apptheme_spinner_default_holo_light.9.png
apptheme_spinner_disabled_holo_light.9.png
apptheme_spinner_focused_holo_light.9.png
apptheme_spinner_pressed_holo_light.9.png
For a more complete explanation of the process, and to see some of the sample XML files, please refer to my related answer:
Change colour of small triangle on spinner in android
android:layout_alignParentRight="true"
android:layout_width="#dimen/spinner_width"
android:layout_height="wrap_content"
android:id="#+id/spnLocation"
android:entries="#array/labelFamily"
android:layout_centerVertical="true"
android:backgroundTint="#color/color_gray"
this work for me
Always while working with spinners, buttons and EditTexts and also needing to insert a drawable, I often wrap the element (spinner, EditText etc.) in a FrameLayout. Check an example:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Spinner
android:id="#+id/spinner_component"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#drawable/your_rectangle_style"
android:textColor="#color/your_text_color" />
<ImageView
android:layout_width="11dp"
android:layout_height="9dp"
android:src="#drawable/arrow_spinner"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="7dp" />
</FrameLayout>
Another important tip is that FrameLayout allows you to set OnClick functions on the drawable, for instance.

Android creating Circular layout

I am trying to create a circular layout that always stay's on the screen.
To do so, I have created a System overlay and added a button.
But, now I want to make it round.
Either I can use 4 different ImageView and and textView and add both to FrameLayout.
I read somewhere that simple things like this can be made by XML.
How do I do it?
I want to achieve something like this :
EDIT
After following your guide I was able to achieve this :
But I am not satisfied by the way I used.
What I did was created 2 shaped (background, forground) and added them to a layerlist.
BACKGROUND
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#50000000" />
</shape>
FORGROUND
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#99009900" />
</shape>
LIST
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/circleback">
</item>
<item
android:bottom="5dp"
android:drawable="#drawable/circlefront"
android:left="5dp"
android:right="5dp"
android:top="5dp">
</item>
</layer-list>
Then, I used a framelayout and added 2 textview.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:background="#drawable/circle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="33dp"
android:text="#string/data_left"
android:layout_marginTop="8dp"
android:textColor="#fff"
android:textSize="30sp"
android:typeface="sans"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:text="#string/band"
android:layout_marginTop="40dp"
android:textColor="#fff"
android:textSize="20sp"/>
</FrameLayout>
And then inflated them by service. But I am not happy with the textposition and the fact that I have to random hit and trial to find center of circle.
I'll later add pinch to zoom to view so, I really want to find a way that text align itself to centre of circle.
You need to create a shape drawable (in the res/drawable folder) like:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"
<solid android:color="#ff00ff00 />
</shape>
See docs: https://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

Possible to create a fixed-width drawable in XML?

I'm trying to simplify some graphics from requiring a 9-patch for each density, to just using an XML drawable. It's a fairly simple graphic:
2 Segments:
8dp wide for both segments
Top segment is 2dp tall
Bottom segment fills the view
Right side is filled with transparency
Giving this result when set as a background image:
It seems like this should be fairly simple to recreate as an XML drawable, and would avoid creating 5 different 9-patch graphics. However, I've looked into layer-list drawables, inset drawables, clip drawables -- they all seem to require that you know the size of the view beforehand (e.g. to keep it 2dp for an inset, you'd need to set insetRight to the width of the view - 2dp). I also tried using the shape tag's size tag, but that doesn't keep a fixed size, just a fixed proportion (so for taller views it will scale proportionally).
Am I overlooking something simple, or is this something I'd have to resort to checking programatically after layout?
This is not possible. This is the best solution I found. Only xml, no coding, no bitmaps, no additional views )
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#ff0000" />
</shape>
</item>
<item
android:top="4dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#00ff00" />
</shape>
</item>
<item
android:left="10dp">
<shape
android:shape="rectangle">
<solid
android:color="#FFFFFF" />
</shape>
</item>
</layer-list>
Via code you can make your own drawble type with desired behavior. Xml drawable very limited. IMHO my suggestion is the closest to what you demanded.
I think the answer by #Leonidos is very close to what I'm proposing, except I'm using the drawable as a separate view instead of the background for the entire list detail layout. This allows it to be a fixed width and to let the item text have its own background. Let me know if I'm not understanding your constraints.
The following file is "res/drawable/list_left_border"
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#e76e63" />
</shape>
</item>
<item android:top="2dp">
<shape android:shape="rectangle" >
<solid android:color="#ffc257" />
</shape>
</item>
</layer-list>
Then on the layout for the list item in "res/layout/list_item.xml"
<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:orientation="horizontal"
tools:context=".MainActivity" >
<View
android:background="#drawable/list_left_border"
android:layout_width="8dp"
android:layout_height="match_parent" />
<TextView
android:id="#+id/listItemText"
android:textSize="15sp"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Here's the image. The background is pink to show that the list item is transparent.
I'm going to go one further and suggest a slight reworking of AndroidGuy's answer, which itself includes Leonidos' answer.
Same drawable XML, different list item XML as follows:
<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:orientation="vertical"
tools:context=".MainActivity" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="100sp">
<ImageView
android:layout_width="8dp"
android:layout_height="match_parent"
android:src="#drawable/list_left_border" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Item Text"
android:textSize="22sp" >
</TextView>
</FrameLayout>
The FrameLayout gives the original background behaviour, rather than separation into a new view.
I've shown this below, with backgrounds to demonstrate:
This doesn't really deserve the points though.

Buttons spacing

I'm trying to set the margin of the buttons to 0, (so no spacing between the buttons).
Basically, I want my buttons to look something like that(with the following style and colors):
Any idea how can I accomplish this kind of task? I do not want to create a 9 patch image by myself (since I don't have any knowledge doing that).
In this specific case, you can do this task easily with XMLs.
This is how you can achieve it in two steps:
Step 1
Create 3 shapes in drawable folder:
First shape is for the left button: shape_button_left.xml. This shape has radial left corners and gradient background.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke
android:width="1dp"
android:color="#BFBFBF" >
</stroke>
<corners
android:bottomLeftRadius="10dp"
android:topLeftRadius="10dp" >
</corners>
<gradient android:startColor="#D2D2D2" android:endColor="#F2F2F2" android:angle="90"/>
</shape>
Second shape is for the center button: shape_button_center.xml. This shape doesn't define anything for corners and also has gradient background.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke
android:width="1dp"
android:color="#BFBFBF" >
</stroke>
<gradient android:startColor="#D2D2D2" android:endColor="#F2F2F2" android:angle="90"/>
</shape>
Third shape is for the right button: shape_button_right.xml. This shape has radial right corners and gradient background.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke
android:width="1dp"
android:color="#BFBFBF" >
</stroke>
<corners
android:bottomRightRadius="10dp"
android:topRightRadius="10dp" >
</corners>
<gradient android:startColor="#D2D2D2" android:endColor="#F2F2F2" android:angle="90"/>
</shape>
Step 2
Now, we can use these shapes in simple views to get the effect of buttons.
In your layout XML add the next code:
<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:gravity="center" >
<!-- Button Left -->
<LinearLayout
android:id="#+id/button_left"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#drawable/shape_button_left"
android:gravity="center"
android:padding="10dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Left"
android:textColor="#333333"
android:textSize="20sp" />
</LinearLayout>
<!-- End Button Left -->
<!-- Button Center -->
<LinearLayout
android:id="#+id/button_center"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#drawable/shape_button_center"
android:gravity="center"
android:padding="10dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center"
android:textColor="#333333"
android:textSize="20sp" />
</LinearLayout>
<!-- End Button Center -->
<!-- Button Right -->
<LinearLayout
android:id="#+id/button_right"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#drawable/shape_button_right"
android:gravity="center"
android:padding="10dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right"
android:textColor="#333333"
android:textSize="20sp" />
</LinearLayout>
<!-- End Button Right -->
</LinearLayout>
That's it
Now, you can add onClick listener in your code to LinearLayouts and work with it like a button.
Testing this code on my mobile gives next result:
Any idea how can I accomplish this kind of task? I do not want to create a 9 patch image by myself (since I don't have any knowledge doing that).
I'm afraid you may not have much choice. The inherent spacing found in between each button is a result of extra transparent pixels built directly into the existing 9-patch backgrounds that the framework uses. To replace this behavior you must set the background of the buttons to a different Drawable that doesn't include this inherent spacing.
Another option would be for you that could be done in code is to create XML drawable shapes to use for each background. You can create an individual shape that has corner radii, a fill gradient, and a stroke just like your image. You can read more about creating XML Drawables in the docs.

Categories

Resources