首页 > 其他分享 >《“透视”个人大数据》项目开发小记 --(三)Android APP 开发(2)自定ImageView

《“透视”个人大数据》项目开发小记 --(三)Android APP 开发(2)自定ImageView

时间:2022-12-10 08:55:56浏览次数:46  
标签:-- double APP float int import ImageView android ph

      在以图片为主的项目数据表界面中,普遍的应用了自定义的ImageView,这增强了图片的表现力。这里以“事件表”介绍一个自定ImageView的实例。这个自定ImageView通过clipPath实现了圆角图片的显示,通过描绘Vector 图标在图片中,绘出了“选择标记”,“星级标记”,“定时任务标记”,“加密标记”及加密类型。

---- 自定的 ImageView

package com.bi3eview.newstart60.local.SelfWidget;

import android.graphics.Matrix;
import android.support.v7.widget.AppCompatImageView;
import android.util.DisplayMetrics;
import android.graphics.RectF;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;

import com.bi3eview.newstart60.local.COMCONST;

public class TextImageView extends AppCompatImageView {
    private static final int TEXT_SIZE = 12;// sp
    private static int BACKGROUND_COLOR = Color.WHITE;
    private static int TEXT_COLOR = Color.BLUE;
    private static int MARKICON_COLOR = Color.YELLOW;
    private static int SELMARK_COLOR = Color.GREEN;
    private static int STAR_COLOR = Color.RED;

    public static String secretName = "se";
    public static String topSecretName = "tse";
    private int secretLockClass = 0;
    private int tasknum = 0;
    private int starClassno = 0;
    private boolean selmarkblv = false;

    public TextImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public void setSecretClassno(int isecretClass) {
        secretLockClass = isecretClass;
    }

    public void setTimerTasknum(int iTasknum) {
        tasknum = iTasknum;
    }
    public void setStarClassno(int iStarClassno) {
        starClassno = iStarClassno;
    }
    public void setSelectMark(Boolean setselblv) {
        selmarkblv = setselblv;
    }

    @Override
    public void draw(Canvas canvas) {
        // 设置图片圆角修剪路经
        canvas.save();
        Path borderpath = new Path();
        int w = this.getWidth();
        int h = this.getHeight();
        float fCornerRadius = h/6;
        borderpath.addRoundRect(new RectF(0,0,w,h),fCornerRadius,fCornerRadius,Path.Direction.CW);
        canvas.clipPath(borderpath);
        super.draw(canvas);
        canvas.restore();
        // 描绘标记
        fCornerRadius = 0;
        canvas.save();
        int iwidth = canvas.getWidth();
        int iheight = canvas.getHeight();
        final Paint paint = new Paint();

        final DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
        paint.setColor(MARKICON_COLOR);
        int ifnsize = (int)(TEXT_SIZE*dm.scaledDensity);
        paint.setTextSize(ifnsize);// 设置文字大小
        int ishapesize = (int)(19*dm.scaledDensity);
        paint.setStrokeWidth(1);
        Matrix cmaxtrix = new Matrix();
        Path starpath;
        /** 描绘定时任务标记 */
        if(tasknum > 0) {
            starpath = PathParser.doPath(COMCONST.VECTORPATH_TASK);
            cmaxtrix.setScale(2, 2);
            starpath.transform(cmaxtrix);
            starpath.offset(iwidth - ishapesize - ishapesize / 4, iheight - ishapesize - ishapesize / 4);
            canvas.drawPath(starpath, paint);
        }
        /** 描绘选择标记 */
        if(selmarkblv == true) {
            starpath = PathParser.doPath(COMCONST.VECTORPATH_SELMARK);
            cmaxtrix.reset();
            cmaxtrix.setScale(4, 4);
            starpath.transform(cmaxtrix);
            starpath.offset(iwidth/2 - ishapesize, iheight/2 - ishapesize/2);
            paint.setColor(SELMARK_COLOR);
            canvas.drawPath(starpath, paint);
        }
        /** 描绘星级标记 */
        if(starClassno >= 10){
            int istarjn = starClassno/10;
            starpath = PathParser.doPath(COMCONST.VECTORPATH_STAR);
            cmaxtrix.reset();
            cmaxtrix.setScale((float)1.5, (float)1.5);
            starpath.transform(cmaxtrix);
            starpath.offset(ishapesize/6, ishapesize/3);
            paint.setColor(STAR_COLOR);
            canvas.drawPath(starpath, paint);
            if(istarjn > 1) {
                for(int j = 1;j < istarjn;j++) {
                    starpath.offset(ishapesize, 0);
                    canvas.drawPath(starpath, paint);
                }
            }
        }
        /** 描绘“加密标记”及标注加密类型 */
        if(secretLockClass > 0) {
            paint.setColor(MARKICON_COLOR);
            starpath = PathParser.doPath(COMCONST.VECTORPATH_LOCK);
            cmaxtrix.reset();
            cmaxtrix.setScale(2, 2);
            starpath.transform(cmaxtrix);
            starpath.offset(ishapesize / 4, iheight - ishapesize-ishapesize/5);// (100,100);
            canvas.drawPath(starpath, paint);
            String secretTxt = secretName;//" 秘密 ";
            if(secretLockClass == 2) secretTxt = topSecretName;//" 绝密 ";
            int iclen = secretTxt.length();
            // 设置Rect Path
            Path path = new Path();
            int iLeft = ishapesize / 3+ishapesize;
            if(iclen > 2) iclen = iclen-1;
            int iRight = iLeft+ifnsize*iclen+ifnsize / 3;
            path.addRect(iLeft, iheight-ifnsize-ifnsize/2, iRight, iheight-ifnsize/3, Path.Direction.CW);
            path.setFillType(Path.FillType.WINDING);
            paint.setColor(BACKGROUND_COLOR);
            canvas.drawPath(path, paint);
            paint.setColor(TEXT_COLOR);
            canvas.drawText(secretTxt,ishapesize / 2+ishapesize,iheight-ifnsize/2,paint);
        }
        canvas.restore();

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

}

  ----- 自定ImageView中用到 vector path Parser 的相关代码及数据

package com.bi3eview.newstart60.local.SelfWidget;

import android.graphics.Path;
import android.graphics.RectF;
import android.util.Log;

public class PathParser {

    private static final String TAG = "SvgToPath.TAG";

    /*
     * This is where the hard-to-parse paths are handled.
     * Uppercase rules are absolute positions, lowercase are relative.
     * Types of path rules:
     * <p/>
     * <ol>
     * <li>M/m - (x y)+ - Move to (without drawing)
     * <li>Z/z - (no params) - Close path (back to starting point)
     * <li>L/l - (x y)+ - Line to
     * <li>H/h - x+ - Horizontal ine to
     * <li>V/v - y+ - Vertical line to
     * <li>C/c - (x1 y1 x2 y2 x y)+ - Cubic bezier to
     * <li>S/s - (x2 y2 x y)+ - Smooth cubic bezier to (shorthand that assumes the x2, y2 from previous C/S is the x1, y1 of this bezier)
     * <li>Q/q - (x1 y1 x y)+ - Quadratic bezier to
     * <li>T/t - (x y)+ - Smooth quadratic bezier to (assumes previous control point is "reflection" of last one w.r.t. to current point)
     * </ol>
     * <p/>
     * Numbers are separate by whitespace, comma or nothing at all (!) if they are self-delimiting, (ie. begin with a - sign)
     */
    public static Path doPath(String s) {
        int n = s.length();
        ParserHelper ph = new ParserHelper(s);
        ph.skipWhitespace();
        Path p = new Path();
        float lastX = 0;
        float lastY = 0;
        float lastX1 = 0;
        float lastY1 = 0;
        float contourInitialX = 0;
        float contourInitialY = 0;
        RectF r = new RectF();
        char cmd = 'x';
        while (ph.pos < n) {
            char next = s.charAt(ph.pos);
            if (!Character.isDigit(next) && !(next == '.') && !(next == '-')) {
                cmd = next;
                ph.advance();
            } else if (cmd == 'M') { // implied command
                cmd = 'L';
            } else if (cmd == 'm') { // implied command
                cmd = 'l';
            } else { // implied command
                //ignore
            }
            p.computeBounds(r, true);
            // Log.d(TAG, "  " + cmd + " " + r);
            // Util.debug("* Commands remaining: '" + path + "'.");
            boolean wasCurve = false;
            switch (cmd) {
                case 'M':
                case 'm': {
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 'm') {
                        p.rMoveTo(x, y);
                        lastX += x;
                        lastY += y;
                    } else {
                        p.moveTo(x, y);
                        lastX = x;
                        lastY = y;
                    }
                    contourInitialX = lastX;
                    contourInitialY = lastY;
                    break;
                }
                case 'Z':
                case 'z': {
                    /// p.lineTo(contourInitialX, contourInitialY);
                    p.close();
                    lastX = contourInitialX;
                    lastY = contourInitialY;
                    break;
                }
                case 'L':
                case 'l': {
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 'l') {
                        p.rLineTo(x, y);
                        lastX += x;
                        lastY += y;
                    } else {
                        p.lineTo(x, y);
                        lastX = x;
                        lastY = y;
                    }
                    break;
                }
                case 'H':
                case 'h': {
                    float x = ph.nextFloat();
                    if (cmd == 'h') {
                        p.rLineTo(x, 0);
                        lastX += x;
                    } else {
                        p.lineTo(x, lastY);
                        lastX = x;
                    }
                    break;
                }
                case 'V':
                case 'v': {
                    float y = ph.nextFloat();
                    if (cmd == 'v') {
                        p.rLineTo(0, y);
                        lastY += y;
                    } else {
                        p.lineTo(lastX, y);
                        lastY = y;
                    }
                    break;
                }
                case 'C':
                case 'c': {
                    wasCurve = true;
                    float x1 = ph.nextFloat();
                    float y1 = ph.nextFloat();
                    float x2 = ph.nextFloat();
                    float y2 = ph.nextFloat();
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 'c') {
                        x1 += lastX;
                        x2 += lastX;
                        x += lastX;
                        y1 += lastY;
                        y2 += lastY;
                        y += lastY;
                    }
                    p.cubicTo(x1, y1, x2, y2, x, y);
                    lastX1 = x2;
                    lastY1 = y2;
                    lastX = x;
                    lastY = y;
                    break;
                }
                case 'S':
                case 's': {
                    wasCurve = true;
                    float x2 = ph.nextFloat();
                    float y2 = ph.nextFloat();
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 's') {
                        x2 += lastX;
                        x += lastX;
                        y2 += lastY;
                        y += lastY;
                    }
                    float x1 = 2 * lastX - lastX1;
                    float y1 = 2 * lastY - lastY1;
                    p.cubicTo(x1, y1, x2, y2, x, y);
                    lastX1 = x2;
                    lastY1 = y2;
                    lastX = x;
                    lastY = y;
                    break;
                }
                case 'A':
                case 'a': {
                    float rx = ph.nextFloat();
                    float ry = ph.nextFloat();
                    float theta = ph.nextFloat();
                    int largeArc = (int) ph.nextFloat();
                    int sweepArc = (int) ph.nextFloat();
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 'a') {
                        x += lastX;
                        y += lastY;
                    }
                    drawArc(p, lastX, lastY, x, y, rx, ry, theta, largeArc == 1, sweepArc == 1);
                    lastX = x;
                    lastY = y;
                    break;
                }
                case 'T':
                case 't': {
                    wasCurve = true;
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 't') {
                        x += lastX;
                        y += lastY;
                    }
                    float x1 = 2 * lastX - lastX1;
                    float y1 = 2 * lastY - lastY1;
                    p.cubicTo( lastX, lastY, x1, y1, x, y );
                    lastX = x;
                    lastY = y;
                    lastX1 = x1;
                    lastY1 = y1;
                    break;
                }
                case 'Q':
                case 'q': {
                    wasCurve = true;
                    float x1 = ph.nextFloat();
                    float y1 = ph.nextFloat();
                    float x = ph.nextFloat();
                    float y = ph.nextFloat();
                    if (cmd == 'q') {
                        x += lastX;
                        y += lastY;
                        x1 += lastX;
                        y1 += lastY;
                    }
                    p.cubicTo( lastX, lastY, x1, y1, x, y );
                    lastX1 = x1;
                    lastY1 = y1;
                    lastX = x;
                    lastY = y;
                    break;
                }
                default:
                    Log.w(TAG, "Invalid path command: " + cmd);
                    ph.advance();
            }
            if (!wasCurve) {
                lastX1 = lastX;
                lastY1 = lastY;
            }
            ph.skipWhitespace();
        }
        return p;
    }

    /*
     * Elliptical arc implementation based on the SVG specification notes
     * Adapted from the Batik library (Apache-2 license) by SAU
     */
    private static void drawArc(Path path, double x0, double y0, double x, double y, double rx,
                                double ry, double angle, boolean largeArcFlag, boolean sweepFlag) {
        double dx2 = (x0 - x) / 2.0;
        double dy2 = (y0 - y) / 2.0;
        angle = Math.toRadians(angle % 360.0);
        double cosAngle = Math.cos(angle);
        double sinAngle = Math.sin(angle);

        double x1 = (cosAngle * dx2 + sinAngle * dy2);
        double y1 = (-sinAngle * dx2 + cosAngle * dy2);
        rx = Math.abs(rx);
        ry = Math.abs(ry);

        double Prx = rx * rx;
        double Pry = ry * ry;
        double Px1 = x1 * x1;
        double Py1 = y1 * y1;

        // check that radii are large enough
        double radiiCheck = Px1 / Prx + Py1 / Pry;
        if (radiiCheck > 1) {
            rx = Math.sqrt(radiiCheck) * rx;
            ry = Math.sqrt(radiiCheck) * ry;
            Prx = rx * rx;
            Pry = ry * ry;
        }

        // Step 2 : Compute (cx1, cy1)
        double sign = (largeArcFlag == sweepFlag) ? -1 : 1;
        double sq = ((Prx * Pry) - (Prx * Py1) - (Pry * Px1))
                / ((Prx * Py1) + (Pry * Px1));
        sq = (sq < 0) ? 0 : sq;
        double coef = (sign * Math.sqrt(sq));
        double cx1 = coef * ((rx * y1) / ry);
        double cy1 = coef * -((ry * x1) / rx);

        double sx2 = (x0 + x) / 2.0;
        double sy2 = (y0 + y) / 2.0;
        double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1);
        double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1);

        // Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle)
        double ux = (x1 - cx1) / rx;
        double uy = (y1 - cy1) / ry;
        double vx = (-x1 - cx1) / rx;
        double vy = (-y1 - cy1) / ry;
        double p, n;

        // Compute the angle start
        n = Math.sqrt((ux * ux) + (uy * uy));
        p = ux; // (1 * ux) + (0 * uy)
        sign = (uy < 0) ? -1.0 : 1.0;
        double angleStart = Math.toDegrees(sign * Math.acos(p / n));

        // Compute the angle extent
        n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
        p = ux * vx + uy * vy;
        sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
        double angleExtent = Math.toDegrees(sign * Math.acos(p / n));
        if (!sweepFlag && angleExtent > 0) {
            angleExtent -= 360f;
        } else if (sweepFlag && angleExtent < 0) {
            angleExtent += 360f;
        }
        angleExtent %= 360f;
        angleStart %= 360f;

        RectF oval = new RectF((float) (cx - rx), (float) (cy - ry), (float) (cx + rx), (float) (cy + ry));
        path.addArc(oval, (float) angleStart, (float) angleExtent);
    }

}

  ------ vector path 数据表

package com.bi3eview.newstart60.local;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.database.Cursor;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.view.Gravity;
import android.view.View;
import android.widget.EditText;
import android.text.InputFilter;
import android.widget.Toast;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.LinearLayout;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

public class COMCONST {
    // 。。。。。。
    // vector path
    public static final String VECTORPATH_TASK = "M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z";
    public static final String VECTORPATH_STAR = "M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z";
    public static final String VECTORPATH_SELMARK = "M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z";
    public static final String VECTORPATH_LOCK = "M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z";;
    // 。。。。
}

  

 

标签:--,double,APP,float,int,import,ImageView,android,ph
From: https://www.cnblogs.com/newstart60/p/16970745.html

相关文章