ShapeDrawables 是否有任何限制阻止它在 ActionBar 上呈现?
没有那样的事。事情就是这样。这就是您看到此内容的原因:
Layer/ShapeDrawables
没有默认大小。换句话说,aShapeDrawable
的宽度和高度为零是完全可以的。stroke-width 参数也没有规定任何内容。
当我将其添加为 Button 或 ImageButton 的背景时,此代码可以正常工作,但是当我将其添加为 ActionBar 项目的图标时,该项目不会显示。
是的当然。ImageButtons/Buttons
有填充/最小宽度/最小高度的概念。这些让ShapeDrawable
他们有一些呼吸的空间。例如,样式为 的 ButtonWidget.Holo.Button
将具有minWidth
andminHeight
设置:
<item name="android:minHeight">48dip</item>
<item name="android:minWidth">64dip</item>
这里的有效测试是:
定义ImageView
如下:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/add" />
</RelativeLayout>
上面的ImageView
定义中没有尺寸指南 - 我们使用的是wrap_content
. 什么都不会显示。另一方面,如果您使用 png 可绘制对象,它本身会定义大小。在上面的示例中,使用显式大小(例如 50dp)将使ShapeDrawable
visible
.
这是ActionMenuItemView
设置drawable的方式:
public void setIcon(Drawable icon) {
mIcon = icon;
if (icon != null) {
// Zero in case you don't define the <size />
int width = icon.getIntrinsicWidth();
int height = icon.getIntrinsicHeight();
if (width > mMaxIconSize) {
final float scale = (float) mMaxIconSize / width;
width = mMaxIconSize;
height *= scale;
}
if (height > mMaxIconSize) {
final float scale = (float) mMaxIconSize / height;
height = mMaxIconSize;
width *= scale;
}
icon.setBounds(0, 0, width, height);
}
setCompoundDrawables(icon, null, null, null);
updateTextButtonVisibility();
}
方法片段ShapeDrawable#inflate(...)
:
setIntrinsicWidth((int)
a.getDimension(com.android.internal.R.styleable.ShapeDrawable_width, 0f));
setIntrinsicHeight((int)
a.getDimension(com.android.internal.R.styleable.ShapeDrawable_height, 0f));
如果没有定义,则固有宽度ShapeDrawable_width
和ShapeDrawable_height
高度将设置为零。这意味着,语句icon.setBounds(0, 0, width, height);
(来自 setIcon(Drawable) 方法)实际上是 => icon.setBounds(0, 0, 0, 0);
。
所以,看来我们确实在处理ShapeDrawables
没有尺寸信息的问题。
一个可能的修复:
<shape android:shape="line">
<size android:width="?android:attr/actionBarSize"
android:height="?android:attr/actionBarSize"/>
<stroke android:color="#000"
android:width="3dp"/>
</shape>
但这不起作用——由于某种原因?android:attr/actionBarSize
,它不被视为一个维度。这很奇怪,因为在布局的情况下?android:attr/actionBarSize
提供给它时可以正常工作。android:layout_width
解决方法是定义一个新维度,比如说actionBarSizeDp
并设置它:
在res/values/dimens.xml
:
<dimen name="actionBarSizeDp">48dp</dimen>
在res/values-land/dimens.xml
:
<dimen name="actionBarSizeDp">40dp</dimen>
这些值是 android 自己的 res/values-XX/dimens.xml 中定义的默认操作栏大小值。
最后,actionBarSizeDp
使用plus_icon_drawable.xml
:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="line">
<size android:width="@dimen/actionBarSizeDp"
android:height="@dimen/actionBarSizeDp"/>
<stroke android:color="#000"
android:width="3dp"/>
</shape>
</item>
<item>
<rotate
android:fromDegrees="90"
android:toDegrees="90">
<size android:width="@dimen/actionBarSizeDp"
android:height="@dimen/actionBarSizeDp"/>
<shape android:shape="line">
<stroke android:color="#000"
android:width="3dp"/>
</shape>
</rotate>
</item>
</layer-list>
事实上,定义size
其中之一LayerDrawables
就足够了。其他(S)将相应地绘制。