# ShapeView **Repository Path**: ekber/ShapeView ## Basic Information - **Project Name**: ShapeView - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-03-19 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ShapView 给任何一个View剪裁不同形状(现已有心形,圆形,圆角矩形,三角形,正多边形,对角线形) [![Apache 2.0 License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0.html) ## APK文件 扫描二维码 或者 点击二维码 下载 [![ShapeView](https://github.com/xwc520/ShapView/raw/master/image/qrcode.png)](https://github.com/xwc520/ShapView/raw/master/image/app-release.apk) #### TODO 提供动态addView方法 #### v1.2.1     1.新增shape_drawble属性    2.url方式加载图片 ## Gradle ``` compile 'com.github.xwc:ShapeView:1.2.1' ``` ## preview ## example ```xml ``` ## Code ```java /** * 圆形 */ @Override public void setCirclePath(Path path, int width, int height) { //xy为圆的圆心 radius为圆的半径 Diection.CW 顺时针方向 path.addCircle(width / 2f, height / 2f, Math.min(width / 2f, height / 2f), Path.Direction.CW); } /** * 带圆角的矩形 */ @Override public void setRoundRectPath(RectF rect, Path path, float topLeftDiameter, float topRightDiameter, float bottomRightDiameter, float bottomLeftDiameter) { topLeftDiameter = topLeftDiameter < 0 ? 0 : topLeftDiameter; topRightDiameter = topRightDiameter < 0 ? 0 : topRightDiameter; bottomLeftDiameter = bottomLeftDiameter < 0 ? 0 : bottomLeftDiameter; bottomRightDiameter = bottomRightDiameter < 0 ? 0 : bottomRightDiameter; float borderWidth = shapeView.getBorderWidthPx() / 2; path.moveTo(rect.left + topLeftDiameter + borderWidth, rect.top + borderWidth); path.lineTo(rect.right - topRightDiameter - borderWidth, rect.top + borderWidth); path.quadTo(rect.right - borderWidth, rect.top + borderWidth, rect.right - borderWidth, rect.top + topRightDiameter + borderWidth); path.lineTo(rect.right - borderWidth, rect.bottom - bottomRightDiameter - borderWidth); path.quadTo(rect.right - borderWidth, rect.bottom - borderWidth, rect.right - bottomRightDiameter - borderWidth, rect.bottom - borderWidth); path.lineTo(rect.left + bottomLeftDiameter + borderWidth, rect.bottom - borderWidth); path.quadTo(rect.left + borderWidth, rect.bottom - borderWidth, rect.left + borderWidth, rect.bottom - bottomLeftDiameter - borderWidth); path.lineTo(rect.left + borderWidth, rect.top + topLeftDiameter + borderWidth); path.quadTo(rect.left + borderWidth, rect.top + borderWidth, rect.left + topLeftDiameter + borderWidth, rect.top + borderWidth); path.close(); } @Override public void setTriangleBroadPath(Path path, int width, int height) { float borderWidth = shapeView.getBorderWidthPx(); path.moveTo(0 + borderWidth, shapeView.getPercentLeft() * height + borderWidth / 2); path.lineTo(shapeView.getPercentBottom() * width - borderWidth / 2, height - borderWidth); path.lineTo(width - borderWidth, shapeView.getPercentBottom() * height + borderWidth / 2); path.close(); } /** * 三角形 */ @Override public void setTrianglePath(Path path, int width, int height) { float borderWidth = shapeView.getBorderWidthPx() / 2; path.moveTo(0 + borderWidth, shapeView.getPercentLeft() * height + borderWidth); path.lineTo(shapeView.getPercentBottom() * width - borderWidth, height - borderWidth); path.lineTo(width - borderWidth, shapeView.getPercentRight() * height + borderWidth); path.close(); } /** * 心形 */ @Override public void setHeartPath(Path path, int width, int height) { int borderWidth = shapeView.getBorderWidthPx() / 2; path.moveTo(0.5f * width, 0.16f * height + borderWidth); path.cubicTo(0.15f * width + borderWidth, -shapeView.getRadian() * height + borderWidth, -0.4f * width + borderWidth, 0.45f * height + borderWidth, 0.5f * width, height - borderWidth); // path.moveTo(0.5f * width, height); path.cubicTo(width + 0.4f * width - borderWidth, 0.45f * height + borderWidth, width - 0.15f * width - borderWidth, -shapeView.getRadian() * height + borderWidth, 0.5f * width, 0.16f * height + borderWidth); path.close(); } /** * 正多边形 */ @Override public void setPolygonPath(RectF rect, Path path) { int sides = shapeView.getSides(); if (sides < 3) { return; } float r = (rect.right - rect.left) / 2 - shapeView.getBorderWidthPx(); float mX = (rect.right + rect.left) / 2; float my = (rect.top + rect.bottom) / 2; for (int i = 0; i <= sides; i++) { // - 0.5 : Turn 90 ° float alpha = Double.valueOf(((2f / sides) * i - shapeView.getTurn()) * Math.PI).floatValue(); float nextX = mX + Double.valueOf(r * Math.cos(alpha)).floatValue(); float nextY = my + Double.valueOf(r * Math.sin(alpha)).floatValue(); if (i == 0) { path.moveTo(nextX, nextY); } else { path.lineTo(nextX, nextY); } } path.close(); } /** * 星星 */ @Override public void setStarPath(Path path, float outR, float inR) { int borderWidthPx = shapeView.getBorderWidthPx(); float radius = outR; float radian = Utils.degree2Radian(36);// 36为五角星的角度 float radius_in = (float) (radius * Math.sin(radian / 2) / Math .cos(radian)); // 中间五边形的半径 path.moveTo((float) (radius * Math.cos(radian / 2) + borderWidthPx), borderWidthPx);// 此点为多边形的起点 path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in * Math.sin(radian) + borderWidthPx), (float) (radius - radius * Math.sin(radian / 2) + borderWidthPx)); path.lineTo((float) (radius * Math.cos(radian / 2) * 2 + borderWidthPx), (float) (radius - radius * Math.sin(radian / 2) + borderWidthPx)); path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in * Math.cos(radian / 2) + borderWidthPx), (float) (radius + radius_in * Math.sin(radian / 2) + borderWidthPx)); path.lineTo( (float) (radius * Math.cos(radian / 2) + radius * Math.sin(radian) + borderWidthPx), (float) (radius + radius * Math.cos(radian) + borderWidthPx)); path.lineTo((float) (radius * Math.cos(radian / 2) + borderWidthPx), radius + radius_in + borderWidthPx); path.lineTo( (float) (radius * Math.cos(radian / 2) - radius * Math.sin(radian) + borderWidthPx), (float) (radius + radius * Math.cos(radian) + borderWidthPx)); path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in * Math.cos(radian / 2) + borderWidthPx), (float) (radius + radius_in * Math.sin(radian / 2) + borderWidthPx)); path.lineTo(borderWidthPx, (float) (radius - radius * Math.sin(radian / 2) + borderWidthPx)); path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in * Math.sin(radian) + borderWidthPx), (float) (radius - radius * Math.sin(radian / 2) + borderWidthPx)); path.close(); } /** * 对角线图形 */ @Override public void setDiagonalPath(Path path, int width, int height) { final float perpendicularHeight = (float) (width * Math.tan(Math.toRadians(shapeView.getDiagonalAngle()))); final boolean isDirectionLeft = shapeView.getDiagonalDirection() == DIRECTION_LEFT; int paddingLeft = shapeView.getPaddingLeft(); int paddingRight = shapeView.getPaddingRight(); int paddingTop = shapeView.getPaddingTop(); int paddingBottom = shapeView.getPaddingBottom(); switch (shapeView.getDiagonalPosition()) { case POSITION_BOTTOM: if (isDirectionLeft) { path.moveTo(paddingLeft, paddingRight); path.lineTo(width - paddingRight, paddingTop); path.lineTo(width - paddingRight, height - perpendicularHeight - paddingBottom); path.lineTo(paddingLeft, height - paddingBottom); path.close(); } else { path.moveTo(width - paddingRight, height - paddingBottom); path.lineTo(paddingLeft, height - perpendicularHeight - paddingBottom); path.lineTo(paddingLeft, paddingTop); path.lineTo(width - paddingRight, paddingTop); path.close(); } break; case POSITION_TOP: if (isDirectionLeft) { path.moveTo(width - paddingRight, height - paddingBottom); path.lineTo(width - paddingRight, paddingTop + perpendicularHeight); path.lineTo(paddingLeft, paddingTop); path.lineTo(paddingLeft, height - paddingBottom); path.close(); } else { path.moveTo(width - paddingRight, height - paddingBottom); path.lineTo(width - paddingRight, paddingTop); path.lineTo(paddingLeft, paddingTop + perpendicularHeight); path.lineTo(paddingLeft, height - paddingBottom); path.close(); } break; case POSITION_RIGHT: if (isDirectionLeft) { path.moveTo(paddingLeft, paddingTop); path.lineTo(width - paddingRight, paddingTop); path.lineTo(width - paddingRight - perpendicularHeight, height - paddingBottom); path.lineTo(paddingLeft, height - paddingBottom); path.close(); } else { path.moveTo(paddingLeft, paddingTop); path.lineTo(width - paddingRight - perpendicularHeight, paddingTop); path.lineTo(width - paddingRight, height - paddingBottom); path.lineTo(paddingLeft, height - paddingBottom); path.close(); } break; case POSITION_LEFT: if (isDirectionLeft) { path.moveTo(paddingLeft + perpendicularHeight, paddingTop); path.lineTo(width - paddingRight, paddingTop); path.lineTo(width - paddingRight, height - paddingBottom); path.lineTo(paddingLeft, height - paddingBottom); path.close(); } else { path.moveTo(paddingLeft, paddingTop); path.lineTo(width - paddingRight, paddingTop); path.lineTo(width - paddingRight, height - paddingBottom); path.lineTo(paddingLeft + perpendicularHeight, height - paddingBottom); path.close(); } break; } } ``` ## attrs 属性 ``` ``` ### 联系邮箱 ## LICENSE ``` Copyright 2018 xwc Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ```