How to Use and Style New Alertdialog from Appcompat 22.1 and Above

How to use and style new AlertDialog from appCompat 22.1 and above

When creating the AlertDialog you can set a theme to use.

Example - Creating the Dialog

AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.MyAlertDialogStyle);
builder.setTitle("AppCompatDialog");
builder.setMessage("Lorem ipsum dolor...");
builder.setPositiveButton("OK", null);
builder.setNegativeButton("Cancel", null);
builder.show();

styles.xml - Custom style

<style name="MyAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<!-- Used for the buttons -->
<item name="colorAccent">#FFC107</item>
<!-- Used for the title and text -->
<item name="android:textColorPrimary">#FFFFFF</item>
<!-- Used for the background -->
<item name="android:background">#4CAF50</item>
</style>

Result

styled alertdialog

Edit

In order to change the Appearance of the Title, you can do the following. First add a new style:

<style name="MyTitleTextStyle">
<item name="android:textColor">#FFEB3B</item>
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Title</item>
</style>

afterwards simply reference this style in your MyAlertDialogStyle:

<style name="MyAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
...
<item name="android:windowTitleStyle">@style/MyTitleTextStyle</item>
</style>

This way you can define a different textColor for the message via android:textColorPrimary and a different for the title via the style.

Custom AlertDialog style Theme.AppCompat.Light.Dialog.Alert

You can do it without using custom style or inflating the custom view like below code.

public void createDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to exit from app");
builder.setCancelable(false);
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});

builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(ViewPagerStyle1Activity.this,
"You exit from app", Toast.LENGTH_LONG).show();

}
});

AlertDialog alert = builder.create();
alert.show();
TextView messageText = (TextView) alert
.findViewById(android.R.id.message);
messageText.setBackgroundColor(Color.RED);
Button nbutton = alert.getButton(DialogInterface.BUTTON_NEGATIVE);
nbutton.setBackgroundColor(Color.MAGENTA);
Button pbutton = alert.getButton(DialogInterface.BUTTON_POSITIVE);
pbutton.setBackgroundColor(Color.YELLOW);
}

Inheriting AppCompat 22.1.1 Dialog colorAccent from app theme doesn't work

<item name="colorAccent">?attr/colorAccent</item>

You already know that this doesn't work. Here's why:

ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
uint32_t* outTypeSpecFlags) const
{
int cnt = 20;

if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;

do {
....
....
if (type == Res_value::TYPE_ATTRIBUTE) {
if (cnt > 0) {
cnt--;
resID = te.value.data;
continue;
}
ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
return BAD_INDEX;
}
....
....
} while (true);

return BAD_INDEX;
}

The snippet is self-explanatory. You can have:

<item name="colorZ" >?attr/colorY</item> 

and then:

<item name="colorY" >?attr/colorX</item> 

....
....

But chaining attributes like this cannot be more that 20 levels deep. Android gives up because of Too many attribute references....

In your case, you are setting an attribute's value by trying to read its present value. Android goes looking, but finds another reference instead - endless pursuit.

Why did it work before?

<style name="AppTheme" parent="@style/Theme.AppCompat">
<item name="colorAccent">#FF9800</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>

<style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert">
<item name="android:colorAccent">?attr/colorAccent</item>
</style>

In AppTheme, you are setting support library's colorAccent attribute (no android: namespace). Under AlertDialogTheme, you set android:colorAccent to support library's colorAccent. This is why an endless loop does not take shape.

?attr/colorAccent is resolved within the Context you pass when creating the AlertDialog. For this reason, it is resolved against <item name="colorAccent">#FF9800</item>.

One possible workaround would be to define a custom attr in res/values/attrs.xml:

<attr name="alertDialogColorAccent" format="reference|color"/>

Now, we can initialize this attribute under AppTheme:

<style name="AppTheme" parent="@style/Theme.AppCompat">
<item name="colorAccent">#FF9800</item>
<item name="alertDialogColorAccent" >?attr/colorAccent</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>

and use it in AlertDialogTheme:

<style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert">
<item name="colorAccent">?attr/alertDialogColorAccent</item>
</style>

BUT, this will still not work. Its still creates a cycle - colorAccent is alertDialogColorAccent & alertDialogColorAccent is colorAccent. Somewhere along the chain, an actual color value needs to be set:

<style name="AppTheme" parent="@style/Theme.AppCompat">
<item name="colorAccent">#FF9800</item>
<item name="alertDialogColorAccent" >#FF9800</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>

Now, you can initialize colorAccent with alertDialogColorAccent since it refers to an actual color value:

<style name="AlertDialogTheme" parent="android:Theme.Material.Dialog.Alert">
<item name="colorAccent">?attr/alertDialogColorAccent</item>
</style>

AlertDialog AppCompat width and height

If it is a customizes dialog box then you can set the height and width in new created XML file only. but if you are using AlertDialog.builder then use this.

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
builder.setTitle("Title");
alertDialog = builder.create();
alertDialog.show();
alertDialog.getWindow().setLayout(600, 400); //Controlling width and height.

And follow this Hope it may help you out.

AlertDIalog Remove unnecessary space

I have tried with changing window attributes sizes but did not achieve what you wanted. Then I replaced your existing style Theme.AppCompat.Light.Dialog.Alert with @style/Theme.AppCompat.Dialog. Now this let us take control over layout.

Changed to:

    <style name="CustomDialog" parent="@style/Theme.AppCompat.Dialog">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:windowNoTitle">true</item>
</style>

In your layout file, I removed redundant LinearLayout.

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:padding="16dp">

<androidx.appcompat.widget.AppCompatToggleButton
android:id="@+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="#43212121"
android:checked="true"
android:textOff="Camera"
android:textOn="Camera"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/two"
app:layout_constraintTop_toTopOf="parent" />

<androidx.appcompat.widget.AppCompatToggleButton
android:id="@+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#43212121"
android:checked="true"
android:textOff="Lidar"
android:textOn="Lidar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<androidx.appcompat.widget.AppCompatToggleButton
android:id="@+id/three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:background="#43212121"
android:checked="true"
android:textOff="Sonar"
android:textOn="Sonar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/two"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

In your java code, I am not sure if I made changes so I will just paste it.

private void showDialogHere() {

AlertDialog.Builder obstacleDialogBuilder = new AlertDialog.Builder(this, R.style.CustomDialog);
obstacleDialogBuilder.setMessage(null);

LayoutInflater inflaterObstacle = this.getLayoutInflater();
View obstacleDialogView = inflaterObstacle.inflate(R.layout.my_dialog, null);
obstacleDialogBuilder.setView(obstacleDialogView);

AlertDialog obstacleAlertDialog = obstacleDialogBuilder.create();
obstacleAlertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

Window window = obstacleAlertDialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();

params.gravity = Gravity.TOP | Gravity.RIGHT;
params.x = 100; //x position
params.y = 100; //y position

obstacleAlertDialog.show();
}

Let me know if this works.

I will further try to understand why the style was not letting change the dialog size. I will post if i found anything useful.

I also found this solution working in your case Another answer.

Appcompat Alert Dialog Action button background On pressed state

You can use style attributes like

  • buttonBarButtonStyle
  • buttonBarNegativeButtonStyle
  • buttonBarNeutralButtonStyle
  • buttonBarPositiveButtonStyle

Example:

<style name="dialog_theme" parent="Theme.AppCompat.Dialog.Alert">
<item name="buttonBarNegativeButtonStyle">@style/dialog_button.negative</item>
<item name="buttonBarPositiveButtonStyle">@style/dialog_button.positive</item>
</style>

<style name="dialog_button">
<item name="android:textStyle">bold</item>
<item name="android:minWidth">64dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:background">@drawable/dialogButtonSelector</item>
</style>

<style name="dialog_button.negative">
<item name="android:textColor">#f00</item>
</style>

<style name="dialog_button.positive">
<item name="android:layout_marginLeft">8dp</item>
<item name="android:textColor">#00f</item>
</style>

Where dialogButtonSelector is our custom drawable selector.

Unfortunatelly setting background on dialog_button destroy our paddings and margins so I need to set it again.

dialog_button style can inherit through Widget.AppCompat.Button.ButtonBar.AlertDialog but I found that it has missing styles like textStyle bold.



Related Topics



Leave a reply



Submit