【发布时间】:2011-04-10 09:58:31
【问题描述】:
是否可以向 AlertDialog 的 positive、negative 和 neutral 按钮添加可绘制对象?如果是,那么如何?
【问题讨论】:
标签: android user-interface controls
是否可以向 AlertDialog 的 positive、negative 和 neutral 按钮添加可绘制对象?如果是,那么如何?
【问题讨论】:
标签: android user-interface controls
由于 onPrepareDialog 已弃用,您可以改用 onShowListener。
您还应该设置 Drawable 边界,否则它将被放置在最左边。
下面的代码输出
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;
}
}
【讨论】:
在onCreateDialog 中构建AlertDialog 后,您可以使用onPrepareDialog 中的以下代码将图像添加到正按钮:
@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);
}
尝试在onCreateDialog 方法中将drawable 添加到按钮似乎不起作用。
【讨论】:
这可以通过使用 getButton() 方法获取对按钮的引用来完成:
alert.show();
Button email = alert.getButton(AlertDialog.BUTTON_NEUTRAL);
email.setBackgroundResource(R.drawable.email);
请注意,您必须在调用 show() 方法后使用 getButton(),否则您将收到 NullPointerException..
【讨论】:
您不能在 onCreateDialog 中添加按钮,必须在 onPrepareDialog 中添加,因为 AlertDialog 是由 android 以一种非常特殊的方式处理的:
当您使用警报对话框时,您实际上并没有真正持有对真实对话框的引用,您通过使用 AlertDialog.Builder.create() 获得的对象只是内部控制器的一张脸。
而在实际调用create之前,jvm中并没有这样的控制器。只是门面。所以,直到这个方法被调用(如果你让你的活动管理它自己的对话框,在 onCreateDialog 的末尾),真正的控制器不存在,真正的按钮也不存在。
全新的 SOF 评论员,Stéphane
【讨论】:
正如@aaronvargas 所说,使用onShowListener。我会稍微改进他的答案,因为对于较旧/较小的设备,图像会与文本重叠。这是onShow 代码:
@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);
}
这是一个实用函数,用于在 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);
}
}
最后一个函数使用Button 的宽度进行计算,因此您必须检查是否在正确的位置调用它。也就是说,宽度不应为零。在这种情况下,从onShow 调用它是正确的地方:)。
【讨论】:
1.首先新建一个布局文件来存放图片按钮: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.将下面的代码添加到您希望显示对话框的位置:
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
}
});
【讨论】: