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

Android中实现平行四边形ImageView:解决skew/matrix顶部截断问题

实现无内容截断的平行四边形ImageView

你遇到的内容截断问题,本质是直接用skew/matrix变换时,控件的实际布局边界没跟着调整,导致超出部分被裁剪了。下面给你两种靠谱的解决方法:

方法一:用Drawable遮罩实现(无需自定义View)

这种方法通过叠加平行四边形遮罩,同时调整padding来适配倾斜,不会截断内容。

  1. 创建平行四边形遮罩的shape文件(res/drawable/parallelogram_mask.xml):
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@android:color/white" />
    <transform>
        <skew android:skewX="-15" /> <!-- 调整倾斜角度,负数左斜、正数右斜 -->
    </transform>
    <padding android:left="25dp" android:right="0dp" /> <!-- 适配倾斜的内边距,按需调整 -->
</shape>
  1. 创建LayerDrawable组合原图和遮罩(res/drawable/image_parallelogram.xml):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/your_target_image" /> <!-- 替换成你的图片 -->
    <item android:drawable="@drawable/parallelogram_mask" />
</layer-list>
  1. 在布局中使用ImageView:
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/image_parallelogram"
    android:paddingLeft="25dp"
    android:scaleType="centerCrop" />

方法二:自定义ImageView(灵活度更高)

通过重写测量和绘制方法,主动调整控件边界和画布,从根源避免截断。

自定义View代码:

public class ParallelogramImageView extends AppCompatImageView {
    private static final float SKEW_ANGLE = -15f; // 倾斜角度,按需修改
    private final float skewRadian = Math.abs(SKEW_ANGLE) * Math.PI / 180;

    public ParallelogramImageView(Context context) {
        super(context);
        init();
    }

    public ParallelogramImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        setLayerType(LAYER_TYPE_SOFTWARE, null); // 关闭硬件加速避免画布变换异常
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 补偿倾斜带来的宽度增量,确保内容能完整显示
        float extraWidth = getMeasuredHeight() * (float) Math.tan(skewRadian);
        setMeasuredDimension((int) (getMeasuredWidth() + extraWidth), getMeasuredHeight());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        // 计算偏移量,让内容在平行四边形内居中
        float offset = getHeight() * (float) Math.tan(skewRadian);
        // 执行倾斜变换
        canvas.skew(SKEW_ANGLE / 180 * Math.PI, 0);
        // 裁剪画布到平行四边形区域,避免内容溢出
        canvas.clipRect(offset, 0, getWidth(), getHeight());
        // 绘制原图
        super.onDraw(canvas);
        canvas.restore();
    }
}

布局中使用:

<com.yourpackage.ParallelogramImageView
    android:layout_width="220dp"
    android:layout_height="160dp"
    android:src="@drawable/your_target_image"
    android:scaleType="centerCrop" />

两种方法都能解决截断问题,方法一适合快速实现,方法二更适合需要动态调整倾斜角度的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:38:26