1

Is there any way to add stroke/outline to buttons with java rather than XML? I've been trying to research it and everything I have come across is all XML.

What I'm looking to do is have a button have a black border by default. Then after it's pressed the color would change to red.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
John Leo
  • 55
  • 7

3 Answers3

1

In Java you can achieve like this,

    public Drawable getMyDrawable() {
        StateListDrawable states = new StateListDrawable();

//        states.addState(new int[]{
//                -android.R.attr.state_enabled,
//        }, getDisableDrawable());

        states.addState(new int[]{
                android.R.attr.state_focused, -android.R.attr.state_pressed,
        }, getDrawable(true));
        states.addState(new int[]{
                android.R.attr.state_focused, android.R.attr.state_pressed,
        }, getDrawable(true));
        states.addState(new int[]{
                -android.R.attr.state_focused, android.R.attr.state_pressed,
        }, getDrawable(true));
        states.addState(new int[]{
                android.R.attr.state_enabled
        }, getDrawable(false));

        return states;
    }

    public Drawable getDrawable(boolean pressed) {
        Drawable[] normalDrawable = new Drawable[2];
        normalDrawable[0] = getRectBorder(pressed);
        normalDrawable[1] = getRectBG();

        LayerDrawable layerDrawable = new LayerDrawable(normalDrawable);
        layerDrawable.setLayerInset(1, 2, 2, 2, 2);

        return layerDrawable.mutate();
    }

    public Drawable getRectBorder(boolean pressed) {
        RectShape rectShape = new RectShape();
        ShapeDrawable shapeDrawable = new ShapeDrawable(rectShape);
        shapeDrawable.getPaint().setColor(pressed ? Color.RED : Color.BLACK);
        shapeDrawable.getPaint().setStyle(Paint.Style.STROKE);
        shapeDrawable.getPaint().setStrokeWidth(2);
        shapeDrawable.getPaint().setAntiAlias(true);
        shapeDrawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
        return shapeDrawable.mutate();
    }

    public Drawable getRectBG() {
        RectShape rectShape = new RectShape();
        ShapeDrawable shapeDrawable = new ShapeDrawable(rectShape);
        shapeDrawable.getPaint().setColor(Color.WHITE);
        shapeDrawable.getPaint().setStyle(Paint.Style.FILL);
        shapeDrawable.getPaint().setAntiAlias(true);
        shapeDrawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
        return shapeDrawable.mutate();
    }

Finally in your button you can set like this,

Button button = (Button) findViewById(R.id.button);

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
    button.setBackgroundDrawable(getMyDrawable());
} else {
    button.setBackground(getMyDrawable());
}
Muthukrishnan Rajendran
  • 11,122
  • 3
  • 31
  • 41
0

I think what you really need is to create a selector and use it as button background

no need to handle the cases your self in java

button_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/button_bg_selected" android:state_selected="true"></item>
    <item android:drawable="@drawable/button_bg_pressed" android:state_pressed="true"></item>
    <item android:drawable="@drawable/button_bg_normal"></item>

</selector>

and use it in the button

<Button
     android:id="@+id/button1"
     android:background="@drawable/selector_xml_name"
     android:layout_width="200dp"
     android:layout_height="126dp"
     android:text="Hello" />

for more info see this question

humazed
  • 74,687
  • 32
  • 99
  • 138
0

The simplest way is put Button inside any layout with margin. Margin size become border size. Then when you clicked just change layout background.

<LinearLayout android:orientation="vertical" 
    android:id="btn_container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/black_alpha2">
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorWhite"
    android:text="Click me"
    android:layout_margin="2dp"/>

Like above. It`s bit difficult to when use default button background

Then change container layout background when btn clicked or anything you need to change

public void onClickBtn(View view){
  btnContainer.setBackground()
}
Fr099y
  • 734
  • 7
  • 15