Initialized custom extension module
19
sample-custom-extension/build.gradle
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
|
||||||
|
compileSdkVersion TARGET_SDK
|
||||||
|
buildToolsVersion BUILD_TOOLS
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "noties.ru.markwon_samplecustomextension"
|
||||||
|
minSdkVersion MIN_SDK
|
||||||
|
targetSdkVersion TARGET_SDK
|
||||||
|
versionCode 1
|
||||||
|
versionName version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(':library')
|
||||||
|
}
|
21
sample-custom-extension/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="noties.ru.markwon_samplecustomextension">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity android:name=".MainActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@ -0,0 +1,7 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import org.commonmark.node.CustomNode;
|
||||||
|
|
||||||
|
public class IconGroupNode extends CustomNode {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.node.CustomNode;
|
||||||
|
import org.commonmark.node.Delimited;
|
||||||
|
|
||||||
|
public class IconNode extends CustomNode implements Delimited {
|
||||||
|
|
||||||
|
|
||||||
|
public static final char DELIMITER = '@';
|
||||||
|
|
||||||
|
public static final String DELIMITER_STRING = "" + DELIMITER;
|
||||||
|
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final String color;
|
||||||
|
|
||||||
|
private final String size;
|
||||||
|
|
||||||
|
public IconNode(@NonNull String name, @NonNull String color, @NonNull String size) {
|
||||||
|
this.name = name;
|
||||||
|
this.color = color;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String color() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOpeningDelimiter() {
|
||||||
|
return DELIMITER_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClosingDelimiter() {
|
||||||
|
return DELIMITER_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "IconNode{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", color='" + color + '\'' +
|
||||||
|
", size='" + size + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import org.commonmark.node.Node;
|
||||||
|
import org.commonmark.node.Text;
|
||||||
|
import org.commonmark.parser.delimiter.DelimiterProcessor;
|
||||||
|
import org.commonmark.parser.delimiter.DelimiterRun;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class IconProcessor implements DelimiterProcessor {
|
||||||
|
|
||||||
|
private static final Pattern PATTERN = Pattern.compile("material-icon-(\\w+)-(\\w+)-(\\w+)");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char getOpeningCharacter() {
|
||||||
|
return IconNode.DELIMITER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char getClosingCharacter() {
|
||||||
|
return IconNode.DELIMITER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinLength() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
|
||||||
|
return opener.length() >= 1 && closer.length() >= 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(Text opener, Text closer, int delimiterUse) {
|
||||||
|
|
||||||
|
final IconGroupNode iconGroupNode = new IconGroupNode();
|
||||||
|
|
||||||
|
final Node next = opener.getNext();
|
||||||
|
|
||||||
|
boolean handled = false;
|
||||||
|
|
||||||
|
// process only if we have exactly one Text node
|
||||||
|
if (next instanceof Text && next.getNext() == closer) {
|
||||||
|
|
||||||
|
final String text = ((Text) next).getLiteral();
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(text)) {
|
||||||
|
|
||||||
|
// attempt to match
|
||||||
|
final Matcher matcher = PATTERN.matcher(text);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
final IconNode iconNode = new IconNode(
|
||||||
|
matcher.group(1),
|
||||||
|
matcher.group(2),
|
||||||
|
matcher.group(3)
|
||||||
|
);
|
||||||
|
iconGroupNode.appendChild(iconNode);
|
||||||
|
next.unlink();
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled) {
|
||||||
|
|
||||||
|
// restore delimiters if we didn't match
|
||||||
|
|
||||||
|
iconGroupNode.appendChild(new Text(IconNode.DELIMITER_STRING));
|
||||||
|
|
||||||
|
Node node;
|
||||||
|
for (Node tmp = opener.getNext(); tmp != null && tmp != closer; tmp = node) {
|
||||||
|
node = tmp.getNext();
|
||||||
|
// append a child anyway
|
||||||
|
iconGroupNode.appendChild(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
iconGroupNode.appendChild(new Text(IconNode.DELIMITER_STRING));
|
||||||
|
}
|
||||||
|
|
||||||
|
opener.insertBefore(iconGroupNode);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.annotation.IntDef;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.style.ReplacementSpan;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
public class IconSpan extends ReplacementSpan {
|
||||||
|
|
||||||
|
@IntDef({ALIGN_BOTTOM, ALIGN_BASELINE, ALIGN_CENTER})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@interface Alignment {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int ALIGN_BOTTOM = 0;
|
||||||
|
public static final int ALIGN_BASELINE = 1;
|
||||||
|
public static final int ALIGN_CENTER = 2; // will only center if drawable height is less than text line height
|
||||||
|
|
||||||
|
|
||||||
|
private final Drawable drawable;
|
||||||
|
|
||||||
|
private final int alignment;
|
||||||
|
|
||||||
|
public IconSpan(@NonNull Drawable drawable, @Alignment int alignment) {
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.alignment = alignment;
|
||||||
|
if (drawable.getBounds().isEmpty()) {
|
||||||
|
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
|
||||||
|
|
||||||
|
final Rect rect = drawable.getBounds();
|
||||||
|
|
||||||
|
if (fm != null) {
|
||||||
|
fm.ascent = -rect.bottom;
|
||||||
|
fm.descent = 0;
|
||||||
|
|
||||||
|
fm.top = fm.ascent;
|
||||||
|
fm.bottom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
|
||||||
|
|
||||||
|
final int b = bottom - drawable.getBounds().bottom;
|
||||||
|
|
||||||
|
final int save = canvas.save();
|
||||||
|
try {
|
||||||
|
final int translationY;
|
||||||
|
if (ALIGN_CENTER == alignment) {
|
||||||
|
translationY = b - ((bottom - top - drawable.getBounds().height()) / 2);
|
||||||
|
} else if (ALIGN_BASELINE == alignment) {
|
||||||
|
translationY = b - paint.getFontMetricsInt().descent;
|
||||||
|
} else {
|
||||||
|
translationY = b;
|
||||||
|
}
|
||||||
|
canvas.translate(x, translationY);
|
||||||
|
drawable.draw(canvas);
|
||||||
|
} finally {
|
||||||
|
canvas.restoreToCount(save);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
public interface IconSpanProvider {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
IconSpan provide(@NonNull String name, @NonNull String color, @NonNull String size);
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.DrawableRes;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
public class IconSpanProviderImpl implements IconSpanProvider {
|
||||||
|
|
||||||
|
private static final boolean IS_L = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private final Resources resources;
|
||||||
|
private final int fallBack;
|
||||||
|
|
||||||
|
public IconSpanProviderImpl(@NonNull Context context, @DrawableRes int fallBack) {
|
||||||
|
this.context = context;
|
||||||
|
this.resources = context.getResources();
|
||||||
|
this.fallBack = fallBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public IconSpan provide(@NonNull String name, @NonNull String color, @NonNull String size) {
|
||||||
|
final String resName = materialIconName(name, color, size);
|
||||||
|
int resId = resources.getIdentifier(resName, "drawable", context.getPackageName());
|
||||||
|
if (resId == 0) {
|
||||||
|
resId = fallBack;
|
||||||
|
}
|
||||||
|
return new IconSpan(getDrawable(resId), IconSpan.ALIGN_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static String materialIconName(@NonNull String name, @NonNull String color, @NonNull String size) {
|
||||||
|
return "ic_" + name + "_" + color + "_" + size + "dp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private Drawable getDrawable(int resId) {
|
||||||
|
final Drawable drawable;
|
||||||
|
if (IS_L) {
|
||||||
|
drawable = context.getDrawable(resId);
|
||||||
|
} else {
|
||||||
|
drawable = resources.getDrawable(resId);
|
||||||
|
}
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
public abstract class IconUtils {
|
||||||
|
|
||||||
|
private static final String TO_FIND = "@material-icon-";
|
||||||
|
|
||||||
|
public static void prepare(@NonNull StringBuilder builder) {
|
||||||
|
|
||||||
|
int start = builder.indexOf(TO_FIND);
|
||||||
|
int end;
|
||||||
|
|
||||||
|
while (start > -1) {
|
||||||
|
end = iconDefinitionEnd(start + TO_FIND.length(), builder);
|
||||||
|
builder.insert(end, '@');
|
||||||
|
start = builder.indexOf(TO_FIND, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int iconDefinitionEnd(int index, @NonNull StringBuilder builder) {
|
||||||
|
|
||||||
|
// all spaces, new lines, non-words or digits,
|
||||||
|
|
||||||
|
char c;
|
||||||
|
|
||||||
|
int end = -1;
|
||||||
|
for (int i = index; i < builder.length(); i++) {
|
||||||
|
c = builder.charAt(i);
|
||||||
|
if (Character.isWhitespace(c)
|
||||||
|
|| !(Character.isLetterOrDigit(c) || c == '-' || c == '_')) {
|
||||||
|
end = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end == -1) {
|
||||||
|
end = builder.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IconUtils() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import org.commonmark.node.CustomNode;
|
||||||
|
|
||||||
|
import ru.noties.markwon.SpannableBuilder;
|
||||||
|
import ru.noties.markwon.SpannableConfiguration;
|
||||||
|
import ru.noties.markwon.renderer.SpannableMarkdownVisitor;
|
||||||
|
|
||||||
|
public class IconVisitor extends SpannableMarkdownVisitor {
|
||||||
|
|
||||||
|
private final SpannableBuilder builder;
|
||||||
|
|
||||||
|
private final IconSpanProvider iconSpanProvider;
|
||||||
|
|
||||||
|
public IconVisitor(
|
||||||
|
@NonNull SpannableConfiguration configuration,
|
||||||
|
@NonNull SpannableBuilder builder,
|
||||||
|
@NonNull IconSpanProvider iconSpanProvider
|
||||||
|
) {
|
||||||
|
super(configuration, builder);
|
||||||
|
this.builder = builder;
|
||||||
|
this.iconSpanProvider = iconSpanProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CustomNode customNode) {
|
||||||
|
if (!visitIconNode(customNode)) {
|
||||||
|
super.visit(customNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean visitIconNode(@NonNull CustomNode customNode) {
|
||||||
|
|
||||||
|
if (customNode instanceof IconNode) {
|
||||||
|
|
||||||
|
final IconNode node = (IconNode) customNode;
|
||||||
|
|
||||||
|
final String name = node.name();
|
||||||
|
final String size = node.size();
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(name)
|
||||||
|
&& !TextUtils.isEmpty(size)) {
|
||||||
|
final int length = builder.length();
|
||||||
|
builder.append(name);
|
||||||
|
builder.setSpan(iconSpanProvider.provide(node.name(), node.color(), node.size()), length);
|
||||||
|
builder.append(' ');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package noties.ru.markwon_samplecustomextension;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension;
|
||||||
|
import org.commonmark.ext.gfm.tables.TablesExtension;
|
||||||
|
import org.commonmark.node.Node;
|
||||||
|
import org.commonmark.parser.Parser;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import ru.noties.markwon.SpannableBuilder;
|
||||||
|
import ru.noties.markwon.SpannableConfiguration;
|
||||||
|
import ru.noties.markwon.tasklist.TaskListExtension;
|
||||||
|
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(0);
|
||||||
|
|
||||||
|
final TextView textView = findViewById(0);
|
||||||
|
|
||||||
|
final Parser parser = new Parser.Builder()
|
||||||
|
// we will register all known to Markwon extensions
|
||||||
|
.extensions(Arrays.asList(
|
||||||
|
StrikethroughExtension.create(),
|
||||||
|
TablesExtension.create(),
|
||||||
|
TaskListExtension.create()
|
||||||
|
))
|
||||||
|
// this is the handler for custom icons
|
||||||
|
.customDelimiterProcessor(new IconProcessor())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final Node node = parser.parse("# Hello icons! @material-icon-home-black-24@\n\n Your account @material-icon-account_balance-white-26@ is 0.00003");
|
||||||
|
final SpannableBuilder builder = new SpannableBuilder();
|
||||||
|
final IconVisitor visitor = new IconVisitor(SpannableConfiguration.create(this), builder, new IconSpanProviderImpl(this, R.drawable.ic_home_black_24dp));
|
||||||
|
node.accept(visitor);
|
||||||
|
textView.setText(builder.text());
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 336 B |
After Width: | Height: | Size: 231 B |
After Width: | Height: | Size: 399 B |
After Width: | Height: | Size: 216 B |
After Width: | Height: | Size: 184 B |
@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1" />
|
||||||
|
</vector>
|
After Width: | Height: | Size: 835 B |
After Width: | Height: | Size: 297 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 327 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 488 B |
After Width: | Height: | Size: 401 B |
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#26A69A"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
</vector>
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
BIN
sample-custom-extension/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 4.9 KiB |
BIN
sample-custom-extension/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 15 KiB |
6
sample-custom-extension/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#3F51B5</color>
|
||||||
|
<color name="colorPrimaryDark">#303F9F</color>
|
||||||
|
<color name="colorAccent">#FF4081</color>
|
||||||
|
</resources>
|
3
sample-custom-extension/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">Markwon-SampleCustomExtension</string>
|
||||||
|
</resources>
|
8
sample-custom-extension/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
@ -1 +1 @@
|
|||||||
include ':app', ':library', ':library-image-loader', ':library-view'
|
include ':app', ':library', ':library-image-loader', ':library-view', ':sample-custom-extension'
|
||||||
|