Is it possible to add drawables to the positive, negative and neutral buttons of an AlertDialog? If yes, then how?
After you have built the AlertDialog
in onCreateDialog
you can use the following code in onPrepareDialog
to add an image to the positive button:
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
AlertDialog alertDialog = (AlertDialog)dialog;
Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
button.setCompoundDrawablesWithIntrinsicBounds(this.getResources().getDrawable(
R.drawable.icon), null, null, null);
}
Trying to add the drawable to the button in the onCreateDialog
method does not seem to work.
As @aaronvargas said, use onShowListener
. I will improve his answer a little bit, since for older/smaller devices the image overlaps the text. Here is the onShow
code:
@Override
public void onShow(DialogInterface dialogInterface) {
Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.your_img, 0, 0, 0);
Utils.centerImageAndTextInButton(button);
}
Here is an utility function to center a left image and text inside a Button
:
public static void centerImageAndTextInButton(Button button) {
Rect textBounds = new Rect();
//Get text bounds
CharSequence text = button.getText();
if (text != null && text.length() > 0) {
TextPaint textPaint = button.getPaint();
textPaint.getTextBounds(text.toString(), 0, text.length(), textBounds);
}
//Set left drawable bounds
Drawable leftDrawable = button.getCompoundDrawables()[0];
if (leftDrawable != null) {
Rect leftBounds = leftDrawable.copyBounds();
int width = button.getWidth() - (button.getPaddingLeft() + button.getPaddingRight());
int leftOffset = (width - (textBounds.width() + leftBounds.width()) - button.getCompoundDrawablePadding()) / 2 - button.getCompoundDrawablePadding();
leftBounds.offset(leftOffset, 0);
leftDrawable.setBounds(leftBounds);
}
}
This last function uses the width of the Button
to make the calculation, so you must check that you are calling this in the right place. That is, the width should be other than zero. In this case, calling it from onShow
is the right place :).
This can be done by getting a reference to the button using the getButton() method:
alert.show();
Button email = alert.getButton(AlertDialog.BUTTON_NEUTRAL);
email.setBackgroundResource(R.drawable.email);
Note that you must use the getButton() AFTER calling the show() method, otherwise you'll get a NullPointerException..
Since onPrepareDialog
is deprecated, you can use the onShowListener
instead.
Also you should set the Drawable bounds or it will be placed far left.
Output of Code below
public class MyDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog dialog = new AlertDialog.Builder(getActivity())
.setTitle("My Dialog")
.setNegativeButton("Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).setPositiveButton("Play", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).create();
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
// if you do the following it will be left aligned, doesn't look
// correct
// button.setCompoundDrawablesWithIntrinsicBounds(android.R.drawable.ic_media_play,
// 0, 0, 0);
Drawable drawable = getActivity().getResources().getDrawable(
android.R.drawable.ic_media_play);
// set the bounds to place the drawable a bit right
drawable.setBounds((int) (drawable.getIntrinsicWidth() * 0.5),
0, (int) (drawable.getIntrinsicWidth() * 1.5),
drawable.getIntrinsicHeight());
button.setCompoundDrawables(drawable, null, null, null);
// could modify the placement more here if desired
// button.setCompoundDrawablePadding();
}
});
return dialog;
}
}
You can't add buttons in the onCreateDialog and MUST do it in the onPrepareDialog because AlertDialog are handled in a very special way by android :
you actually don't really hold a reference to the real dialog when you use alert dialog, the object you get by using AlertDialog.Builder.create() is just a face to an inner controller.
And before create is actually called, there is no such controller in the jvm. Just the facade. So, until this method is called (at the end of onCreateDialog if you let your activity manage its own dialogs), the real controller doesn't exist, and real buttons don't neither.
brand new SOF commenter, Stéphane
1.first create a new layout file to store the imagebuttons:new_layout.xml;
<?xml version="1.0" encoding="UTF-8" ?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="15dp"
android:gravity="center_horizontal"
android:background = "#FFFFFF"
android:orientation="horizontal">
<!-- game button -->
<ImageButton
android:id="@+id/game"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="5dp"
android:layout_gravity="bottom"
android:background = "#00ffffff"
android:src="@drawable/game"/>
<!-- browser button -->
<ImageButton
android:id="@+id/browser"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="5dp"
android:layout_gravity="bottom"
android:background = "#00ffffff"
android:src="@drawable/browser"/>
<!-- email button -->
<ImageButton
android:id="@+id/email"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="5dp"
android:layout_gravity="bottom"
android:background = "#00ffffff"
android:src="@drawable/email"/>
</LinearLayout>
2.add the code below to where you want the dialogue to show:
final AlertDialog alertDialog = new AlertDialog.Builder(TalkerActivity.this).create();
alertDialog.show();
Window win = alertDialog.getWindow();
win.setContentView(R.layout.new_layout);
//Game
ImageButton game_btn = (ImageButton)win.findViewById(R.id.game);
game_btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
//Browser
ImageButton browser_btn = (ImageButton)win.findViewById(R.id.browser);
browser_btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
//Email
ImageButton email_btn = (ImageButton)win.findViewById(R.id.email);
email_btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
link:http://blog.csdn.net/willproud/article/details/9191971