提供对视图的对角线切割,具有很好的用户定制
基本用法:
<com.intrusoft.squint.DiagonalView
android:id="@+id/diagonal"
android:layout_width="match_parent"
android:layout_height="240dp"
android:scaleType="centerCrop"
android:src="@drawable/c1"
squint:diagonalDirection="bottom_to_top"
squint:angle="12"
squint:gravity="right" />
所有属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="src" format="reference" />
<attr name="angle" format="integer" />
<attr name="scaleType">
<enum name="centerCrop" value="0" />
<enum name="fitXY" value="1" />
</attr>
<attr name="gravity">
<enum name="left" value="0" />
<enum name="right" value="1" />
<enum name="top" value="2" />
<enum name="bottom" value="3" />
</attr>
<attr name="diagonalDirection">
<enum name="left_to_right" value="0" />
<enum name="right_to_left" value="1" />
<enum name="top_to_bottom" value="2" />
<enum name="bottom_to_top" value="3" />
</attr>
<attr name="tint" format="color" />
<attr name="solidColor" format="color" />
<attr name="fillColor" format="color" />
<declare-styleable name="DiagonalView">
<attr name="angle" />
<attr name="gravity" />
<attr name="tint" />
<attr name="solidColor" />
<attr name="fillColor" />
<attr name="diagonalDirection" />
</declare-styleable>
</resources>
也可以通过代码设置:
DiagonalView diagonalView = (DiagonalView) findViewById(R.id.diagonal);
// to set image from resources
diagonalView.setImageSource(R.drawable.your_image);
// to set bitmap
diagonalView.setBitmap(bitmap);
// to set the diagonal angle
diagonalView.setAngle(15);
// to set the diagonal gravity
diagonalView.setGravity(DiagonalView.Gravity.LEFT);
// to set the background color (color should have some alpha val)
diagonalView.setColorTint(Color.GREEN);
// to make the solid color diagonal
diagonalView.setSolidColor(Color.BLUE);
一共有三个类,只供学习用:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.intrusoft.squint.Squint.Direction;
import com.intrusoft.squint.Squint.Gravity;
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static com.intrusoft.squint.Squint.DIRECTIONS;
import static com.intrusoft.squint.Squint.GRAVITIES;
public class DiagonalView extends ImageView {
private final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private final Paint fillPaint = new Paint(ANTI_ALIAS_FLAG);
private final Paint tintPaint = new Paint(ANTI_ALIAS_FLAG);
private final Paint bitmapPaint = new Paint(ANTI_ALIAS_FLAG);
private final Paint solidPaint = new Paint(ANTI_ALIAS_FLAG);
private final Matrix shaderMatrix = new Matrix();
private final int DEFAULT_ALPHA = 50;
private static int tintColor = Color.TRANSPARENT;
private static int fillColor = Color.TRANSPARENT;
private static int solidColor = Color.TRANSPARENT;
private float width;
private float height;
private int angle = 10;
private Gravity gravity = Gravity.BOTTOM;
private Direction direction = Direction.LEFT_TO_RIGHT;
private Bitmap bitmap;
private BitmapShader bitmapShader;
private ColorFilter colorFilter;
public DiagonalView(Context context) {
super(context);
init(context, null, 0);
}
public DiagonalView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public DiagonalView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attributeSet, int defStyleAttr) {
if (attributeSet != null) {
TypedArray array = context.obtainStyledAttributes(attributeSet, R.styleable.DiagonalView, defStyleAttr, 0);
angle = array.getInt(R.styleable.DiagonalView_angle, angle);
gravity = GRAVITIES[array.getInt(R.styleable.DiagonalView_gravity, 3)];
tintColor = array.getColor(R.styleable.DiagonalView_tint, Color.TRANSPARENT);
fillColor = array.getColor(R.styleable.DiagonalView_fillColor, Color.TRANSPARENT);
solidColor = array.getColor(R.styleable.DiagonalView_solidColor, Color.TRANSPARENT);
direction = DIRECTIONS[array.getInt(R.styleable.DiagonalView_diagonalDirection, 0)];
array.recycle();
}
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setColor(fillColor);
tintPaint.setStyle(Paint.Style.FILL);
tintPaint.setColor(tintColor);
solidPaint.setStyle(Paint.Style.FILL);
solidPaint.setColor(solidColor);
solidPaint.setAlpha(255);
if (tintPaint.getAlpha() == 255)
tintPaint.setAlpha(DEFAULT_ALPHA);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
initializeBitmap();
}
@Override
public void draw(Canvas canvas) {
Path path = PathHelper.getPathFor(getWidth(), getHeight(), angle, direction, gravity);
if (bitmap != null) {
if (fillColor != Color.TRANSPARENT)
canvas.drawPath(path, fillPaint);
canvas.drawPath(path, bitmapPaint);
if (tintColor != Color.TRANSPARENT)
canvas.drawPath(path, tintPaint);
}
if (solidColor != Color.TRANSPARENT)
canvas.drawPath(path, solidPaint);
}
private void initializeBitmap() {
width = getMeasuredWidth();
height = getMeasuredHeight();
Drawable drawable = getDrawable();
if (drawable != null) {
if (drawable instanceof BitmapDrawable)
bitmap = ((BitmapDrawable) drawable).getBitmap();
else {
try {
int COLOR_DRAWABLE_DIMENSIONS = 2;
if (drawable instanceof ColorDrawable)
bitmap = Bitmap.createBitmap(COLOR_DRAWABLE_DIMENSIONS, COLOR_DRAWABLE_DIMENSIONS, BITMAP_CONFIG);
else
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
if (bitmap == null) {
invalidate();
return;
}
if (bitmapPaint != null) {
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
bitmapPaint.setShader(bitmapShader);
}
if (this.getScaleType() != ScaleType.CENTER_CROP && this.getScaleType() != ScaleType.FIT_XY)
this.setScaleType(ScaleType.CENTER_CROP);
setUpScaleType();
applyColorFilter();
invalidate();
}
}
private void applyColorFilter() {
if (bitmapPaint != null) {
bitmapPaint.setColorFilter(colorFilter);
}
}
private void setUpScaleType() {
float scaleX = 1, scaleY = 1, dx = 0, dy = 0;
if (bitmap == null || shaderMatrix == null)
return;
shaderMatrix.set(null);
if (getScaleType() == ScaleType.CENTER_CROP) {
if (width != bitmap.getWidth()) {
scaleX = width / bitmap.getWidth();
}
if (scaleX * bitmap.getHeight() < height) {
scaleX = height / bitmap.getHeight();
}
dy = (height - bitmap.getHeight() * scaleX) * 0.5f;
dx = (width - bitmap.getWidth() * scaleX) * 0.5f;
shaderMatrix.setScale(scaleX, scaleX);
} else {
scaleX = width / bitmap.getWidth();
scaleY = height / bitmap.getHeight();
dy = (height - bitmap.getHeight() * scaleY) * 0.5f;
dx = (width - bitmap.getWidth() * scaleX) * 0.5f;
shaderMatrix.setScale(scaleX, scaleY);
}
shaderMatrix.postTranslate(dx + 0.5f, dy + 0.5f);
bitmapShader.setLocalMatrix(shaderMatrix);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
if (colorFilter == this.colorFilter) {
return;
}
this.colorFilter = colorFilter;
applyColorFilter();
invalidate();
}
@Override
public ColorFilter getColorFilter() {
return colorFilter;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType == ScaleType.CENTER_CROP || scaleType == ScaleType.FIT_XY)
super.setScaleType(scaleType);
else
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
initializeBitmap();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
initializeBitmap();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
initializeBitmap();
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
initializeBitmap();
}
public int getTintColor() {
return tintColor;
}
public void setTintColor(int tintColor) {
DiagonalView.tintColor = tintColor;
tintPaint.setColor(tintColor);
if (tintPaint.getAlpha() == 255)
tintPaint.setAlpha(DEFAULT_ALPHA);
invalidate();
}
public int getFillColor() {
return fillColor;
}
public void setFillColor(int fillColor) {
DiagonalView.fillColor = fillColor;
fillPaint.setColor(fillColor);
invalidate();
}
public int getSolidColor() {
return solidColor;
}
public void setSolidColor(int solidColor) {
DiagonalView.solidColor = solidColor;
solidPaint.setColor(solidColor);
solidPaint.setAlpha(255);
invalidate();
}
public void setDiagonalGravity(Gravity gravity) {
this.gravity = gravity;
invalidate();
}
public void setDiagonalDirection(Direction direction) {
this.direction = direction;
invalidate();
}
public void setAngle(int angle) {
this.angle = angle;
invalidate();
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
invalidate();
}
}
import android.graphics.Path;
import com.intrusoft.squint.Squint.Direction;
import com.intrusoft.squint.Squint.Gravity;
import static com.intrusoft.squint.Squint.Gravity.BOTTOM;
import static com.intrusoft.squint.Squint.Gravity.LEFT;
import static com.intrusoft.squint.Squint.Gravity.RIGHT;
import static com.intrusoft.squint.Squint.Gravity.TOP;
public class PathHelper {
public static Path getPathFor(float width, float height, double angle, Direction direction, Gravity gravity) {
switch (direction) {
case LEFT_TO_RIGHT:
return leftToRight(width, height, angle, gravity);
case RIGHT_TO_LEFT:
return rightToLeft(width, height, angle, gravity);
case TOP_TO_BOTTOM:
return topToBottom(width, height, angle, gravity);
case BOTTOM_TO_TOP:
return bottomToTop(width, height, angle, gravity);
}
return null;
}
private static Path leftToRight(float width, float height, double angle, Gravity gravity) {
if (gravity == LEFT || gravity == RIGHT)
gravity = BOTTOM;
Path path = new Path();
float attitude = (float) Math.abs(Math.tan(Math.toRadians(angle)) * width);
if (gravity == BOTTOM) {
path.moveTo(0, 0);
path.lineTo(width, 0);
path.lineTo(width, height - attitude);
path.lineTo(0, height);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(width, attitude);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
}
return path;
}
private static Path rightToLeft(float width, float height, double angle, Gravity gravity) {
if (gravity == LEFT || gravity == RIGHT)
gravity = BOTTOM;
Path path = new Path();
float attitude = (float) Math.abs(Math.tan(Math.toRadians(angle)) * width);
if (gravity == BOTTOM) {
path.moveTo(0, 0);
path.lineTo(width, 0);
path.lineTo(width, height);
path.lineTo(0, height - attitude);
path.close();
} else {
path.moveTo(0, attitude);
path.lineTo(width, 0);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
}
return path;
}
private static Path topToBottom(float width, float height, double angle, Gravity gravity) {
if (gravity == TOP || gravity == BOTTOM)
gravity = LEFT;
float attitude = (float) Math.abs(Math.tan(Math.toRadians(angle)) * height);
Path path = new Path();
if (gravity == LEFT) {
path.moveTo(0, 0);
path.lineTo(0, height);
path.lineTo(width - attitude, height);
path.lineTo(width, 0);
path.close();
} else {
path.moveTo(0, 0);
path.lineTo(attitude, height);
path.lineTo(width, height);
path.lineTo(width, 0);
path.close();
}
return path;
}
private static Path bottomToTop(float width, float height, double angle, Gravity gravity) {
if (gravity == TOP || gravity == BOTTOM)
gravity = LEFT;
float attitude = (float) Math.abs(Math.tan(Math.toRadians(angle)) * height);
Path path = new Path();
if (gravity == LEFT) {
path.moveTo(0, 0);
path.lineTo(0, height);
path.lineTo(width, height);
path.lineTo(width - attitude, 0);
path.close();
} else {
path.moveTo(attitude, 0);
path.lineTo(width, 0);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
}
return path;
}
}
public class Squint {
public enum Gravity {
LEFT(0),
RIGHT(1),
TOP(2),
BOTTOM(3);
final int value;
Gravity(int value) {
this.value = value;
}
}
static final Gravity[] GRAVITIES = {Gravity.LEFT, Gravity.RIGHT, Gravity.TOP, Gravity.BOTTOM};
public enum Direction {
LEFT_TO_RIGHT(0),
RIGHT_TO_LEFT(1),
TOP_TO_BOTTOM(2),
BOTTOM_TO_TOP(3);
final int value;
Direction(int value) {
this.value = value;
}
}
static final Direction[] DIRECTIONS = {Direction.LEFT_TO_RIGHT, Direction.RIGHT_TO_LEFT, Direction.TOP_TO_BOTTOM, Direction.BOTTOM_TO_TOP};
}
github:
https://github.com/IntruderShanky/Squint
标签:import,gravity,视图,height,width,DiagonalView,对角线,path,public From: https://blog.51cto.com/u_5454003/6238912