最近较流行的效果 Android自定义View实现倾斜列表/图片
作者:pengkv 发布时间:2021-09-06 03:56:51
标签:Android,View,倾斜,图片
先看看效果图:
实现思路:擦除图片相应的角,然后层叠图片,产生倾斜效果
代码实现:
1、定义属性
在values文件夹下的attrs文件添加以下代码
<resources>
<declare-styleable name="TiltView">
<attr name="type" format="integer" />
</declare-styleable>
</resources>
2、自定义布局
public class TiltView extends ImageView {
private int imageWidth;//图片宽度
private int imageHeight;//图片高度
private double angle = 10 * Math.PI / 180;//三角形角度
private int triangleHeight;//三角形高度
private Paint paint;//画笔
private Path path;//绘制路径
private int type;//倾斜图片的类型
public TiltView(Context context) {
this(context, null);
}
public TiltView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TiltView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TiltView);
type = array.getInteger(R.styleable.TiltView_type, 1);
array.recycle();
}
//重测大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
imageWidth = measureSpec(widthMeasureSpec);
imageHeight = measureSpec(heightMeasureSpec);
setMeasuredDimension(imageWidth, imageHeight); //设置View的大小
triangleHeight = (int) (Math.abs(Math.tan(angle) * imageHeight));
}
//测量长度
private int measureSpec(int measureSpec) {
int minLength = 200;
int mode = MeasureSpec.getMode(measureSpec);
int length = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.AT_MOST) {
length = Math.min(length, minLength);
}
return length;
}
@Override
protected void onDraw(Canvas canvas) {
initPaint();
Bitmap mBitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888); //初始化Bitmap
Canvas mCanvas = new Canvas(mBitmap);//创建画布,并绘制mBitmap
Bitmap mBackBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
mCanvas.drawBitmap(resizeBitmap(mBackBitmap), 0, 0, null);//绘制Bitmap
setTriangle();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mCanvas.drawPath(path, paint);
canvas.drawBitmap(mBitmap, 0, 0, null);
}
//初始化画笔
private void initPaint() {
paint = new Paint();
paint.setDither(true);//设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
paint.setAntiAlias(true);//设置抗锯齿
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);//圆角
}
//设置三角形区域
private void setTriangle() {
path = new Path();
switch (type) {
case 1://右下角
path.moveTo(0, imageHeight);
path.lineTo(imageWidth, imageHeight);
path.lineTo(imageWidth, imageHeight - triangleHeight);
path.lineTo(0, imageHeight);
break;
case 2://左上角+左下角
path.moveTo(0, triangleHeight);
path.lineTo(imageWidth, 0);
path.lineTo(0, 0);
path.lineTo(0, imageHeight);
path.lineTo(imageWidth, imageHeight);
path.lineTo(0, imageHeight - triangleHeight);
break;
case 3://右上角+右下角
path.moveTo(imageWidth, triangleHeight);
path.lineTo(0, 0);
path.lineTo(imageWidth, 0);
path.lineTo(imageWidth, imageHeight);
path.lineTo(0, imageHeight);
path.lineTo(imageWidth, imageHeight - triangleHeight);
break;
case 4://右上角
path.moveTo(0, 0);
path.lineTo(imageWidth, 0);
path.lineTo(imageWidth, triangleHeight);
path.lineTo(0, 0);
break;
case 5://左上角
path.moveTo(0, 0);
path.lineTo(imageWidth, 0);
path.lineTo(0, triangleHeight);
path.lineTo(0, 0);
break;
}
}
//重新调节图片大小
private Bitmap resizeBitmap(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// 设置想要的大小
int newWidth = imageWidth;
int newHeight = imageHeight;
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
}
}
3、布局代码调用
//其中android:layout_marginTop="-15dp"对效果实现有很大的作用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.pengkv.may.widget.TiltView
android:layout_width="match_parent"
android:layout_height="100dp"
android:src="@drawable/sample_0"
app:type="1" />
<com.pengkv.may.widget.TiltView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="-15dp"
android:src="@drawable/sample_1"
app:type="2" />
<com.pengkv.may.widget.TiltView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="-15dp"
android:src="@drawable/sample_2"
app:type="4" />
</LinearLayout>


猜你喜欢
- 一、准备工作1、pom依赖在pom.xml中加入POI的依赖<dependency> <groupId>org.ap
- 动态获取对象的性能值,这个在开发过程中经常会遇到,这里我们探讨一下何如高性能的获取属性值。为了对比测试,我们定义一个类Peoplepubli
- 在之前我们分析了Android6.0系统在启动时安装应用程序的过程,这些应用程序安装好之后,Launcher应用就负责把它们在桌面上展示出来
- Java单例模式的实现,对java 单例模式的几种实现方法进行了整理:单例模式好多书上都是这么写的:public class SingleT
- Android ListView的Item点击效果的定制
- 各个方法1. 得到class的成员变量首先得到object的class对象然后在class对象中用getDeclaredFields()方法
- 什么原因使我们不得不使用线程池?个人认为主要原因是:短时间内需要处理的任务数量很多使用线程池的好处:1.减少在创建和销毁线程上所花的时间以及
- 实践过程pdf转excelpublic static long pdfToExcel(String inFile, String outFi
- 最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时间,也只是达到了实现功能的水平,并没有太多考虑到性能问题,所以这篇文章比较适合初
- 1.首先,需要指定获取的文件夹,以及获取文件的文件名;文件夹:strLocalPath = System.Windows.Forms.App
- 背景由于前前前阵子写了个壳,得去了解类的加载流程,当时记了一些潦草的笔记。这几天把这些东西简单梳理了一下,本文分析的代码基于Android8
- 1、抽象类1.1 什么是抽象类?1.1.1 对抽象类的理解1.1.2 关于抽象类类与类之间具有共同特征,将这些共同特征提取出来,形成的就是抽
- 说明:曾经在网上看过花样繁多的分页,很多都号称如何通用,但很多时候往往不尽如人意:有在分页类中还加入URL地址信息的,有在分页类中还进行分页
- 本文实例讲述了Java Arrays工具类用法。分享给大家供大家参考,具体如下:Arrays类功能描述Arrays类是一个工具类,其中包含了
- 背景:SpringMVC如何响应json格式的数据?技术实现方式1:在Controller使用@RestController注解方式2:在C
- ProgressBar进度条,分为旋转进度条和水平进度条,进度条的样式根据需要自定义,之前一直不明白进度条如何在实际项目中使用,网上演示进度
- 前文说到 优雅的使用枚举参数 和 实现原理,本文继续说一下如何在 RequestBody 中优雅使用枚举。本文先上实战,说一下如何实现。在
- 一、策略模式到底是什么?策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替
- 🚀 ChatGPT是最近很热门的AI智能聊天机器人🚀 本文使用SpringBoot+OpenAI的官方API接口,自己实现一个可以返回对话数
- 今天来了一个问题:软键盘无法弹出。分析后是因为系统判断当前有外接硬键盘,就会隐藏软键盘。但实际情况并不是这么简单,该问题只有在特定条件下偶现