mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Added support for layer list drawables
This commit is contained in:
Generated
+1
@@ -57,6 +57,7 @@
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/menu/menu_editor.xml" value="0.20512820512820512" />
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/menu/menu_editor_nav.xml" value="0.20512820512820512" />
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/common/src/main/res/layout/layout_color_picker.xml" value="0.264" />
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/xml-inflater/src/main/res/drawable/empy_drawable.xml" value="0.147" />
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/xml-inflater/src/main/res/drawable/test.xml" value="0.1675925925925926" />
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable-mdpi/bg_widgets_list.xml" value="0.3105485232067511" />
|
||||
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable-mdpi/ic_widget_progress.xml" value="0.3071729957805907" />
|
||||
|
||||
Binary file not shown.
+32
-20
@@ -55,13 +55,13 @@ public abstract class DrawableParserFactory {
|
||||
* is an XML document, then a suitable parser is determined by looking at the root tag of the
|
||||
* drawable.
|
||||
*
|
||||
* @param context The context. This will be used for obtaining app resources.
|
||||
* @param file The file to parse.
|
||||
* @param context The context. This will be used for obtaining app resources.
|
||||
* @param file The file to parse.
|
||||
* @param resourceFinder The resource finder. Used for finding references to another resources.
|
||||
* @return A new {@link IDrawableParser} instance if the inputs are valid, or {@code null} if there were any
|
||||
* issues creating the parser.
|
||||
* issues creating the parser.
|
||||
* @throws XmlPullParserException Thrown by the {@link XmlPullParser#setInput(Reader)}.
|
||||
* @throws IOException Thrown by {@link XmlPullParser#next()}
|
||||
* @throws IOException Thrown by {@link XmlPullParser#next()}
|
||||
*/
|
||||
@Nullable
|
||||
public static IDrawableParser newParser (@NonNull final Context context, @NonNull final File file, final IResourceTable resourceFinder) throws XmlPullParserException, IOException {
|
||||
@@ -86,13 +86,13 @@ public abstract class DrawableParserFactory {
|
||||
/**
|
||||
* Create a new drawable parser for the given xml code.
|
||||
*
|
||||
* @param xmlDrawable The XML code. This must be valid.
|
||||
* @param xmlDrawable The XML code. This must be valid.
|
||||
* @param resourceFinder The resource finder. Used for finding references to another resources.
|
||||
* @param displayMetrics This will be used by generated parsers to parse dimension vlaues.
|
||||
* @return A new {@link IDrawableParser} instance if the inputs are valid, or {@code null} if there were any
|
||||
* issues creating the parser.
|
||||
* issues creating the parser.
|
||||
* @throws XmlPullParserException Thrown by the {@link XmlPullParser#setInput(Reader)}.
|
||||
* @throws IOException Thrown by {@link XmlPullParser#next()}
|
||||
* @throws IOException Thrown by {@link XmlPullParser#next()}
|
||||
*/
|
||||
@Nullable
|
||||
public static IDrawableParser newXmlDrawableParser (String xmlDrawable, IResourceTable resourceFinder, DisplayMetrics displayMetrics) throws XmlPullParserException, IOException {
|
||||
@@ -106,33 +106,45 @@ public abstract class DrawableParserFactory {
|
||||
while (event != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final var name = parser.getName ();
|
||||
switch (name) {
|
||||
case "shape" :
|
||||
return new ShapeDrawableParser (parser, resourceFinder, displayMetrics);
|
||||
case "vector" :
|
||||
return new NoParser (VectorMasterDrawable.fromXML (xmlDrawable));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return parserForTag (xmlDrawable, resourceFinder, displayMetrics, parser, name);
|
||||
}
|
||||
event = parser.next ();
|
||||
}
|
||||
|
||||
// TODO Implement parsers for these root tags if possible
|
||||
// 1. <bitmap>
|
||||
// 2. <nine-patch>
|
||||
// 2. <nine-patch>------ DONE
|
||||
// 3. <layer-list>
|
||||
// 4. <selector>
|
||||
// 5. <level-list>
|
||||
// 6. <transition>
|
||||
// 7. <inset>
|
||||
// 7. <inset>----------- DONE
|
||||
// 8. <clip>
|
||||
// 9. <scale>
|
||||
|
||||
// We don't support parsing of this type of drawable
|
||||
// Cannot parse this type of drawable
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IDrawableParser parserForTag (String xmlDrawable, IResourceTable resourceFinder, DisplayMetrics displayMetrics, XmlPullParser parser, @NonNull String name) throws XmlPullParserException {
|
||||
switch (name) {
|
||||
case "shape":
|
||||
return new ShapeDrawableParser (parser, resourceFinder, displayMetrics, IDrawableParser.ANY_DEPTH);
|
||||
case "inset":
|
||||
return new InsetDrawableParser (parser, resourceFinder, displayMetrics, IDrawableParser.ANY_DEPTH);
|
||||
case "layer-list":
|
||||
return new LayerListParser (parser, resourceFinder, displayMetrics, IDrawableParser.ANY_DEPTH);
|
||||
case "vector":
|
||||
if (xmlDrawable != null) {
|
||||
return new NoParser (VectorMasterDrawable.fromXML (xmlDrawable));
|
||||
}
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of parsing anything, this returns the provided drawable.
|
||||
*/
|
||||
@@ -141,10 +153,10 @@ public abstract class DrawableParserFactory {
|
||||
private final Drawable parsed;
|
||||
|
||||
protected NoParser (final Drawable parsed) {
|
||||
super (null, null, null);
|
||||
super (null, null, null, ANY_DEPTH);
|
||||
this.parsed = parsed;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Drawable parse () {
|
||||
return parsed;
|
||||
|
||||
@@ -33,15 +33,44 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
*/
|
||||
public abstract class IDrawableParser extends CommonParseUtils {
|
||||
|
||||
protected final XmlPullParser parser;
|
||||
public static final int ANY_DEPTH = -1;
|
||||
|
||||
protected IDrawableParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics) {
|
||||
super(resourceFinder, displayMetrics);
|
||||
protected final XmlPullParser parser;
|
||||
protected int minDepth;
|
||||
|
||||
protected IDrawableParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics, int minDepth) {
|
||||
super (resourceFinder, displayMetrics);
|
||||
this.parser = parser;
|
||||
this.minDepth = minDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the drawable using the already provided parser and data.
|
||||
*
|
||||
* @return The parsed {@link Drawable} or <code>null</code> if the parse was unsuccessful.
|
||||
* @throws Exception If any fatal error occurred while parsing the drawable.
|
||||
*/
|
||||
public abstract Drawable parse () throws Exception;
|
||||
|
||||
/**
|
||||
* Set the minimum depth that this parser should keep parsing.
|
||||
* Subclasses are expected to parse child tags with depths greater
|
||||
* than this specified value.
|
||||
*
|
||||
* @param minDepth The minimum depth of this parser.
|
||||
* @return <code>this</code> instance for chained method calls.
|
||||
*/
|
||||
public IDrawableParser setMinDepth (int minDepth) {
|
||||
this.minDepth = minDepth;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of the attribute with the given name.
|
||||
*
|
||||
* @param name The name of the attribute to look for.
|
||||
* @return The index of the attribute or <code>-1</code>.
|
||||
*/
|
||||
protected int attrIndex (final String name) {
|
||||
for (int i = 0; i < this.parser.getAttributeCount (); i++) {
|
||||
if (this.parser.getAttributeName (i).equals (name)) {
|
||||
@@ -52,23 +81,45 @@ public abstract class IDrawableParser extends CommonParseUtils {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the attribute at the given index.
|
||||
*
|
||||
* @param index The index of the attribute.
|
||||
* @return The value of the attribute.
|
||||
*/
|
||||
protected String value (int index) {
|
||||
return parser.getAttributeValue (index);
|
||||
}
|
||||
|
||||
protected boolean isApi26() {
|
||||
/**
|
||||
* Checks if the drawable parser is allowed to parse at the current depth.
|
||||
* This must be checked if the drawable parser keeps looking for {@link XmlPullParser#START_TAG}
|
||||
* or {@link XmlPullParser#END_TAG}.
|
||||
* <p>
|
||||
* The {@link LayerListParser} can contain tags which are expected to be parsed by other parsers. So,
|
||||
* if the nesting parser does not check if this method if <code>true</code>, it might consume all
|
||||
* the events and the {@link LayerListParser} will have invalid data to parse. In some cases, the nested
|
||||
* parser might consume all the events until {@link XmlPullParser#END_DOCUMENT}.
|
||||
*
|
||||
* @return <code>true</code> if the parser can keep parsing, <code>false</code> otherwise.
|
||||
*/
|
||||
protected boolean canParse () {
|
||||
return this.parser.getDepth () >= minDepth;
|
||||
}
|
||||
|
||||
protected boolean isApi26 () {
|
||||
return Build.VERSION.SDK_INT >= 26;
|
||||
}
|
||||
|
||||
protected boolean isApi28() {
|
||||
protected boolean isApi28 () {
|
||||
return Build.VERSION.SDK_INT >= 28;
|
||||
}
|
||||
|
||||
protected boolean isApi29() {
|
||||
protected boolean isApi29 () {
|
||||
return Build.VERSION.SDK_INT >= 29;
|
||||
}
|
||||
|
||||
protected boolean isApi30() {
|
||||
protected boolean isApi30 () {
|
||||
return Build.VERSION.SDK_INT >= 30;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
*/
|
||||
public class InsetDrawableParser extends IDrawableParser {
|
||||
|
||||
protected InsetDrawableParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics) {
|
||||
super (parser, resourceFinder, displayMetrics);
|
||||
protected InsetDrawableParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics, int minDepth) {
|
||||
super (parser, resourceFinder, displayMetrics, minDepth);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.itsaky.inflater.drawable;
|
||||
|
||||
import static com.itsaky.inflater.util.Preconditions.assertNotBlank;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.itsaky.androidide.app.BaseApplication;
|
||||
import com.itsaky.inflater.IResourceTable;
|
||||
import com.itsaky.inflater.util.TextDrawable;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* Parser for parsing <layer-list> drawables.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
public class LayerListParser extends IDrawableParser {
|
||||
|
||||
protected LayerListParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics, int minDepth) {
|
||||
super (parser, resourceFinder, displayMetrics, minDepth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable parse () throws Exception {
|
||||
final var layer = new LayerDrawable (new Drawable[0]);
|
||||
var index = -1;
|
||||
var value = "";
|
||||
var event = parser.getEventType ();
|
||||
int left = 0, top = 0, right = 0, bottom = 0;
|
||||
var parseInner = true;
|
||||
while (event != XmlPullParser.END_DOCUMENT && canParse ()) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final var name = parser.getName ();
|
||||
if ("item".equals (name)) {
|
||||
index = attrIndex ("drawable");
|
||||
Drawable drawable = null;
|
||||
if (index != -1) {
|
||||
value = value (index);
|
||||
assertNotBlank (value, "Invalid value for android:drawable attribute");
|
||||
drawable = parseDrawable (value, BaseApplication.getBaseInstance ());
|
||||
|
||||
// if the android:drawable is specified, we do not parse the inner elements of <item>
|
||||
parseInner = false;
|
||||
}
|
||||
|
||||
index = attrIndex ("left");
|
||||
left = index == -1 ? 0 : parseDimension (value (index), 0);
|
||||
|
||||
index = attrIndex ("top");
|
||||
top = index == -1 ? 0 : parseDimension (value (index), 0);
|
||||
|
||||
index = attrIndex ("right");
|
||||
right = index == -1 ? 0 : parseDimension (value (index), 0);
|
||||
|
||||
index = attrIndex ("bottom");
|
||||
bottom = index == -1 ? 0 : parseDimension (value (index), 0);
|
||||
|
||||
if (drawable == null) {
|
||||
parseInner = true;
|
||||
} else {
|
||||
addLayer (layer, drawable, left, top, right, bottom);
|
||||
}
|
||||
|
||||
if (!parseInner) {
|
||||
skipToEndTag (this.parser.getDepth ());
|
||||
}
|
||||
} else if (parser.getDepth () > 2 && parseInner) {
|
||||
// depth 1 = <layer-list>
|
||||
// depth 2 = <item>
|
||||
// depth > 2 = child drawables inside <item> tag
|
||||
final var parser = DrawableParserFactory.parserForTag (null, resourceFinder, displayMetrics, this.parser, name);
|
||||
if (parser != null) {
|
||||
parser.setMinDepth (this.parser.getDepth ());
|
||||
var d = parser.parse ();
|
||||
if (d == null) {
|
||||
d = unsupported ();
|
||||
}
|
||||
|
||||
addLayer (layer, d, left, top, right, bottom);
|
||||
} else {
|
||||
addLayer (layer, unsupported (), left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = parser.next ();
|
||||
}
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
private void addLayer (LayerDrawable layer, Drawable drawable, int left, int top, int right, int bottom) {
|
||||
final int index = layer.addLayer (drawable);
|
||||
layer.setLayerInset (index, left, top, right, bottom);
|
||||
}
|
||||
|
||||
private void skipToEndTag (int depth) throws Exception {
|
||||
for (var event = parser.getEventType (); event != XmlPullParser.END_DOCUMENT; event = parser.next ()) {
|
||||
if (event == XmlPullParser.END_TAG && depth == parser.getDepth ()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Contract(" -> new")
|
||||
private Drawable unsupported () {
|
||||
return new TextDrawable ("Unsupported drawable", displayMetrics);
|
||||
}
|
||||
}
|
||||
@@ -44,14 +44,14 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class ShapeDrawableParser extends IDrawableParser {
|
||||
|
||||
protected ShapeDrawableParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics) {
|
||||
super (parser, resourceFinder, displayMetrics);
|
||||
protected ShapeDrawableParser (XmlPullParser parser, IResourceTable resourceFinder, DisplayMetrics displayMetrics, int minDepth) {
|
||||
super (parser, resourceFinder, displayMetrics, minDepth);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Drawable parse () throws Exception {
|
||||
|
||||
|
||||
final var drawable = new GradientDrawable ();
|
||||
|
||||
var index = attrIndex ("shape");
|
||||
@@ -66,7 +66,7 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
|
||||
index = attrIndex ("thickness");
|
||||
drawable.setThickness (index == -1 ? 0 : parseDimension (value (index), 0));
|
||||
|
||||
|
||||
index = attrIndex ("thicknessRatio");
|
||||
drawable.setThicknessRatio (index == -1 ? 1f : Float.parseFloat (value (index)));
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
drawable.setUseLevel (index != -1 && parseBoolean (value (index)));
|
||||
|
||||
var event = parser.getEventType ();
|
||||
while (event != XmlPullParser.END_DOCUMENT) {
|
||||
while (event != XmlPullParser.END_DOCUMENT && canParse ()) {
|
||||
final var name = parser.getName ();
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
switch (name) {
|
||||
@@ -85,16 +85,16 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
case "gradient":
|
||||
parseGradient (drawable);
|
||||
break;
|
||||
case "padding" :
|
||||
case "padding":
|
||||
parsePadding (drawable);
|
||||
break;
|
||||
case "size" :
|
||||
case "size":
|
||||
parseSize (drawable);
|
||||
break;
|
||||
case "solid" :
|
||||
case "solid":
|
||||
parseSolid (drawable);
|
||||
break;
|
||||
case "stroke" :
|
||||
case "stroke":
|
||||
parseStroke (drawable);
|
||||
break;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
private void parseStroke (@NonNull final GradientDrawable drawable) {
|
||||
var index = attrIndex ("width");
|
||||
var strokeWidth = 0;
|
||||
if (index != - 1) {
|
||||
if (index != -1) {
|
||||
drawable.setStroke (strokeWidth = parseDimension (value (index), 0), Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
|
||||
final var rect = new Rect ();
|
||||
if (!drawable.getPadding (rect)) {
|
||||
rect.set (0,0,0,0);
|
||||
rect.set (0, 0, 0, 0);
|
||||
}
|
||||
|
||||
var changed = false;
|
||||
@@ -167,19 +167,19 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
rect.left = parseDimension (value (index), 0);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
index = attrIndex ("top");
|
||||
if (index != -1) {
|
||||
rect.top = parseDimension (value (index), 0);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
index = attrIndex ("right");
|
||||
if (index != -1) {
|
||||
rect.right = parseDimension (value (index), 0);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
index = attrIndex ("bottom");
|
||||
if (index != -1) {
|
||||
rect.bottom = parseDimension (value (index), 0);
|
||||
@@ -196,26 +196,26 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
drawable.setOrientation (index == -1 ? GradientDrawable.Orientation.LEFT_RIGHT : parseGradientOrientation (value (index)));
|
||||
|
||||
index = attrIndex ("centerX");
|
||||
var center = index == - 1 ? drawable.getGradientCenterX () : Float.parseFloat (value (index));
|
||||
var center = index == -1 ? drawable.getGradientCenterX () : Float.parseFloat (value (index));
|
||||
drawable.setGradientCenter (center, drawable.getGradientCenterY ());
|
||||
|
||||
|
||||
index = attrIndex ("centerY");
|
||||
center = index == - 1 ? drawable.getGradientCenterX () : Float.parseFloat (value (index));
|
||||
center = index == -1 ? drawable.getGradientCenterX () : Float.parseFloat (value (index));
|
||||
drawable.setGradientCenter (drawable.getGradientCenterX (), center);
|
||||
|
||||
final var colors = new int [3];
|
||||
final var colors = new int[3];
|
||||
var changed = false;
|
||||
Arrays.fill (colors, -1);
|
||||
|
||||
index = attrIndex ("centerColor");
|
||||
if (index != -1) {
|
||||
colors [1] = parseColor (value (index), appContext ());
|
||||
colors[1] = parseColor (value (index), appContext ());
|
||||
changed = true;
|
||||
}
|
||||
|
||||
index = attrIndex ("endColor");
|
||||
if (index != -1) {
|
||||
colors [2] = parseColor (value (index), appContext ());
|
||||
colors[2] = parseColor (value (index), appContext ());
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@@ -241,11 +241,11 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
|
||||
private int parseGradientType (String value) {
|
||||
switch (value) {
|
||||
case "radial" :
|
||||
case "radial":
|
||||
return GradientDrawable.RADIAL_GRADIENT;
|
||||
case "sweep" :
|
||||
case "sweep":
|
||||
return GradientDrawable.SWEEP_GRADIENT;
|
||||
case "linear" :
|
||||
case "linear":
|
||||
default:
|
||||
return GradientDrawable.LINEAR_GRADIENT;
|
||||
}
|
||||
@@ -307,14 +307,14 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
if (index != -1) {
|
||||
radii[2] = radii[3] = parseDimension (value (index), 0);
|
||||
changed = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
index = attrIndex ("bottomLeftRadius");
|
||||
if (index != -1) {
|
||||
radii[4] = radii[5] = parseDimension (value (index), 0);
|
||||
changed = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
index = attrIndex ("bottomRightRadius");
|
||||
@@ -331,13 +331,13 @@ public class ShapeDrawableParser extends IDrawableParser {
|
||||
@Contract(pure = true)
|
||||
private int parseShape (@NonNull String value) {
|
||||
switch (value) {
|
||||
case "oval" :
|
||||
case "oval":
|
||||
return GradientDrawable.OVAL;
|
||||
case "line":
|
||||
return GradientDrawable.LINE;
|
||||
case "ring" :
|
||||
case "ring":
|
||||
return GradientDrawable.RING;
|
||||
case "rectangle" :
|
||||
case "rectangle":
|
||||
default:
|
||||
return GradientDrawable.RECTANGLE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.itsaky.inflater.util;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class TextDrawable extends Drawable {
|
||||
private static final int DEFAULT_COLOR = Color.WHITE;
|
||||
private static final int DEFAULT_TEXT_SIZE = 15;
|
||||
private final Paint mPaint;
|
||||
private final CharSequence mText;
|
||||
private final int mIntrinsicWidth;
|
||||
private final int mIntrinsicHeight;
|
||||
|
||||
public TextDrawable (CharSequence text, @NonNull DisplayMetrics displayMetrics) {
|
||||
mText = text;
|
||||
mPaint = new Paint (Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setColor (DEFAULT_COLOR);
|
||||
mPaint.setTextAlign (Align.CENTER);
|
||||
float textSize = TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_SP,
|
||||
DEFAULT_TEXT_SIZE, displayMetrics);
|
||||
mPaint.setTextSize (textSize);
|
||||
mIntrinsicWidth = (int) (mPaint.measureText (mText, 0, mText.length ()) + .5);
|
||||
mIntrinsicHeight = mPaint.getFontMetricsInt (null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw (Canvas canvas) {
|
||||
Rect bounds = getBounds ();
|
||||
canvas.drawText (mText, 0, mText.length (),
|
||||
bounds.centerX (), bounds.centerY (), mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity () {
|
||||
return mPaint.getAlpha ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth () {
|
||||
return mIntrinsicWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight () {
|
||||
return mIntrinsicHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha (int alpha) {
|
||||
mPaint.setAlpha (alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter (ColorFilter filter) {
|
||||
mPaint.setColorFilter (filter);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user