How to create a custom shape button background? - android

I am trying to make a custom background for my button(simple) but it is not displaying properly. it only displays the following output.
Create Room(btn_create_room_bg) :
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<corners
android:bottomLeftRadius="360dp"
android:topLeftRadius="360dp" />
<solid android:color="#color/colorAccent" />
</shape>
</item>
</layer-list>
Join Room(btn_join_room_bg):
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners
android:bottomRightRadius="360dp"
android:topRightRadius="360dp" />
<solid android:color="#color/colorPrimary" />
</shape>
</item>
</layer-list>
Button code:
Here are my two-button codes in a linear layout.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="300dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="300dp"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
android:layout_weight="5"
android:background="#drawable/btn_create_room_bg"
android:fontFamily="#font/open_sans_bold"
android:text="#string/landing_btn_create_room"
android:textAllCaps="false"
android:textColor="#color/colorWhite" />
<Button
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_weight="5"
android:background="#drawable/btn_join_room_bg"
android:fontFamily="#font/open_sans_bold"
android:text="#string/landing_btn_join_room"
android:textAllCaps="false"
android:textColor="#color/colorWhite" />
</LinearLayout>
I need an output like this.

You can build a custom CornerTreatment with the MaterialButton.
You can extend the default CutCornerTreatment:
public class FullCutCornerTreatment extends CutCornerTreatment {
protected static final float ANGLE_LEFT = 180;
public FullCutCornerTreatment() {
super();
}
#Override
public void getCornerPath(
#NonNull ShapePath shapePath, float angle, float interpolation, float radius) {
shapePath.reset(0, 2*radius * interpolation, ANGLE_LEFT, 180 - angle);
shapePath.lineTo(
(float) (Math.sin(Math.toRadians(angle)) * radius * interpolation),
(float) (Math.sin(Math.toRadians(90 - angle)) * radius * interpolation));
}
}
Then just apply the CornerTreatment to the Button:
MaterialButton materialButton = findViewById(R.id....);
FullCutCornerTreatment customCutCornerTreatment = new FullCutCornerTreatment();
materialButton.setShapeAppearanceModel(materialButton.getShapeAppearanceModel().toBuilder()
//Standard rounded corner with corner radius=50%
.setTopLeftCorner(CornerFamily.ROUNDED,new RelativeCornerSize(0.5f))
.setBottomLeftCorner(CornerFamily.ROUNDED,new RelativeCornerSize(0.5f))
//Square angle
.setTopRightCorner(CornerFamily.ROUNDED,0)
//Full cut corner
.setBottomRightCorner(customCutCornerTreatment)
.setBottomRightCornerSize(new RelativeCornerSize(0.5f))
.build());
Just a note about new RelativeCornerSize(0.5f): It changed in 1.2.0-beta01. Before it was new RelativeCornerSize(50)).

Related

android how to select only one of button in adapter recycle view at view holder?

How to select the only 1 button out of 3 button? I manage to set/unset the background color on selected button for currently. But not able to select the only one selected button.
Example btn1, btn2, btn3.
When I selected btn1, the btn1 background was change color, and btn2 and btn3 not affected. After that when I selected the btn2 again, the btn1 background color was unset and the btn2 background was change color. So at this time the btn2 is selected and btn1 and btn3 not selected.
Below is my sample code:
public class ViewHolder extends RecyclerView.ViewHolder {
Button mButton;
public ViewHolder(View v) {
super(v);
parentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mButton= itemView.findViewById(R.id.mButton);
}
});
}
}
holder.mButton.setOnClickListener(new DebouncedOnClickListener(500) {
#Override
public void onDebouncedClick(View v) {
if(!holder.mButton.isSelected()){
holder.mButton.setSelected(true);
setSelectedButton(holder);
}
else{
holder.mButton.setSelected(false);
setSelectedButton(holder);
}
}
});
private void setSelectedButton(ViewHolder holder){
if(holder.mButton.isSelected()){
holder.mButton.setBackgroundColor(parentActivity.getResources().getColor(R.color.unread_notification));
}
else{
holder.mButton.setBackgroundColor(parentActivity.getResources().getColor(R.color.white));
}
}
What you need is to implement selection into your RecyclerView. After some searching, I found that this website might be useful for you
https://medium.com/#maydin/multi-and-single-selection-in-recyclerview-d29587a7dee2
I suggest you to use CheckBox instead of buttons like this -
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/background"
android:orientation="horizontal">
<RadioButton
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#drawable/button_background"
android:button="#null"
android:gravity="center"
android:text="Button 1"
android:textColor="#fff"
android:checked="true"
android:textStyle="bold" />
<RadioButton
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#drawable/button_background"
android:button="#null"
android:gravity="center"
android:text="Button 2"
android:textColor="#fff"
android:textStyle="bold" />
<RadioButton
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="#drawable/button_background"
android:button="#null"
android:gravity="center"
android:text="Button 3"
android:textColor="#fff"
android:textStyle="bold" />
</RadioGroup>
And for the Button background -
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false">
<shape android:shape="rectangle" >
<corners android:radius="50dp"/>
<solid android:color="#c7c7c7"/>
</shape>
</item>
<item android:state_checked="true">
<shape android:shape="rectangle" >
<corners android:radius="50dp"/>
<gradient android:startColor="#79ccff"
android:endColor="#7900ca"/>
</shape>
</item>
</selector>
And for the background -
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="50dp" />
<solid android:color="#c7c7c7" />
</shape>

android - How to set corner radius programmatically?

I have two ListViews (leftList, rightList). I also have one TextView which I use as row view in both of them.
I have a rectangle drawable shape and set it as background to the TextView.
I would like to change this shape and have rounded corners on the left.
What I tried :
GradientDrawable gradientDrawable = new GradientDrawable();
// gradientDrawable.setCornerRadius(30);
((GradientDrawable)gradientDrawable.mutate()).setCornerRadius(30);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
viewHolderPattern.digits.setBackground(gradientDrawable);
}
I have created a new layout in drawable with the right corner radius set and set that to the textView with setBackgroundRescource but still didn't work.
The TextView that I use as items in both listViews
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/digitsTextView"
android:textSize="15dp"
android:paddingTop="7dp"
android:paddingBottom="8dp"
android:fontFamily="monospace"
android:textColor="#color/selected_items"
android:background="#drawable/digital_text_shape">
</TextView>
Shape layout digital_text_shape.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#color/orange" />
<solid android:color="#color/orange" />
<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="20dp"
android:topRightRadius="0dp"
/>
<padding
android:bottom="0dp"
android:left="20dp"
android:right="0dp"
android:top="0dp" />
</shape>
Left list and Right list
<!-- Left ListView -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:id="#+id/left_listView"
android:divider="#android:color/transparent"
android:dividerHeight="0.1sp"
android:choiceMode="singleChoice"
>
</ListView>
</LinearLayout>
<!-- Right ListView -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
>
<ListView
android:id="#+id/right_listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#android:color/transparent"
android:dividerHeight="0.1sp"
android:choiceMode="singleChoice"
>
</ListView>
</LinearLayout>
Here example for how to create GradientDrawable shape programmatically.
GradientDrawable shape = new GradientDrawable();
shape.setShape(GradientDrawable.RECTANGLE);
shape.setColor(Color.RED);
shape.setStroke(3, Color.YELLOW);
For change the radius for all corners of the gradient.
shape.setCornerRadius(15);
For Change the radius for specific corners of the gradient.
shape.setCornerRadii(new float[] { 8, 8, 8, 8, 0, 0, 0, 0 });
You can use this drawable as a background as below :
view.setBackgroundDrawable(shape);
The answer of #Rohit Suthar in Kotlin, with dp converted to pixel, and color resources:
private val STROKE_WIDTH_PX = 2.dpToPx
private val CORNER_RADIUS_PX = 5.dpToPx.toFloat()
val shape = GradientDrawable()
shape.shape = GradientDrawable.RECTANGLE
shape.setColor(ContextCompat.getColor(context, R.color.pink))
shape.setStroke(STROKE_WIDTH_PX, ContextCompat.getColor(context, R.color.black))
// choose either cornerRadius or cornerRadii
shape.cornerRadius = CORNER_RADIUS_PX
shape.cornerRadii = floatArrayOf(
// top left
0f,
0f,
// top right
CORNER_RADIUS_PX,
CORNER_RADIUS_PX,
// bottom right
CORNER_RADIUS_PX,
CORNER_RADIUS_PX,
// bottom left
0f,
0f
)
view.background = shape
To convert dp to px:
val Int.dpToPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()

How to draw border for circular image view?

I am using drawable as image background for giving border but its not working as required (circle is not perfect).
Recycler view item layout
<data>
<variable
name="news"
type="com.android.mvvm.model.NewsItem" />
<variable
name="clickListener"
type="com.android.common.util.RecyclerViewOnItemClickHandler"></variable>
</data>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/circular_image_selected"
android:layout_width="100dp"
android:layout_height="100dp"
android:onClick="#{clickListener.onClick}"
android:src="#{news.thumb}" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/circular_image_unselected"
android:layout_width="100dp"
android:layout_height="100dp"
android:onClick="#{clickListener.onClick}"
android:src="#{news.thumb}"
android:visibility="gone" />
</FrameLayout>
Adapter's onBindViewHolder method where i am setting background to the image view on item selected
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof RecyclerViewHolder) {
NewsItem item = list.get(position);
RecyclerViewHolder newsViewHolder = (RecyclerViewHolder) holder;
if (item.isSelected) {
CircleImageView img = (CircleImageView) newsViewHolder.getBinding().getRoot().findViewById(R.id.circular_image_unselected);
newsViewHolder.getBinding().getRoot().findViewById(R.id.circular_image_unselected).setVisibility(View.VISIBLE);
img.setBackground(context.getResources().getDrawable(R.drawable.selected_img_bg));
} else {
CircleImageView img = (CircleImageView) newsViewHolder.getBinding().getRoot().findViewById(R.id.circular_image_selected);
img.setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.SRC_ATOP);
newsViewHolder.getBinding().getRoot().findViewById(R.id.circular_image_unselected).setVisibility(View.INVISIBLE);
}
newsViewHolder.getBinding().setVariable(BR.clickListener,
new RecyclerViewOnItemClickHandler<>(item, position, listener));
newsViewHolder.getBinding().setVariable(BR.news, item);
newsViewHolder.getBinding().executePendingBindings();
}
}
Drawable for image background
<?xml version="1.0" encoding="utf-8"?><shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#android:color/transparent" />
<stroke android:color="#android:color/holo_red_dark" android:width="3dp"/>
<size
android:width="100dp"
android:height="100dp"/>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:useLevel="false"
android:thickness="7.8dp"
android:innerRadius="0dp"
>
<solid
android:color="#F00"
/>
<stroke
android:width="1dip"
android:color="#FFF" />
use this as background to you image... increase thickness accordingly.. or if this doesn't work retain the previous background xml and add android:padding around 10 to 15 dp in your imageview
i solve this by placing imageview into relativelayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="5dp"
android:padding="2dp"
android:background="#drawable/imageborder"
android:src="#drawable/placeholder"
android:id="#+id/notificator_image"/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<stroke android:width="2dp"
android:color="#cc195d" />
</shape>

Draw circles inside TextView

I have a calendar that looks like this:
The Class that draws this Calendar is called MonthView and is a TableLayout:
class MonthView extends TableLayout{...}
The function that creates the calendar is shown below:
TextView btn;
TableRow tr;
void DisplayMonth(boolean animationEnabled){
...
for(int i = 0; i < 6; i++){
if(day > cal.getActualMaximum(Calendar.DAY_OF_MONTH))
break;
tr = new TableRow(context);
tr.setWeightSum(0.7f);
for(int j = 0; j < 7; j++){
btn = new TextView(context);
...
}
}
The function that changes the color of the background day is below:
public void changeBackgroundDay(List<Class> classes){
for(int i = 0; i < getChildCount; i++){
TableRow row = (TableRow)getChildAt(i);
for(int j = 0; j < row.getChildCount(); j++){
TextView t = (TextView)row.getChildAt(j);
for(int tam = 0; tam < classes.size(); tam++){
Class class = classes.get(tam);
// ---- THIS IS THE PART THAT I WANT TO CHANGE ----//
if(class.getTypePlanning().equals("null"){
t.setBackgroundColor(Color.parseColor("#777777");
}
else if(class.getTypePlanning().equals("R")){
t.setBackgroundColor(Color.parseColor("#2477B2");
}
// -----------------------------------------------//
...
}
}
}
}
I want to, instead of just changing the background color of the TextView, draw 4 circles on this TextView. In some cases, it can be drawn just 2 or 3. For example, like is shown in the pictures:
I've tried to make a Layer list with items that contains shape and color and defined this Layer list as the background of the TextView, but it didn't work really well.
The Layer list xml is below:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layerlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<item android:id="#+id/itemnaoplanejado"
android:bottom="1dp" android:right="1dp">
<shape android:shape="oval" android:visible="false">
<size android:width="2dp"
android:height="2dp"/>
<solid android:color="#777777"/>
</shape>
</item>
<item android:id="#+id/itemplanejado"
android:bottom="1dp" android:left="1dp">
<shape android:shape="oval" android:visible="false">
<size android:width="2dp"
android:height="2dp"/>
<solid android:color="#8CC9F3"/>
</shape>
</item>
....
</layer-list>
On the function changeBackgroundDay I do this:
public void changeBackgroundDay(List<Class> classes){
...
if(class.getTypePlanning().equals("null"){
LayerDrawable layerDrawable = (LayerDrawable) getResources().getDrawable(R.drawable.layerlistday);
layerDrawable.findDrawableByLayerId(R.id.itemnotplanned).setVisible(true, false);
t.setBackground(layerDrawable);
}
}
Any ideas?
Thanks in advance.
Tyr this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/num_txt"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="0dp"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:textSize="10dp" />
</RelativeLayout>
</RelativeLayout>
save in drwable bg_red.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<corners android:radius="10dip"/>
<stroke android:color="#FF0000" android:width="5dip"/>
<solid android:color="#FF0000"/>
</shape>
Edited Code -----
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<TextView
android:id="#+id/num_txt"
android:layout_width="185dp"
android:layout_height="185dp"
android:layout_alignParentTop="true"
android:layout_marginTop="163dp"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:layout_marginLeft="10dp"
android:textSize="10dp" />
<TextView
android:id="#+id/TextView02"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/TextView01"
android:layout_marginRight="90dp"
android:layout_marginTop="122dp"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:textSize="10dp" />
<TextView
android:id="#+id/TextView01"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_alignTop="#+id/num_txt"
android:layout_toRightOf="#+id/num_txt"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:textSize="10dp" />
</RelativeLayout>

ListView performance lower on 4.2 than on 4.1

I have just upgraded on Android 4.2 on my Galaxy Nexus and ListView seems to be slower than It used to be on 4.1. This bindView method was perfect fast on 4.1, on new 4.2 I see small glitches. I have tried to explicitly enable hardware acceleration in AndroidManifest.xml, but it dit not help much. People (Contacts) app works perfect on 4.2, which I guess is also implemented by extended android.support.v4.widget.CursorAdapter. I have also already tried to change android.support.v4.widget.CursorAdapter for android.widget.CursorAdapter without visible improvement.
#Override
public void bindView(View view, Context context, Cursor cursor) {
final ViewHolder holder = (ViewHolder) view.getTag();
holder.nameView.setText(cursor.getString(mStreetColumnIndex));
holder.townView.setText(cursor.getString(mTownColumnIndex));
if (mDistanceColumn != null) {
float distance = cursor.getFloat(mDistanceColumn);
String distanceUnit;
if (distance >= 1000) {
distance /= 1000;
distanceUnit = " km";
} else {
distanceUnit = " m";
}
String decimalString = mDecimalFormat.format(distance);
holder.distanceView.setText(decimalString + distanceUnit);
holder.distanceView.setVisibility(View.VISIBLE);
} else {
holder.distanceView.setVisibility(View.GONE);
}
// read only brand first letter to be faster
cursor.copyStringToBuffer(mBrandColumnIndex, mBuffer);
if (mBuffer.sizeCopied > 0) {
if (mBuffer.data[0] == 'a') {
holder.logoImgView.setImageResource(R.drawable.agip);
} else {
holder.logoImgView.setImageResource(R.drawable.papoil);
}
} else {
holder.logoImgView.setVisibility(View.INVISIBLE);
}
}
EDIT: added row 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="wrap_content"
android:minHeight="#dimen/row_height"
android:background="#drawable/bg_list_selector"
android:layout_marginRight="#dimen/screen_padding"
android:layout_marginLeft="#dimen/screen_padding"
android:paddingLeft="#dimen/screen_padding">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_marginRight="#dimen/screen_padding"
android:layout_toLeftOf="#+id/txtDistance"
android:orientation="vertical"
>
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/list_text_primary_size"
android:textStyle="bold"
/>
<TextView
android:id="#+id/txtTown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/list_text_primary_size"
/>
</LinearLayout>
<TextView
android:id="#+id/txtDistance"
android:layout_toLeftOf="#+id/imgLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="#color/grey_dark"
android:textSize="13sp"
android:textStyle="bold"
android:layout_marginRight="#dimen/screen_padding"/>
<ImageView
android:id="#+id/imgLogo"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/agip"
android:background="#color/grey_dark"
/>
</RelativeLayout>
EDIT 2:
here is traceview http://goo.gl/UmS3w
which was made using http://goo.gl/Yoe1u
It was caused by too much complicated windowBackground, which was:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/bg_repeat">
</item>
<item>
<shape>
<gradient android:startColor="#0affffff" android:endColor="#0a000000"
android:type="radial" android:gradientRadius="500"/>
</shape>
</item>
<item>
<shape>
<gradient android:startColor="#1effffff" android:endColor="#1e000000"
android:type="linear" android:angle="270"/>
</shape>
</item>
</layer-list>
and bg_repeat.xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/bg"
android:tileMode="repeat"/>
Thanks all for help!

Categories

Resources