Search code examples
javaandroidlayoutandroid-buttonandroid-styles

Android Buttons look different when added by code


I found that a button that is added to a layout by code looks very different than a button defined in xml.
I made a short example.

Here is the layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <LinearLayout
        android:id="@+id/viewCommands"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button in xml"
            />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

This is the code

Button btn = new Button(this);
btn.setText("button by code");
btn.setBackgroundColor(0xff00e033);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.WRAP_CONTENT);

LinearLayout lo = findViewById(R.id.viewCommands);
lo.addView(btn, lp);

And this is what it looks like. Quite different, isn't it?
example image

I did not add any style to the button in code except background color, so no wonder it's so boring.
But I also didn't add anything in xml and as both buttons land in the same layout. If the layout adds style to elements, what's the difference?

I would appreciate to get some more insight in this.
How can I make the code-added buttons look the same as those coming from xml?

please see that in contrast to many other questions I found, this question is not about different look on different devices, Android versions, frameworks, resolutions, apps... it's in the very same layout.


Solution

  • My app style seems to be inherited from Theme.Material3.DayNight.NoActionBar. Now what do I have to specify for my button to use this style?

    So, the idea is that the XML abstract Button is automatically converted to the appropriate button version that comply with the app theme. That is not the case when it comes to do that programmatically because the exact Java/Kotlin Button class is already specified and imported.

    The referenced answer is suitable for Theme.AppCompat (Material 1) where its Button version is AppCompatButton.

    Starting from Material components (Material 2 library), the Button version is the MaterialButton which extends from the AppCompatButton but has a different/enhanced style.

    As you use Material3 library, then you need to use MaterialButton instead of Button programmatically:

    MaterialButton btn = new MaterialButton(this);
    ...