`

对视图的对角线切割DiagonalView

阅读更多
提供对视图的对角线切割,具有很好的用户定制





基本用法:
<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
  • 大小: 759.2 KB
  • 大小: 629.2 KB
分享到:
评论

相关推荐

    一个简单的图像视图,可让您轻松创建对角线切割视图-Android开发

    Diagonal ImageView一个简单的imageview,可让您轻松创建对角线切割视图。样品用法Gradle allprojects {存储库{maven {url Diagonal ImageView一个简单的imageview,可让您轻松创建对角线切割视图。Samples用法...

    Android-DiagonalImageView一个简单的imageview允许您轻松创建对角切割视图

    `Android-DiagonalImageView` 是一个专为提升UI设计独特性而设计的组件,它允许开发者创建具有对角线切割效果的ImageView,从而实现非传统但引人注目的图像展示方式。这个库可以帮助开发者在不增加过多复杂性的情况...

    行业文档-设计装置-一种几何体对角线或高线可视化教学模型.zip

    例如,在立方体中,每个面都有对角线,而穿过立方体中心的对角线被称为体对角线。通过可视化模型,学生可以直观看到不同几何体的对角线形状和长度,有助于理解对角线的概念和计算方法。 3. 高线:高线是从几何体的...

    MFC单文档视图切割

    4. 处理用户对分割线的拖动事件,动态调整子视图的大小。 总的来说,"MFC单文档视图切割"是一个强大的功能,可以让用户在同一文档界面下享受多种视图体验。通过理解和熟练掌握MFC中的相关类和方法,开发者可以创建...

    切割球体的三视图学习教案.pptx

    切割球体的三视图学习教案.pptx

    VC++基于单文档切割成多视图

    本教程将详细讲解如何利用MFC的单文档接口(Single Document Interface, SDI)实现视图的切割,将一个单文档切割成多个视图,分别使用CListView和CFormView类。 首先,让我们理解什么是SDI。SDI是一种用户界面模式...

    切割体的三视图PPT学习教案.pptx

    在实际操作中,有六个关键的作图步骤:分析形体、确定放置位置和主视方向、选择比例和图纸尺寸、布置视图并定位、画草稿、最后去掉切割部分并检查描深结果线。在打底稿时,要充分利用三等关系,即长对正(主视图与...

    多视图Demo,包括自定义视图,窗口分割,窗口样式改变

    MFC给我们做好了一个多视图的框架。但在应用中,MFC默认的视图并不能满足我们的要求。本Demo中包含以下做界面的常用代码: 自定义视图: 在CWinApp::Initlnstance里定义CMultiDocTemplate 视图窗口分割: 在...

    MFC 单文档视图中进行多种视图的切换

    然而,有时我们可能希望在同一个SDI应用中展示不同类型的视图,比如文本视图、图像视图或者图表视图。这种需求可以通过在MFC中实现多视图来解决。下面将详细解释如何在MFC的单文档视图中进行多种视图的切换。 首先...

    vtk中三视图显示

    体切片(Volume Slicing)是体绘制的一种变体,它通过沿特定方向切割数据体来显示其内部结构。vtk可以使用vtkPlaneSource或者vtkImageSlice来创建切片,然后结合vtkSliceMapper和vtkActor进行渲染。用户可以自由调整...

    【成功方案】2020届高考数学一轮复习课时检测 第七章 第一节 空间几何体的结构特征及三视图和直观图 理.doc

    7. **四边形的性质**:在正方体中,过对角线的平面切割产生的四边形可能具有不同的性质,如菱形、梯形等。问题7考察了这些性质及其在底面投影的形状。 8. **组合几何体**:问题8让学生根据正视图和侧视图估算几何体...

    fullCalendar 增加年视图版

    然而,根据你提供的标题和描述,有人对`fullCalendar`进行了扩展,添加了年视图功能。年视图允许用户以年度为单位查看和管理事件,这对于那些需要查看整个年度计划或者安排长期项目的人来说非常有用。年视图的增加让...

    计算机视觉中的多视图几何

    ### 计算机视觉中的多视图几何 ...通过对本中文版的学习,读者可以建立起对多视图几何基本概念的理解,并为进一步深入学习打下坚实的基础。随着技术的进步,未来多视图几何将在更多领域发挥重要作用。

    view_fenge.rar_VC 视图

    在VC++编程环境中,视图...总的来说,这个"view_fenge.rar_VC 视图"的资源对学习和提升VC++视图操作及界面设计能力非常有价值,它提供了一种实践性的学习方法,让开发者能够通过实际代码来理解和掌握视图切割的技巧。

    4+1视图建模教程实例大全

    这个模型包括了四个主要的视图:逻辑视图、进程视图、物理视图和开发视图,以及一个附加的用例视图,这五个部分共同构建了一个全面的软件体系结构描述。 1. **逻辑视图**:这是从功能性的角度来看待软件系统,主要...

    vc++实现的视图放大缩小功能,居于mfc的CScrollview

    本项目是基于MFC的CScrollView类实现的视图放大缩小功能,这对于图形编辑、图像查看或者绘图类应用来说是非常重要的特性。 CScrollView是MFC提供的一种视图类,它扩展了CView类,内置了滚动条支持,能够处理大型...

    n棱柱直观图视图截交线

    "截交线"是在立体几何中,当一个平面切割几何体时,与几何体表面的交线即为截交线。在n棱柱的例子中,可以调整截平面的位置和角度,观察截交线如何随截平面的变化而变化。这种动态演示有助于学生理解截交线的形成...

    2020高考数学 课后作业 9-1 空间几何体的结构特征及其直观图、三视图 新人教A版.doc

    这部分知识涉及到立体几何,主要包括圆台、正三棱柱、几何体的侧面积、体积以及对角线的计算。以下是对这些知识点的详细解释: 1. 圆台的侧面积计算:圆台的侧面积可以通过公式 `S = π(l + r)h` 计算,其中 l 和 r...

    Android仿微信UI布局视图(圆角布局的实现)

    为了确保子视图的形状也符合圆角布局,我们需要在自定义布局中对子视图进行裁剪。这可以通过调用`clipPath()`或`clipRect()`方法实现,确保裁剪区域与圆角形状一致。 5. **处理边框** 如果需要添加边框,可以在...

Global site tag (gtag.js) - Google Analytics