我正在开发Android应用程序,我有一个AlertDialog子类。我想在对话框的标题区域的右侧放置2个ImageButtons(类似于Activity中的ActionBar)。我正在使用setCustomTitle()执行此操作,它将标题区域替换为我自己创建的自定义视图。这很好用,但我的自定义标题区域的样式与标准标题样式(高度,颜色,分隔符等)不同。
我的问题是:了解样式因OS版本和制造商而异,如何在对话框中设置自定义标题的样式,使其与其他AlertDialogs的标准样式样式相匹配?< / p>
以下是具有标准样式的anAlertDialog图像(这是来自ICS,但我希望能够匹配任何变体 - 而不是这种特殊样式)
这是一个带有自定义标题和按钮的AlertDialog图像(注意标题高度和颜色与标准对话框的匹配程度)
编辑:我不能只将ImageButtons添加到标准标题视图中,因为我无法访问它。 如果你知道(可靠的,非黑客的)方法让我在标准标题区域添加按钮,我也会接受。
答案 0 :(得分:10)
鉴于对这个问题有新的兴趣,让我详细说明我是如何“解决”这个问题的。
首先,我在我的应用中使用ActionBarSherlock。我认为这不是必需的,尽管它有很大帮助,因为ABS项目中定义的样式和主题允许我模仿ICS前设备上的Holo主题,从而在应用程序中提供一致的体验。
其次,我的“对话框”不再是对话框 - 它是一个以对话框为主题的活动。这使得视图层次结构的操作更简单,因为我有完全的控制权。因此,在标题区域添加按钮现在很简单。
以下是截图(2.2设备和4.1模拟器)。请注意,唯一重要的样式差异是EditText,我选择不解决。
这是我在对话框活动中的onCreate:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_tag);
setTitle(R.string.tag_dialog_title);
View sherlockTitle = findViewById(android.R.id.title);
if (sherlockTitle != null) {
sherlockTitle.setVisibility(View.GONE);
}
View sherlockDivider = findViewById(R.id.abs__titleDivider);
if (sherlockDivider != null) {
sherlockDivider.setVisibility(View.GONE);
}
// setup custom title area
final View titleArea = findViewById(R.id.dialog_custom_title_area);
if (titleArea != null) {
titleArea.setVisibility(View.VISIBLE);
TextView titleView = (TextView) titleArea.findViewById(R.id.custom_title);
if (titleView != null) {
titleView.setText(R.string.tag_dialog_title);
}
ImageButton cancelBtn = (ImageButton) titleArea.findViewById(R.id.cancel_btn);
cancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
cancelBtn.setVisibility(View.VISIBLE);
ImageButton okBtn = (ImageButton) titleArea.findViewById(R.id.ok_btn);
okBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do stuff here
finish();
}
});
okBtn.setVisibility(View.VISIBLE);
}
}
以下是活动的相关布局:
<LinearLayout
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<LinearLayout
android:id="@+id/dialog_custom_title_area"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingRight="10dp">
<TextView
android:id="@+id/custom_title" style="?android:attr/windowTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="@dimen/abs__alert_dialog_title_height"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:textColor="#ffffff"
android:gravity="center_vertical|left" />
<ImageButton
android:id="@+id/ok_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="@dimen/abs__action_button_min_width"
android:minHeight="@dimen/abs__alert_dialog_title_height"
android:scaleType="center"
android:src="@drawable/ic_action_accept"
android:background="@drawable/abs__item_background_holo_dark"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:contentDescription="@string/acc_done"/>
<ImageButton
android:id="@+id/cancel_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="@dimen/abs__action_button_min_width"
android:minHeight="@dimen/abs__alert_dialog_title_height"
android:scaleType="center"
android:src="@drawable/ic_action_cancel"
android:background="@drawable/abs__item_background_holo_dark"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:contentDescription="@string/acc_cancel"
/>
</LinearLayout>
<View
android:id="@+id/dialog_title_divider"
android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="@color/abs__holo_blue_light" />
</LinearLayout>
<RelativeLayout
android:id="@+id/list_suggestions_layout"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<!-- this is where the main dialog area is laid out -->
</RelativeLayout>
</LinearLayout>
最后,在我的AndroidManifext.xml中,以下是我定义TagActivity的方法:
<activity
android:icon="@drawable/ic_home"
android:name=".activity.TagActivity"
android:theme="@style/Theme.Sherlock.Dialog"/>
答案 1 :(得分:0)
好吧,也许这不是超级完美的解决方案,也许这是一个糟糕的解决方案,但我在Android 2.3.7和Android 4.1.2上试过这个:
<强> 2.3.7 (real device)
强>
<强> 4.1.2 (emulator)
强>
我们首先创建一个对话框标题样式,以确保我们的图标有一些空间:
<强> res/values/dialogstyles.xml
强>
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowTitleStyle">@style/MyOwnDialogTitle</item>
</style>
<style name="MyOwnDialogTitle">
<!-- we need to make sure our images fit -->
<item name="android:layout_marginRight">100dp</item>
</style>
</resources>
<强> res/values-v11/dialogstyles.xml
强>
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Dialog" parent="@android:style/Theme.Holo.Dialog">
<item name="android:windowTitleStyle">@style/MyOwnDialogTitle</item>
</style>
</resources>
然后我们用两个技巧创建DialogFragment:
在onCreate
:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.Dialog);
}
覆盖onCreateView
并将我们的布局(按钮)添加到对话框中(参见评论)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//we need the view to remove the tree observer (that's why it is final)
final View view = inflater.inflate(R.layout.dialog_custom, container);
getDialog().setTitle("Shush Dialog");
//register a layout listener to add our buttons
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
//inflate our buttons
View menu = LayoutInflater.from(getActivity()).inflate(R.layout.layout_mymenu, null);
//get the root view of the Dialog (I am pretty sure this is the weakest link)
FrameLayout fl = ((FrameLayout) getDialog().getWindow().getDecorView());
//get the height of the root view (to estimate the height of the title)
int height = fl.getHeight() - fl.getPaddingTop() - fl.getPaddingBottom();
//to estimate the height of the title, we subtract our view's height
//we are sure we have the heights btw because layout is done
height = height - view.getHeight();
//prepare the layout params for our view (this includes setting its width)
//setting the height is not necessary if we ensure it is small
//we could even add some padding but anyway!
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, height);
params.gravity = Gravity.RIGHT | Gravity.TOP;
//add the view and we are done
fl.addView(menu, params);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
return view;
}
答案 2 :(得分:-2)
好吧,如果它只是图像,那么你只需要确保你在xml中创建的所有内容都按密度像素或DP缩放。设置绘画的大多数简单编码通常也按像素设置,并且可能需要手动编码版本来密度像素。