You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API≥21下以代码方式居中layer-list中的Drawable?

Hey there! Let's tackle this problem of centering your ic_audio icon without relying on API 23+ methods. I've got a couple of solid solutions depending on whether you're defining your layer-list in XML or building it dynamically in code.

Solution 1: Define the Layer List in XML (Simplest, Works for API 21+)

If you can create your layer-list via XML (instead of code), you don't need to worry about API version restrictions at all. Just add android:gravity="center" directly to the icon item—it's fully compatible with API 21 and below. Here's the corrected XML:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#1e1e1e" />
            <size android:height="45dp" android:width="82dp" />
        </shape>
    </item>
    <!-- Add android:gravity="center" here to keep the icon sized correctly and centered -->
    <item 
        android:drawable="@drawable/ic_audio" 
        android:gravity="center" />
</layer-list>

The android:gravity="center" attribute on the item tells Android to keep the drawable's original size and position it in the center of the layer, instead of stretching it to fill the entire layer bounds. This works perfectly on API 21—no code hacks needed.

Solution 2: Dynamically Adjust Bounds (For Code-Defined LayerDrawables)

If you're building the LayerDrawable programmatically and can't use XML, you can manually calculate and set the bounds of your icon drawable to center it. This uses methods that are available since API 1, so it's fully compatible with API 21.

Here's how to do it:

// Get your base layer drawable and the icon drawable
LayerDrawable layerDrawable = (LayerDrawable) getResources().getDrawable(R.drawable.your_base_layer);
Drawable iconDrawable = getResources().getDrawable(R.drawable.ic_audio);

// Calculate the center position
int containerWidth = layerDrawable.getIntrinsicWidth();
int containerHeight = layerDrawable.getIntrinsicHeight();
int iconWidth = iconDrawable.getIntrinsicWidth();
int iconHeight = iconDrawable.getIntrinsicHeight();

int leftOffset = (containerWidth - iconWidth) / 2;
int topOffset = (containerHeight - iconHeight) / 2;

// Set the bounds of the icon to center it within the container
iconDrawable.setBounds(leftOffset, topOffset, leftOffset + iconWidth, topOffset + iconHeight);

// Replace the icon layer in the LayerDrawable
layerDrawable.setDrawableByLayerId(R.id.icon_layer, iconDrawable); // Or use index if you don't have an ID

// Assign the updated LayerDrawable to your view
yourView.setBackground(layerDrawable);

How this works:

  • We calculate the difference between the container's size and the icon's size, then split that difference equally between the left/right and top/bottom offsets.
  • Calling setBounds() manually positions the icon exactly where we want it, bypassing the default behavior of stretching the drawable to fill the layer.

Why the Icon Stretches Without Gravity

When you don't set gravity on the layer item, Android defaults to scaling the drawable to fill the entire bounds of the layer. By either using the XML gravity attribute or manually setting the bounds, you override this default behavior and keep the icon's original size while centering it.

内容的提问来源于stack exchange,提问作者Ashuthosh Patoa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:37:48