4

私は単純なプロジェクトに取り組んでおり、PNG 画像をできるだけ避けたいと考えています。「+」(追加)ボタンが必要で、指定されたコードで ShapeDrawable を使用して作成しました。

res/drawable/plus_icon_drawable.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="line">
            <stroke android:color="#000"
                android:width="3dp"/>
        </shape>
    </item>
    <item>
        <rotate
            android:fromDegrees="90"
            android:toDegrees="90">
            <shape android:shape="line">
                <stroke android:color="#000"
                    android:width="3dp"/>
            </shape>
        </rotate>
    </item>
</layer-list>

このコードを Button または ImageButton の背景として追加すると正常に動作しますが、これを ActionBar アイテムのアイコンとして追加すると、アイテムが表示されません。

PNG 画像をアイコンとして設定すると、正常に動作します。ActionBar でのレンダリングをブロックする ShapeDrawables に制限はありますか?

これは私の ActiobBar コードです

res/menu/action_my_actions.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_some_id"
        android:icon="@drawable/plus_icon_drawable"
        android:title="My Action"
        android:showAsAction="always"/>
</menu>

更新 (2014 年 7 月 8 日): Native と AppCompat の両方でテスト済み。実際にはアイテムはそこに存在しますが、ShapeDrawable 画像はレンダリングされません。アクション アイテムはクリックに反応します。

ここで何が欠けていますか?

4

1 に答える 1

3

ActionBar でのレンダリングをブロックする ShapeDrawables に制限はありますか?

そのような何もありません。それはまさに物事のあり方です。これが表示される理由は次のとおりです。

Layer/ShapeDrawablesデフォルトのサイズはありません。言い換えれば、 aShapeDrawableの幅と高さがゼロであってもまったく問題ありません。stroke-width パラメータも何も指定しません。

このコードを Button または ImageButton の背景として追加すると正常に動作しますが、これを ActionBar アイテムのアイコンとして追加すると、アイテムが表示されません。

はい、もちろん。ImageButtons/Buttonsパディング/最小幅/最小高さの概念があります。これらにより、ShapeDrawable息をする余地ができます。たとえば、 でスタイル設定された ButtonWidget.Holo.Buttonには、minWidthandminHeightが設定されます。

<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 ドローアブルを使用する場合は、それ自体がサイズを定義します。上記の例では、明示的なサイズ (たとえば 50 dp) を使用すると、ShapeDrawable visible.

これはActionMenuItemView、ドローアブルを設定する方法です:

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_widthandが定義されていない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 で定義されているデフォルトのアクション バー サイズ値です。

最後に、次のように使用actionBarSizeDpplus_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実際、 の1 つを定義するだけでLayerDrawables十分です。他のものはそれに応じて描画されます。

于 2014-08-04T20:11:55.903 に答える