I have the following CardView and I want to set different radius for each corner in the card. Is it possible to change them by XML or programmaticaly? Thanks in advance.
<android.support.v7.widget.CardView
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:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
app:cardCornerRadius="0dp"
app:cardElevation="0dp">
</android.support.v7.widget.CardView>
EDIT
As Avinash suggest, I am looking for the behaviour of this lib github.com/captain-miao/OptionRoundCardview but using the default CardView item. If it is not possible to change it individually, this lib is a good approach.
It requires the official MaterialCardView (which extends the androidx.cardview.widget.CardView) and at least the version 1.1.0 of the Material components library.
Add to your layout the MaterialCardView:
<com.google.android.material.card.MaterialCardView
style="#style/CustomCardViewStyle"
...>
</com.google.android.material.card.MaterialCardView>
Define a custom style inheriting a material card style (for example Widget.MaterialComponents.CardView) and use the shapeAppearanceOverlay attribute:
<style name="CustomCardViewStyle" parent="#style/Widget.MaterialComponents.CardView">
<item name="shapeAppearanceOverlay">#style/ShapeAppearanceOverlay_card_custom_corners</item>
</style>
<style name="ShapeAppearanceOverlay_card_custom_corners" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopRight">4dp</item>
<item name="cornerSizeTopLeft">8dp</item>
<item name="cornerSizeBottomRight">16dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
You can also achieve it programmatically.
Just apply a custom ShapeAppearanceModel to the corners of the card.
Something like:
float radius = getResources().getDimension(R.dimen.my_corner_radius);
cardView.setShapeAppearanceModel(
cardView.getShapeAppearanceModel()
.toBuilder()
.setTopLeftCorner(CornerFamily.ROUNDED,..)
.setTopRightCorner(CornerFamily.ROUNDED,..)
.setBottomRightCorner(CornerFamily.ROUNDED,radius)
.setBottomLeftCornerSize(0)
.build());
Note: it requires the version 1.1.0 of the library.
With Jetpack compose you can use the shape parameter in the Card.
Something like:
Card(
shape = RoundedCornerShape(
topStart = 4.dp,
topEnd = 8.dp,
bottomEnd = 16.dp,
bottomStart = 2.dp,
)
){
Text("Content Card")
}
You can create a custom xml and name it rounded_corners.xml like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"
android:topLeftRadius="20dp"
android:topRightRadius="30dp"
android:bottomLeftRadius="40dp"
android:bottomRightRadius="50dp"/>
<solid android:color="your_background_color" />
</shape>
And then use this as the background for your CardView:
android:background="#drawable/rounded_corners"
EDIT: I just noticed that this may work for all other views other than CardView, so refer to this question for seeing how to do a workaround.
NOTE: This here is a workaround if you want to achieve rounded corners at the bottom only and regular corners at the top. This will not work if you want to have different radius for all four corners of the cardview. You will have to use material cardview for it or use some third party library.
Here's what seemed to work for me:
<?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="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#F9F9F9">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#drawable/profile_bg"/>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="#+id/cvProfileHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="32dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="280dp"
android:orientation="vertical"
android:background="#drawable/profile_bg"
android:id="#+id/llProfileHeader"
android:gravity="center_horizontal">
<!--Enter your code here-->
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
There's two cardview's in all. The second cardview is the one that will have rounded corners (on all sides as usual) and will hold all other subviews under it. The first cardview above it is also at the same level (of elevation), and has the same background but is only about half the height of the second cardview and has no rounded corners (just the usual sharp corners). This way I was able to achieve partially rounded corners on the bottom and normal corners on the top. But for all four sides, you may have to use the material cardview.
In case, if you use ImageView inside CardView, you should change ImageView into ShapeableImageView. Normal ImageView only works with all corners not each corner.
Here is more detail example on material.io docs
themes.xml
<style name="MyCardView" parent="#style/Widget.MaterialComponents.CardView">
<item name="shapeAppearanceOverlay">#style/MyCardViewOverlay</item>
</style>
<style name="MyCardViewOverlay">
<item name="cornerFamily">rounded</item>
<!-- below items does not work with normal ImageView -->
<item name="cornerSizeTopRight">0dp</item>
<item name="cornerSizeTopLeft">60dp</item>
<item name="cornerSizeBottomRight">0dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
layout.xml
<com.google.android.material.card.MaterialCardView
style="#style/MyCardView"
android:layout_width="200dp"
android:layout_height="200dp"
app:cardPreventCornerOverlap="false">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#color/orange_600"
app:shapeAppearanceOverlay="#style/MyCardViewOverlay" />
</com.google.android.material.card.MaterialCardView>
Hi you can add it programmatically or by xml with following code.
app:cardCornerRadius="0dp"// xml
cardView.setRadius(0);
this one is extra who is looking for elevation
app:cardElevation="0.7dp"//xml
app:cardMaxElevation="1dp"//xml
cardView.setCardElevation(2.1f);//code
cardView.setMaxCardElevation(3f);//code
The complete Java representation of the CardView’s XML.
CardView cardView = (CardView) findViewById(R.id.cardView);
cardView.setUseCompatPadding(true);
cardView.setContentPadding(30, 30, 30, 0);
cardView.setPreventCornerOverlap(true);
cardView.setCardBackgroundColor(Color.WHITE);
cardView.setCardElevation(2.1f);
cardView.setRadius(0);
cardView.setMaxCardElevation(3f);
Related
I want to make an a bit circular button with a drawableStart (without padding).
I added this to the button background:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#CC232323"/>
<corners android:radius="50sp"/>
</shape>
The button is:
<Button
android:id="#+id/btn_play"
android:layout_width="match_parent"
android:layout_height="50sp"
android:layout_marginStart="25sp"
android:layout_marginEnd="25sp"
android:layout_weight="1"
android:background="#drawable/btn_bg"
android:drawableStart="#drawable/icon_layer_list"
android:text="#string/sample_text"
android:textAlignment="textStart"
android:textAllCaps="false"
android:textColor="#color/colorWhite" />
The layer-list is:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/background_design"
android:height="50sp"
android:width="50sp"
/>
</layer-list>
the corner does work on the button it self but the drawableStart is not affected by them, so I get a button that on one side is with circular border and on the other side a square border of the drawableStart.
View (or Button in your case) is always rectangle. When you apply background with rounded corners, it is only background image rounded, not the View itself. If you need to have rounded corners in drawableStart, you need to have rounded corners in drawable you set for drawableStart.
I found a simple and easy solution, the idea of it is to wrap the button with a CardView and set it's cardCornersRadius to the wanted radius.
like so:
<androidx.cardview.widget.CardView
android:layout_width="150dp"
android:layout_height="150dp"
app:cardCornerRadius="250dp"
android:layout_gravity="center">
<Button
android:id="#+id/btn_play"
android:layout_width="match_parent"
android:layout_height="50sp"
android:layout_marginStart="25sp"
android:layout_marginEnd="25sp"
android:layout_weight="1"
android:background="#drawable/btn_bg"
android:drawableStart="#drawable/icon_layer_list"
android:text="#string/sample_text"
android:textAlignment="textStart"
android:textAllCaps="false"
android:textColor="#color/colorWhite"/>
</androidx.cardview.widget.CardView>
it is without a doubt the simplest way I've found in order to get the view act withthin the borderd, the CardView will not let the button or anything within it to draw outside of its borders / corners.
For more information about CardView (it's properties, dependency, etc...), go to This link.
This is the code in the layout
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:passwordToggleEnabled="true"
app:passwordToggleDrawable="#drawable/selector_password_icon">
<android.support.design.widget.TextInputEditText
android:id="#+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/activity_login_password_text_value"
android:inputType="textPassword"/>
</android.support.design.widget.TextInputLayout>
And this is the code in the Selector
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/ic_eye_active" />
<item android:drawable="#drawable/ic_eye_inactive" />
The Icons have different colors (Gray and Black) but the same shape and size. The problem is that both icons show the same color, therefore stays the same if its active or inactive.
Edit: I want to use XML because it will be used in multiple pages
Update your color values, use color values directly, follow this link:
https://www.codevscolor.com/android-material-design-tutorial-10-password-visibility-toggle/
I'm hoping there is an xml solution to this... I am trying to create a layout that has rounded corners and then filling that layout with an image (tiled, repeat). So basically I have a LinearLayout that has a drawble layered-list assigned to the background. Here is the test layout (xml):
<?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="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/rate_buttons"
android:layout_width="100dp"
android:layout_height="50dp"
android:orientation="horizontal"
android:padding="0dp"
android:background="#drawable/test_rounded">
</LinearLayout>
</LinearLayout>
here is the test_rounded drawable xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item ><bitmap android:src="#drawable/my_tiled_image" android:tileMode="repeat"/></item>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="3dip" android:color="#B1BCBE" />
<corners android:radius="20dip"/>
</shape>
</item>
</layer-list>
The image is overflowing at the corners of the shape/layout border. I get the following
As you can see the corners are overflowed. I heard about modifying the image part (blue pattern) in code but I have issues with that since I do modify it and animate it along the way. SO, if its at all possible to just fill in the layout with that image, please let me know. Thank you all for your help.
You can do this only programatically. But if you want to do this using xml, you have to add the background image in a layout above the rounded corner layout with the help of Relative layout and set margin. This will not give a perfect solution but will solve your problem.
The first is the XML way
Create an xml file in your respective drawable folder for the round border.
I have namedd it as popupborder.xml.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#FFFFFF" />
<stroke android:width="2dp" />
<corners android:radius="15dip" />
</shape>
The main layout
<?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="match_parent"
android:layout_gravity="center"
android:layout_margin="10dp"
android:background="#drawable/popupborder" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp" >
<LinearLayout
android:id="#+id/property_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Inner view with Background and margin"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#000000" />
</LinearLayout>
</RelativeLayout>
i recommend you to use an image loader library such as universal image loader, picasso etc. Here is an example code for it:
String url = "file://" + your_file_path
com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(url, ivPicture, options);
You have to add
.displayer(new RoundedBitmapDisplayer(px))
to your Universal Image Loader display options.
Also there is another library (i think this is what you are looking for) https://github.com/vinc3m1/RoundedImageView
You can check this. But in second way you can get "Out of Memory Exception" cause of loading big sized image.
I hope this'll help you.
I'm developing Android app for 4.0 version, and all checkboxes have got a black background for tick, but I need white. If I use "background" xml attribute as "white" then all checkbox (with text) is white; I need only white place for tick.
The most simple way - emulate CheckBox using ImageView with 3 background states (stateSelected=true, stateSelected=false, statePressed = true). Just create appropriate xml file with 3 backgrounds and set it to ImageView background. Then in code, when click on ImageView just switch ImageView.setSelected = !ImageView.isSelected. Hope its help
I dont know if i am extremely late or what, but here is the solution
Code snippet:
say this selector is name "checkbox_selector"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/cbchk_blue"
android:state_focused="false">
</item>
<item android:state_checked="true"
android:drawable="#drawable/cbchk_blue"
android:state_focused="true">
</item>
<item android:state_checked="false"
android:drawable="#drawable/cbunchk_blue"
android:state_focused="false">
</item>
<item android:state_checked="false"
android:drawable="#drawable/cbunchk_blue"
android:state_focused="true">
</item>
in order to set it just for the checkbox and not the entire text also, you could have it as:
<CheckBox
android:layout_width="45dip"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:button="#drawable/checkbox_selector"
android:text="#string/text_here" />
Maybe my solution is not very elegant, but it works for me:
I simplily create another layout with the dimensions of the checkbox rectangle (15x15) and with white background. Then I add this layout to a RelativeLayout, where I also put the checkbox. With a margin of 9dp, I put the white layout-rectangle below the checkbox, so it seems that the checkbox bacground color is white.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/login_large_margin"
android:layout_marginTop="#dimen/login_medium_margin" >
<RelativeLayout
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_margin="9dp"
android:background="#color/white" >
</RelativeLayout>
<CheckBox
android:id="#+id/login_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:text="#string/login_check"
android:textColor="#color/white" >
</CheckBox>
</RelativeLayout>
I just want to make an ImageView as my headbar ... it should just fill out his parent linear-layout.. apparently it does not.
is there any way to tell the scaleType just to fit its parent-layout? (best solution in XML) i saw the was a programming-solution which setting the scaleType to "fill" ... but there seems to be no matching xml-attribute, or didn't i see it?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
android:id="#+id/linearlayoutmain">
<ImageView
android:layout_marginTop="0dp"
android:src="#drawable/headbar"
android:id="#+id/mainheadbar"
android:scaleType="fitStart"
android:paddingTop="0dp"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
</LinearLayout>
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_weight="7"
android:layout_below="#id/linearlayoutmain">
</LinearLayout>
</RelativeLayout>
any thoughts/solutions about it? I thought i don't need to mind about the aspect ratio because I 9patched the whole thing.. so it shouldn't mind.
edit: it seems to work better when i use an ImageBUtton instead of an imageview... however, i got problems on lower -size screens... they seem to don't mind my 9patching... lol
You need to use three types of layouts in general
layout-hdpi
layout-mdpi
layout-ldpi
Also you need to use three values layouts in general
values-hdpi
values-mdpi
values-ldpi
Here i explain for LDPI Device Header you have to do for all you device HDPI,MDPI, etc
For example simple xml that has Image as Header : layout-ldpi - Header
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="50px"
android:orientation="horizontal" >
<ImageView android:id="#+id/header_main_title" android:layout_marginTop="10dip"
android:layout_width="wrap_content" android:layout_height="50dip"
android:background="#drawable/header_image"
android:layout_centerHorizontal="true" android:layout_marginRight="10dip"
/>
Similarly values-ldpi contains
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme">
<item name="android:windowTitleSize">50px</item>
<item name="android:windowTitleBackgroundStyle">#style/WindowTitleBackground
</item>
</style>
</resources>
Similarly for Styles.xml :
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="WindowTitleBackground" parent="android:WindowTitleBackground">
<item name="android:background">#android:color/transparent</item>
</style>
In your Manifest.xml include this Line :
<application android:icon="#drawable/vmi_icon" android:label="#string/app_name" android:theme="#style/MyTheme" >
Put the Styles.xml and Themes.xml inside of values-ldpi folder
I shown Header for ldpi device similarly you need to create for MDPI and HDPI device
changes should be made in this line of all
if it's HDPI :
<item name="android:windowTitleSize">100px</item>
If it's Mdpi :
<item name="android:windowTitleSize">70px</item>
Similarly for header.xml :
if it's HDPI :
android:layout_height="100px"
If it's Mdpi :
android:layout_height="70px"