android自定义view绘制svg资源图片

1. 复杂SVG渲染View实现

public class AdvancedSvgView extends View {

    private static final String TAG = "AdvancedSvgView";

   

    private SVG svg;

    private Map<String, SvgElement> elementMap = new HashMap<>();

    private Map<String, Region> hitRegionMap = new HashMap<>();

    private Map<String, Paint> elementPaintMap = new HashMap<>();

    private Map<String, Object> originalStyles = new HashMap<>();

   

    // 变换参数

    private float scaleFactor = 1.0f;

    private float translateX = 0f;

    private float translateY = 0f;

    private final Matrix renderMatrix = new Matrix();

   

    // 交互相关

    private GestureDetector gestureDetector;

    private OnSvgElementClickListener elementClickListener;

    private String selectedElementId;

   

    // 渐变色缓存

    private final Map<String, Shader> gradientCache = new HashMap<>();

    private final Map<String, Paint> paintCache = new HashMap<>();

   

    // 绘制参数

    private final Paint defaultPaint;

    private final Paint selectionPaint;

    private boolean showHitRegions = false; // 调试用

   

    public interface OnSvgElementClickListener {

        void onSvgElementClick(String elementId, SvgElement element);

    }

   

    public AdvancedSvgView(Context context) {

        super(context);

        init();

        defaultPaint = createDefaultPaint();

        selectionPaint = createSelectionPaint();

    }

   

    public AdvancedSvgView(Context context, AttributeSet attrs) {

        super(context, attrs);

        init();

        defaultPaint = createDefaultPaint();

        selectionPaint = createSelectionPaint();

    }

   

    public AdvancedSvgView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        init();

        defaultPaint = createDefaultPaint();

        selectionPaint = createSelectionPaint();

    }

   

    private void init() {

        setupGestureDetector();

        setLayerType(LAYER_TYPE_SOFTWARE, null); // 确保兼容性

    }

   

    private Paint createDefaultPaint() {

        Paint paint = new Paint();

        paint.setAntiAlias(true);

        paint.setFilterBitmap(true);

        paint.setStyle(Paint.Style.FILL);

        return paint;

    }

   

    private Paint createSelectionPaint() {

        Paint paint = new Paint();

        paint.setAntiAlias(true);

        paint.setStyle(Paint.Style.STROKE);

        paint.setStrokeWidth(3f);

        paint.setColor(Color.RED);

        return paint;

    }

   

    private void setupGestureDetector() {

        gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {

            @Override

        }    public boolean onSingleTapUp(MotionEvent e) {

                handleTap(e.getX(), e.getY());

                return true;

            }

        });

    }

   

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        return gestureDetector.onTouchEvent(event) || super.onTouchEvent(event);

    }

   

    // SVG加载方法

    public void loadSvgFromResource(int resId) {

        try {

            svg = SVG.getFromResource(getContext(), resId);

            processSvgDocument();

            requestLayout();

            invalidate();

        } catch (SVGParseException e) {

            Log.e(TAG, "Error parsing SVG resource", e);

        }

    }

   

    public void loadSvgFromAssets(String filename) {

        try {

            svg = SVG.getFromAsset(getContext().getAssets(), filename);

            processSvgDocument();

            requestLayout();

            invalidate();

        } catch (SVGParseException | IOException e) {

            Log.e(TAG, "Error loading SVG from assets", e);

        }

    }

   

    public void loadSvgFromString(String svgData) {

        try {

            svg = SVG.getFromString(svgData);

            processSvgDocument();

            requestLayout();

            invalidate();

        } catch (SVGParseException e) {

            Log.e(TAG, "Error parsing SVG string", e);

        }

    }

   

    /**

    * 处理SVG文档,提取所有元素和样式

    */

    private void processSvgDocument() {

        elementMap.clear();

        hitRegionMap.clear();

        elementPaintMap.clear();

        originalStyles.clear();

        gradientCache.clear();

        paintCache.clear();

       

        if (svg == null || svg.getRootElement() == null) {

            return;

        }

       

        // 遍历所有元素

        traverseElements(svg.getRootElement(), "");

       

        // 预计算点击区域

        calculateHitRegions();

    }

   

    /**

    * 递归遍历SVG元素

    */

    private void traverseElements(SvgElement element, String parentPath) {

        String elementId = element.getId();

        String fullPath = parentPath + (elementId != null ? "." + elementId : "");

       

        if (elementId != null && !elementId.isEmpty()) {

            elementMap.put(elementId, element);

            storeOriginalStyle(elementId, element);

        }

       

        // 处理子元素

        if (element instanceof Group) {

            Group group = (Group) element;

            for (SvgObject child : group.getChildren()) {

                if (child instanceof SvgElement) {

                    traverseElements((SvgElement) child, fullPath);

                }

            }

        } else if (element instanceof SvgElement) {

            for (SvgObject child : element.getChildren()) {

                if (child instanceof SvgElement) {

                    traverseElements((SvgElement) child, fullPath);

                }

            }

        }

    }

   

    /**

    * 存储元素的原始样式

    */

    private void storeOriginalStyle(String elementId, SvgElement element) {

        Map<String, Object> style = new HashMap<>();

       

        // 存储填充信息

        if (element.getFill() != null) {

            style.put("fill", element.getFill());

        }

       

        // 存储描边信息

        if (element.getStroke() != null) {

            style.put("stroke", element.getStroke());

        }

       

        if (element.getStrokeWidth() != null) {

            style.put("strokeWidth", element.getStrokeWidth());

        }

       

        originalStyles.put(elementId, style);

    }

   

    /**

    * 计算点击区域

    */

    private void calculateHitRegions() {

        for (Map.Entry<String, SvgElement> entry : elementMap.entrySet()) {

            String elementId = entry.getKey();

            SvgElement element = entry.getValue();

           

            if (element instanceof Path) {

                Path pathElement = (Path) element;

                android.graphics.Path path = pathElement.getPath();

               

                // 创建点击区域

                Region region = new Region();

                RectF bounds = new RectF();

                path.computeBounds(bounds, true);

               

                // 应用变换矩阵

                android.graphics.Path transformedPath = new android.graphics.Path();

                path.transform(getRenderMatrix(), transformedPath);

               

                region.setPath(transformedPath, new Region(

                    (int) Math.floor(bounds.left),

                    (int) Math.floor(bounds.top),

                    (int) Math.ceil(bounds.right),

                    (int) Math.ceil(bounds.bottom)

                ));

               

                hitRegionMap.put(elementId, region);

            }

        }

    }

   

    @Override

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        super.onSizeChanged(w, h, oldw, oldh);

        calculateViewport();

        calculateHitRegions();

    }

   

    /**

    * 计算视口变换

    */

    private void calculateViewport() {

        if (svg == null) return;

       

        float svgWidth = svg.getDocumentWidth();

        float svgHeight = svg.getDocumentHeight();

        float viewWidth = getWidth();

        float viewHeight = getHeight();

       

        if (svgWidth > 0 && svgHeight > 0) {

            // 计算缩放比例,保持宽高比

            float scaleX = viewWidth / svgWidth;

            float scaleY = viewHeight / svgHeight;

            scaleFactor = Math.min(scaleX, scaleY);

           

            // 计算居中的偏移量

            translateX = (viewWidth - svgWidth * scaleFactor) / 2;

            translateY = (viewHeight - svgHeight * scaleFactor) / 2;

           

            // 更新渲染矩阵

            renderMatrix.setTranslate(translateX, translateY);

            renderMatrix.preScale(scaleFactor, scaleFactor);

        }

    }

   

    /**

    * 获取渲染矩阵

    */

    private Matrix getRenderMatrix() {

        return renderMatrix;

    }

   

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

       

        if (svg == null || svg.getRootElement() == null) {

            return;

        }

       

        canvas.save();

        canvas.concat(renderMatrix);

       

        // 渲染SVG

        renderSvgElement(canvas, svg.getRootElement());

       

        // 绘制选中状态

        if (selectedElementId != null) {

            drawSelectionHighlight(canvas, selectedElementId);

        }

       

        // 调试:绘制点击区域

        if (showHitRegions) {

            drawHitRegions(canvas);

        }

       

        canvas.restore();

    }

   

    /**

    * 渲染SVG元素

    */

    private void renderSvgElement(Canvas canvas, SvgElement element) {

        if (element instanceof Path) {

            renderPathElement(canvas, (Path) element);

        } else if (element instanceof Group) {

            Group group = (Group) element;

            for (SvgObject child : group.getChildren()) {

                if (child instanceof SvgElement) {

                    renderSvgElement(canvas, (SvgElement) child);

                }

            }

        } else if (element instanceof SvgElement) {

            for (SvgObject child : element.getChildren()) {

                if (child instanceof SvgElement) {

                    renderSvgElement(canvas, (SvgElement) child);

                }

            }

        }

    }

   

    /**

    * 渲染路径元素

    */

    private void renderPathElement(Canvas canvas, Path pathElement) {

        String elementId = pathElement.getId();

        Paint paint = getPaintForElement(pathElement, elementId);

       

        if (paint != null) {

            canvas.drawPath(pathElement.getPath(), paint);

        }

    }

   

    /**

    * 获取元素的绘制Paint

    */

    private Paint getPaintForElement(SvgElement element, String elementId) {

        // 检查缓存

        if (paintCache.containsKey(elementId)) {

            return paintCache.get(elementId);

        }

       

        Paint paint = new Paint(defaultPaint);

        boolean hasFill = false;

       

        // 处理填充

        if (element.getFill() != null) {

            hasFill = applyFillStyle(paint, element.getFill(), elementId);

        }

       

        // 处理描边

        if (element.getStroke() != null) {

            applyStrokeStyle(paint, element);

        }

       

        // 如果没有填充也没有描边,使用默认颜色

        if (!hasFill && paint.getStyle() == Paint.Style.FILL) {

            paint.setColor(Color.GRAY);

        }

       

        paintCache.put(elementId, paint);

        return paint;

    }

   

    /**

    * 应用填充样式

    */

    private boolean applyFillStyle(Paint paint, SvgPaint fill, String elementId) {

        if (fill instanceof Colour) {

            // 纯色填充

            Colour colour = (Colour) fill;

            paint.setColor(colour.getValue());

            paint.setStyle(Paint.Style.FILL);

            return true;

        } else if (fill instanceof SvgLinearGradient) {

            // 线性渐变

            SvgLinearGradient gradient = (SvgLinearGradient) fill;

            LinearGradient linearGradient = createLinearGradient(gradient, elementId);

            if (linearGradient != null) {

                paint.setShader(linearGradient);

                paint.setStyle(Paint.Style.FILL);

                return true;

            }

        } else if (fill instanceof SvgRadialGradient) {

            // 径向渐变

            SvgRadialGradient gradient = (SvgRadialGradient) fill;

            RadialGradient radialGradient = createRadialGradient(gradient, elementId);

            if (radialGradient != null) {

                paint.setShader(radialGradient);

                paint.setStyle(Paint.Style.FILL);

                return true;

            }

        }

       

        return false;

    }

   

    /**

    * 应用描边样式

    */

    private void applyStrokeStyle(Paint paint, SvgElement element) {

        if (element.getStroke() instanceof Colour) {

            Colour strokeColour = (Colour) element.getStroke();

            paint.setColor(strokeColour.getValue());

            paint.setStyle(Paint.Style.STROKE);

           

            if (element.getStrokeWidth() != null) {

                paint.setStrokeWidth(element.getStrokeWidth());

            } else {

                paint.setStrokeWidth(1f);

            }

        }

    }

   

    /**

    * 创建线性渐变

    */

    private LinearGradient createLinearGradient(SvgLinearGradient gradient, String elementId) {

        String cacheKey = "linear_" + elementId;

       

        if (gradientCache.containsKey(cacheKey)) {

            Shader shader = gradientCache.get(cacheKey);

            if (shader instanceof LinearGradient) {

                return (LinearGradient) shader;

            }

        }

       

        try {

            float x1 = gradient.getX1() != null ? gradient.getX1() : 0f;

            float y1 = gradient.getY1() != null ? gradient.getY1() : 0f;

            float x2 = gradient.getX2() != null ? gradient.getX2() : 1f;

            float y2 = gradient.getY2() != null ? gradient.getY2() : 0f;

           

            int stopCount = gradient.getStopCount();

            if (stopCount == 0) return null;

           

            int[] colors = new int[stopCount];

            float[] positions = new float[stopCount];

           

            for (int i = 0; i < stopCount; i++) {

                SVG.SvgStop stop = gradient.getStop(i);

                if (stop.colour instanceof Colour) {

                    colors[i] = ((Colour) stop.colour).getValue();

                } else {

                    colors[i] = Color.BLACK;

                }

                positions[i] = stop.offset;

            }

           

            LinearGradient linearGradient = new LinearGradient(

                x1, y1, x2, y2, colors, positions, Shader.TileMode.CLAMP

            );

           

            gradientCache.put(cacheKey, linearGradient);

            return linearGradient;

           

        } catch (Exception e) {

            Log.e(TAG, "Error creating linear gradient", e);

            return null;

        }

    }

   

    /**

    * 创建径向渐变

    */

    private RadialGradient createRadialGradient(SvgRadialGradient gradient, String elementId) {

        String cacheKey = "radial_" + elementId;

       

        if (gradientCache.containsKey(cacheKey)) {

            Shader shader = gradientCache.get(cacheKey);

            if (shader instanceof RadialGradient) {

                return (RadialGradient) shader;

            }

        }

       

        try {

            float centerX = gradient.getCx() != null ? gradient.getCx() : 0.5f;

            float centerY = gradient.getCy() != null ? gradient.getCy() : 0.5f;

            float radius = gradient.getR() != null ? gradient.getR() : 0.5f;

           

            int stopCount = gradient.getStopCount();

            if (stopCount == 0) return null;

           

            int[] colors = new int[stopCount];

            float[] positions = new float[stopCount];

           

            for (int i = 0; i < stopCount; i++) {

                SVG.SvgStop stop = gradient.getStop(i);

                if (stop.colour instanceof Colour) {

                    colors[i] = ((Colour) stop.colour).getValue();

                } else {

                    colors[i] = Color.BLACK;

                }

                positions[i] = stop.offset;

            }

           

            RadialGradient radialGradient = new RadialGradient(

                centerX, centerY, radius, colors, positions, Shader.TileMode.CLAMP

            );

           

            gradientCache.put(cacheKey, radialGradient);

            return radialGradient;

           

        } catch (Exception e) {

            Log.e(TAG, "Error creating radial gradient", e);

            return null;

        }

    }

   

    /**

    * 处理点击事件

    */

    private void handleTap(float x, float y) {

        String tappedElementId = findElementAt(x, y);

       

        if (tappedElementId != null) {

            selectedElementId = tappedElementId;

            SvgElement element = elementMap.get(tappedElementId);

           

            if (elementClickListener != null) {

                elementClickListener.onSvgElementClick(tappedElementId, element);

            }

           

            invalidate();

        }

    }

   

    /**

    * 查找指定坐标下的元素

    */

    private String findElementAt(float x, float y) {

        // 将屏幕坐标转换为SVG坐标

        float[] point = {x, y};

        Matrix inverseMatrix = new Matrix();

        if (renderMatrix.invert(inverseMatrix)) {

            inverseMatrix.mapPoints(point);

        }

       

        int screenX = (int) point[0];

        int screenY = (int) point[1];

       

        for (Map.Entry<String, Region> entry : hitRegionMap.entrySet()) {

            if (entry.getValue().contains(screenX, screenY)) {

                return entry.getKey();

            }

        }

       

        return null;

    }

   

    /**

    * 绘制选中状态高亮

    */

    private void drawSelectionHighlight(Canvas canvas, String elementId) {

        SvgElement element = elementMap.get(elementId);

        if (element instanceof Path) {

            Path path = (Path) element;

            canvas.drawPath(path.getPath(), selectionPaint);

        }

    }

   

    /**

    * 绘制点击区域(调试用)

    */

    private void drawHitRegions(Canvas canvas) {

        Paint debugPaint = new Paint();

        debugPaint.setColor(Color.argb(100, 255, 0, 0));

        debugPaint.setStyle(Paint.Style.FILL);

       

        for (Region region : hitRegionMap.values()) {

            Rect bounds = region.getBounds();

            canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.bottom, debugPaint);

        }

    }

   

    // 公共API方法

   

    public void setOnSvgElementClickListener(OnSvgElementClickListener listener) {

        this.elementClickListener = listener;

    }

   

    public void setSelectedElement(String elementId) {

        this.selectedElementId = elementId;

        invalidate();

    }

   

    public void clearSelection() {

        this.selectedElementId = null;

        invalidate();

    }

   

    public void changeElementColor(String elementId, int color) {

        SvgElement element = elementMap.get(elementId);

        if (element != null) {

            // 创建新的纯色填充

            element.setFill(new Colour(color));

           

            // 清除Paint缓存,强制重新创建

            paintCache.remove(elementId);

           

            invalidate();

        }

    }

   

    public void changeElementGradient(String elementId, int[] colors, float[] positions) {

        SvgElement element = elementMap.get(elementId);

        if (element != null && colors != null && positions != null && colors.length == positions.length) {

            // 创建新的线性渐变

            SvgLinearGradient gradient = new SvgLinearGradient();

            gradient.setGradientUnits(SvgLinearGradient.GradientUnits.OBJECT_BOUNDING_BOX);

            gradient.setX1(0f);

            gradient.setY1(0f);

            gradient.setX2(1f);

            gradient.setY2(0f);

           

            // 添加颜色停止点

            for (int i = 0; i < colors.length; i++) {

                SVG.SvgStop stop = new SVG.SvgStop(positions[i], new Colour(colors[i]));

                // 这里需要调用gradient的addStop方法,但AndroidSVG API可能不支持直接修改

            }

           

            element.setFill(gradient);

           

            // 清除缓存

            paintCache.remove(elementId);

            gradientCache.entrySet().removeIf(entry -> entry.getKey().contains(elementId));

           

            invalidate();

        }

    }

   

    public void resetElementStyle(String elementId) {

        SvgElement element = elementMap.get(elementId);

        Map<String, Object> originalStyle = (Map<String, Object>) originalStyles.get(elementId);

       

        if (element != null && originalStyle != null) {

            // 恢复原始样式

            if (originalStyle.containsKey("fill")) {

                element.setFill((SvgPaint) originalStyle.get("fill"));

            }

            if (originalStyle.containsKey("stroke")) {

                element.setStroke((SvgPaint) originalStyle.get("stroke"));

            }

           

            // 清除缓存

            paintCache.remove(elementId);

            gradientCache.entrySet().removeIf(entry -> entry.getKey().contains(elementId));

           

            invalidate();

        }

    }

   

    public void resetAllStyles() {

        for (String elementId : elementMap.keySet()) {

            resetElementStyle(elementId);

        }

    }

   

    public void setShowHitRegions(boolean show) {

        this.showHitRegions = show;

        invalidate();

    }

   

    public Set<String> getElementIds() {

        return elementMap.keySet();

    }

   

    public SvgElement getElement(String elementId) {

        return elementMap.get(elementId);

    }

   

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

       

        int width, height;

       

        if (svg != null) {

            float svgWidth = svg.getDocumentWidth();

            float svgHeight = svg.getDocumentHeight();

           

            if (widthMode == MeasureSpec.EXACTLY) {

                width = widthSize;

            } else {

                width = (int) Math.ceil(svgWidth);

                if (widthMode == MeasureSpec.AT_MOST) {

                    width = Math.min(width, widthSize);

                }

            }

           

            if (heightMode == MeasureSpec.EXACTLY) {

                height = heightSize;

            } else {

                height = (int) Math.ceil(svgHeight);

                if (heightMode == MeasureSpec.AT_MOST) {

                    height = Math.min(height, heightSize);

                }

            }

        } else {

            width = widthSize;

            height = heightSize;

        }

       

        setMeasuredDimension(width, height);

    }

}



2.使用

public class MainActivity extends AppCompatActivity {

    private AdvancedSvgView svgView;

    private TextView infoText;

   

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

       

        svgView = findViewById(R.id.svgView);

        infoText = findViewById(R.id.infoText);

       

        // 加载SVG资源

        svgView.loadSvgFromResource(R.raw.complex_gradient_svg);

       

        // 设置点击监听器

        svgView.setOnSvgElementClickListener(new AdvancedSvgView.OnSvgElementClickListener() {

            @Override

            public void onSvgElementClick(String elementId, SvgElement element) {

                infoText.setText("点击了: " + elementId);

               

                // 随机改变颜色

                Random random = new Random();

                int randomColor = Color.rgb(

                    random.nextInt(256),

                    random.nextInt(256),

                    random.nextInt(256)

                );

               

                svgView.changeElementColor(elementId, randomColor);

            }

        });

       

        // 设置控制按钮

        setupControlButtons();

    }

   

    private void setupControlButtons() {

        Button resetButton = findViewById(R.id.resetButton);

        Button gradientButton = findViewById(R.id.gradientButton);

        Button debugButton = findViewById(R.id.debugButton);

       

        resetButton.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                svgView.resetAllStyles();

                infoText.setText("已重置所有样式");

            }

        });

       

        gradientButton.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                // 为第一个元素应用渐变色

                Set<String> elementIds = svgView.getElementIds();

                if (!elementIds.isEmpty()) {

                    String firstElement = elementIds.iterator().next();

                    int[] colors = {Color.RED, Color.YELLOW, Color.GREEN};

                    float[] positions = {0f, 0.5f, 1f};

                    svgView.changeElementGradient(firstElement, colors, positions);

                    infoText.setText("为 " + firstElement + " 应用渐变");

                }

            }

        });

       

        debugButton.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                boolean showDebug = !svgView.isShowHitRegions();

                svgView.setShowHitRegions(showDebug);

                infoText.setText(showDebug ? "显示点击区域" : "隐藏点击区域");

            }

        });

    }

}


3.布局

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:padding="16dp">

    <TextView

        android:id="@+id/infoText"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="点击SVG元素测试交互"

        android:textSize="16sp"

        android:padding="8dp" />

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="horizontal"

        android:gravity="center">

        <Button

            android:id="@+id/resetButton"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="重置"

            android:layout_margin="4dp" />

        <Button

            android:id="@+id/gradientButton"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="应用渐变"

            android:layout_margin="4dp" />

        <Button

            android:id="@+id/debugButton"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="调试模式"

            android:layout_margin="4dp" />

    </LinearLayout>

    <com.example.AdvancedSvgView

        android:id="@+id/svgView"

        android:layout_width="match_parent"

        android:layout_height="0dp"

        android:layout_weight="1"

        android:background="#f0f0f0" />

</LinearLayout>



4总结

核心特性

1. 渐变色支持

· 线性渐变:完整支持 SVG 线性渐变

· 径向渐变:完整支持 SVG 径向渐变

· 渐变缓存:优化性能,避免重复创建

2. 精确点击检测

· 区域映射:为每个路径创建精确的点击区域

· 坐标转换:正确处理屏幕坐标到SVG坐标的转换

· 层级支持:支持复杂的分组结构

3. 动态样式修改

· 颜色修改:实时修改元素颜色

· 渐变修改:动态应用新的渐变色

· 样式重置:恢复原始样式

4. 性能优化

· 缓存机制:Paint和Shader对象缓存

· 按需重绘:只重绘发生变化的元素

· 内存管理:合理管理Region和Path对象

使用说明

1. 添加依赖:确保在build.gradle中添加AndroidSVG依赖

2. 放置资源:将SVG文件放在res/raw目录或assets目录

3. 交互处理:通过点击监听器处理用户交互

4. 样式控制:使用提供的API方法动态修改样式

这个实现能够处理包含复杂渐变色效果的SVG资源,并提供完整的交互支持,适用于地图、图表、图标等需要动态样式修改的场景。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容