要实现的效果图如下:

实现此效果的第一思路是使用Path 和canvas实现,path来规定平行四边形。

实现如下

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><com.whuthm.imageshape.TestViewandroid:layout_width="250dp"android:layout_height="150dp"android:layout_centerInParent="true"/></RelativeLayout>

TestView类实现

package com.whuthm.imageshape;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;public class TestView extends ImageView {public TestView(Context context) {this(context, null);}public TestView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public TestView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int width = getWidth();int height = getHeight();Drawable d = getResources().getDrawable(R.drawable.image1);d.setBounds(0, 0, width, height);canvas.save();//一个平行四边形Path path = new Path();path.moveTo(100, 0);path.lineTo(0, height);path.lineTo(width - 100, height);path.lineTo(width, 0);canvas.clipPath(path);//将图像画在canvas上d.draw(canvas);canvas.restore();}}

效果实现,但是一个很严重的问题是锯齿很严重,而且对paint,bitmapshader,或者canvas使用抗锯齿也无效。效果图如下:

另一种解决方法是,使用ShapeDrawable

方法:根据ImageView的drawable创建一个shapedrawable,并设置shapedrawable的shape, 然后在ondraw方法中设置位图渲染,设置区域,然后将shapedrawable画在canvas上。

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><com.whuthm.imageshape.ShapeImageViewandroid:id="@+id/image1"android:layout_width="250dp"android:layout_height="150dp"android:layout_centerInParent="true"android:scaleType="fitXY"android:src="@drawable/image1" /><com.whuthm.imageshape.ShapeImageViewandroid:id="@+id/image2"android:layout_width="250dp"android:layout_height="150dp"android:scaleType="fitXY"android:src="@drawable/image2" /></RelativeLayout>

关键类ShapeImageView

package com.whuthm.imageshape;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
import android.widget.ImageView;public class ShapeImageView extends ImageView {public static final String TAG = "ShapeImageView";private ShapeDrawable mShapeDrawable;private Shape mShape;private boolean mIsShape;private boolean mRebuildShape;public ShapeImageView(Context context) {this(context, null);}public ShapeImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ShapeImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}//设置shapepublic void setShap(Shape shape) {mShape = shape;mIsShape = true;mRebuildShape = true;}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {if (mIsShape) {//获取ImageView的drawble,当调用过setShape方法时,走下面的流程Drawable oldDrawable = getDrawable();if (oldDrawable == null || mShape == null) {return;}Rect bounds = oldDrawable.getBounds();if (bounds == null || bounds.width() == 0 || bounds.height() == 0) {return;}if (mShapeDrawable == null) {mShapeDrawable = new ShapeDrawable();}//设置shapedrawable的boundsmShapeDrawable.setBounds(bounds);if (mRebuildShape) {mRebuildShape = false;//获取bitmapBitmap bm = drawableToBitmap(oldDrawable);if (bm == null) {return;}//创建一个bitmapshader,shapedrawable设置这个位图渲染BitmapShader bitmapShader = new BitmapShader(bm,TileMode.CLAMP, TileMode.CLAMP);mShapeDrawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);mShapeDrawable.getPaint().setStyle(Paint.Style.FILL);mShapeDrawable.getPaint().setShader(bitmapShader);mShapeDrawable.setShape(mShape);}//当时平行四边形时设置Shape的所在区域if (mShape instanceof ParallelogramShape) {((ParallelogramShape) mShape).setRect(bounds);}int paddingTop = getPaddingTop();int paddingLeft = getPaddingLeft();// int paddingRight = getPaddingRight();// int paddingBottom = getPaddingBottom();// Matrix imageMatrix = getImageMatrix();// int left = getLeft();// int top = getTop();// int right = getRight();// int bottom = getBottom();//将mShapeDrawable画在canvasif (paddingTop == 0 && paddingLeft == 0) {mShapeDrawable.draw(canvas);} else {int saveCount = canvas.getSaveCount();canvas.save();canvas.translate(paddingLeft, paddingTop);mShapeDrawable.draw(canvas);canvas.restoreToCount(saveCount);}} else {super.onDraw(canvas);}}//此方法用于创建一个bitmappublic static Bitmap drawableToBitmap(Drawable drawable) {if (drawable == null || drawable.getBounds() == null) {return null;}// if (drawable instanceof BitmapDrawable) {// return ((BitmapDrawable) drawable).getBitmap();// }Bitmap bitmap;int width = drawable.getBounds().width();int height = drawable.getBounds().height();try {bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);drawable.draw(canvas);} catch (IllegalArgumentException e) {e.printStackTrace();bitmap = null;}return bitmap;}}

平行四边形shape :ParallelogramShape

package com.whuthm.imageshape;import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.shapes.Shape;public class ParallelogramShape extends Shape {Path path;Rect rect;int offset;float scale = -1f;ParallelogramShape() {path = new Path();}public void setRect(Rect rect) {this.rect = rect;}public void setOffset(int offset) {this.offset = offset;}public void setScale(float scale) {this.scale = scale;}//此方法设置path,path为平行四边形@Overridepublic void draw(Canvas canvas, Paint paint) {if (rect == null || rect.width() <= 0 || rect.height() <= 0) {return;}if (scale > 0.0f && scale < 1.0f) {offset = (int) (scale * rect.width());}path.reset();path.moveTo(offset, rect.left);path.lineTo(rect.left, rect.bottom);path.lineTo(rect.right - offset, rect.bottom);path.lineTo(rect.right, 0);canvas.drawPath(path, paint);}}

activity如下:

package com.whuthm.imageshape;import android.os.Bundle;
import android.app.Activity;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建一个平行四边形的shapeParallelogramShape shape = new ParallelogramShape();shape.setScale(0.2f);((ShapeImageView) findViewById(R.id.image1)).setShap(shape);}}

效果图如下:

代码链接

平行四边形的效果实现相关推荐

  1. web前端入门到实战:CSS实现平行四边形布局效果

    如何实现下图所示的平行四边形布局效果? 一.skewX的局限 一提到平行四边形,条件反射般的就会想起CSS transform中的skew()/skewX()/skewY()方法,可以让元素斜切,从而 ...

  2. 使用C语言打印不同星号图案(矩形 平行四边形 三角形)

    献给大一或大二的学弟学妹们和在自学 C语言的同志们. 打印自定义行数的矩形 打印效果: 参考代码: #include<stdio.h> int main() {int i,j,n;prin ...

  3. 纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等),里面很多涉及到CSS3的一些属性。

    今天在css-tricks上看到一篇文章,那篇文章让我不禁心头一震,强大的CSS啊,居然能画出这么多基本的图形.图形包括基本的矩形.圆形. 椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八 ...

  4. 机器人制证系统大屏可视化

    0x01项目背景 本项目是一个机器人制证的可视化系统. 其中包括制证设备的显示和监控,质检设备的显示和监控:同时也包括AGV机器人的显示和监控. 制证设备用于制作证书,质检设备用于合格检查,而AGV机 ...

  5. 利用CSS制作一些实用的图标

    图形包括基本的矩形.圆形.椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八卦等.当然有一些需要用到CSS3的属性,所以在你打开这篇文章的时候,我希望你用的是firefox或者chrome, ...

  6. android自定义u形线,Android自定义彩色织带分割线

    前言 最近开发的一个产品需要涉及到订单,订单页涉及到了一个UI元素,类似饿了么的订单页以及支付宝口碑外卖订单页的彩带(通俗点讲就是一条两种颜色相间而成的分割线): 可以看到,风格基本都是以两种颜色为主 ...

  7. 纯CSS画的基本图形

    今天在css-tricks上看到一篇文章,那篇文章让我不禁心头一震,强大的CSS啊,居然能画出这么多基本的图形.图形包括基本的矩形.圆形. 椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八 ...

  8. java写三角形圆矩形_纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)...

    图形包括基本的矩形.圆形.椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八卦等.当然有一些需要用到CSS3的属性,所以在你打开这篇文章的时候,我希望你用的是firefox或者chrome, ...

  9. 纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)20种类型

    今天在css-tricks上看到一篇文章,那篇文章让我不禁心头一震,强大的CSS啊,居然能画出这么多基本的图形.图形包括基本的矩形.圆形.椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八卦 ...

最新文章

  1. 向量算子优化Vector Operation Optimization
  2. JDK相关版本特性浏览
  3. Android实战技巧之十一:Android Studio和Gradle
  4. Springboot - -web应用开发-Servlets, Filters, listeners
  5. asp是什么文件?html和asp的区别?(HTML是客户端语言,主要用于创建静态网页;asp是服务器端语言,用于设计用户交互式页面或动态页面)
  6. 分布式认证-技术方案
  7. C++中各种智能指针的实现及弊端(一)
  8. 一.redis 环境搭建
  9. Spring的@Scheduled任务调度
  10. 计算机网络之物理层:6、传输介质
  11. Dirichlet过程混合模型(DPMM)的Gibbs抽样程序
  12. 中山大学提出新型行人重识别方法和史上最大评测基准
  13. 2019年微信数据报告:男性用户最爱搜“小姐姐”,表情包最受欢迎的是它
  14. 华为mate20云备份恢复卡住了_注意了!包括华为、荣耀在内的14款老机型开启EMUI11公测了...
  15. win10下安装ubuntu双系统
  16. python第三次作业
  17. 外贸邮箱购买申请哪个好?办公邮箱哪个比较好 工作用什么邮箱?
  18. java实现远程控制
  19. Blurry 高斯模糊库的使用
  20. 分享时刻—今日一收获

热门文章

  1. 创业手记 Mr.Hua
  2. DNS无法解析IP_域名解析错误怎么办?域名解析错误原因有哪些?
  3. 轻松玩转“项目管理” 群硕软件PMS正式发布
  4. 美国CN2服务器推荐:RAKsmart电信Cn2 GIA直连服务器
  5. minigui 编译与使用
  6. 数据库---四中连接查询(交叉、左连接、右连接、完整查询)
  7. win10安装RabbitMQ教程
  8. 追寻上古文明毕业季研学营
  9. 《今日简史》2018比尔盖茨推荐(pdf, mobi, epub三种格式)
  10. linux sd卡 分区变大,Linux下使用fdisk命令将高容量SD卡(SDHC)格成两个分区