Working on new sample application
This commit is contained in:
parent
0505845e4c
commit
e01787982f
@ -68,6 +68,7 @@ ext {
|
||||
'okhttp' : 'com.squareup.okhttp3:okhttp:3.9.0',
|
||||
'prism4j' : 'ru.noties:prism4j:1.1.0',
|
||||
'debug' : 'ru.noties:debug:3.0.0@jar',
|
||||
'adapt' : 'ru.noties:adapt:1.1.0',
|
||||
'dagger' : "com.google.dagger:dagger:$daggerVersion"
|
||||
]
|
||||
|
||||
|
@ -12,11 +12,23 @@ android {
|
||||
versionCode 1
|
||||
versionName version
|
||||
setProperty("archivesBaseName", "markwon-sample-$versionName")
|
||||
|
||||
resConfig 'en'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
dexOptions {
|
||||
preDexLibraries true
|
||||
javaMaxHeapSize '5g'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -31,12 +43,20 @@ dependencies {
|
||||
implementation project(':markwon-syntax-highlight')
|
||||
|
||||
deps.with {
|
||||
implementation it['support-recycler-view']
|
||||
implementation it['okhttp']
|
||||
implementation it['prism4j']
|
||||
implementation it['debug']
|
||||
implementation it['adapt']
|
||||
}
|
||||
|
||||
deps['annotationProcessor'].with {
|
||||
annotationProcessor it['prism4j-bundler']
|
||||
}
|
||||
|
||||
deps['test'].with {
|
||||
testImplementation it['junit']
|
||||
testImplementation it['robolectric']
|
||||
testImplementation it['mockito']
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,10 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".core.CoreActivity" />
|
||||
<activity android:name=".latex.LatexActivity" />
|
||||
<activity android:name=".customextension.CustomExtensionActivity" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -1,12 +1,96 @@
|
||||
package ru.noties.markwon.sample;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import ru.noties.adapt.Adapt;
|
||||
import ru.noties.adapt.OnClickViewProcessor;
|
||||
import ru.noties.debug.AndroidLogDebugOutput;
|
||||
import ru.noties.debug.Debug;
|
||||
import ru.noties.markwon.Markwon;
|
||||
import ru.noties.markwon.sample.core.CoreActivity;
|
||||
import ru.noties.markwon.sample.customextension.CustomExtensionActivity;
|
||||
import ru.noties.markwon.sample.latex.LatexActivity;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
static {
|
||||
Debug.init(new AndroidLogDebugOutput(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// obtain an instance of Markwon
|
||||
// here we are creating as core markwon (no additional plugins are registered)
|
||||
final Markwon markwon = Markwon.create(this);
|
||||
|
||||
final Adapt<SampleItem> adapt = Adapt.builder(SampleItem.class)
|
||||
.include(SampleItem.class, new SampleItemView(markwon), new OnClickViewProcessor<SampleItem>() {
|
||||
@Override
|
||||
public void onClick(@NonNull SampleItem item, @NonNull View view) {
|
||||
showSample(item);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
adapt.setItems(Arrays.asList(SampleItem.values()));
|
||||
|
||||
final RecyclerView recyclerView = findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.addItemDecoration(createSampleItemDecoration());
|
||||
recyclerView.setAdapter(adapt.recyclerViewAdapter());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private SampleItemDecoration createSampleItemDecoration() {
|
||||
final float density = getResources().getDisplayMetrics().density;
|
||||
return new SampleItemDecoration(
|
||||
0xffeeeeee,
|
||||
(int) (24 * density + .5F),
|
||||
(int) (1 * density + .5F),
|
||||
0xFFBDBDBD
|
||||
);
|
||||
}
|
||||
|
||||
private void showSample(@NonNull SampleItem item) {
|
||||
startActivity(sampleItemIntent(this, item));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static Intent sampleItemIntent(@NonNull Context context, @NonNull SampleItem item) {
|
||||
|
||||
final Class<? extends Activity> activity;
|
||||
|
||||
switch (item) {
|
||||
|
||||
case CORE:
|
||||
activity = CoreActivity.class;
|
||||
break;
|
||||
|
||||
case LATEX:
|
||||
activity = LatexActivity.class;
|
||||
break;
|
||||
|
||||
case CUSTOM_EXTENSION:
|
||||
activity = CustomExtensionActivity.class;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("No Activity is associated with sample-item: " + item);
|
||||
}
|
||||
|
||||
return new Intent(context, activity);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package ru.noties.markwon.sample;
|
||||
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
public enum SampleItem {
|
||||
|
||||
// all usages of markwon without plugins (parse, render, setMarkwon, etc)
|
||||
CORE(R.string.sample_core),
|
||||
|
||||
LATEX(R.string.sample_latex),
|
||||
|
||||
CUSTOM_EXTENSION(R.string.sample_custom_extension),
|
||||
|
||||
;
|
||||
|
||||
private final int textResId;
|
||||
|
||||
SampleItem(@StringRes int textResId) {
|
||||
this.textResId = textResId;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
public int textResId() {
|
||||
return textResId;
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package ru.noties.markwon.sample;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.Px;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
class SampleItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private final Rect rect = new Rect();
|
||||
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private final int oddItemBackgroundColor;
|
||||
|
||||
private final int bottomPadding;
|
||||
|
||||
private final int dividerHeight;
|
||||
private final int dividerColor;
|
||||
|
||||
SampleItemDecoration(
|
||||
@ColorInt int oddItemBackgroundColor,
|
||||
@Px int bottomPadding,
|
||||
@Px int dividerHeight,
|
||||
@ColorInt int dividerColor) {
|
||||
this.oddItemBackgroundColor = oddItemBackgroundColor;
|
||||
this.bottomPadding = bottomPadding;
|
||||
this.dividerHeight = dividerHeight;
|
||||
this.dividerColor = dividerColor;
|
||||
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
||||
|
||||
// if bottom < parent.getBottom() -> draw bottom background
|
||||
|
||||
paint.setColor(dividerColor);
|
||||
|
||||
View view;
|
||||
|
||||
// we will use this flag afterwards (if we will have to draw bottom background)
|
||||
// so, if last item is even (no background) -> draw odd
|
||||
// if last item is odd -> draw no background
|
||||
//
|
||||
// let's start with true, so if we have no items no background will be drawn
|
||||
boolean isOdd = true;
|
||||
|
||||
for (int i = 0, count = parent.getChildCount(); i < count; i++) {
|
||||
|
||||
view = parent.getChildAt(i);
|
||||
isOdd = parent.getChildAdapterPosition(view) % 2 != 0;
|
||||
|
||||
// odd
|
||||
if (isOdd) {
|
||||
rect.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
|
||||
paint.setColor(oddItemBackgroundColor);
|
||||
c.drawRect(rect, paint);
|
||||
|
||||
// set divider color back
|
||||
paint.setColor(dividerColor);
|
||||
}
|
||||
|
||||
rect.set(0, view.getBottom(), c.getWidth(), view.getBottom() + dividerHeight);
|
||||
c.drawRect(rect, paint);
|
||||
}
|
||||
|
||||
if (!isOdd && rect.bottom < parent.getBottom()) {
|
||||
|
||||
paint.setColor(oddItemBackgroundColor);
|
||||
|
||||
rect.set(0, rect.bottom, c.getWidth(), parent.getBottom());
|
||||
c.drawRect(rect, paint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
|
||||
// divider to bottom
|
||||
// + {if last} -> bottomPadding
|
||||
|
||||
final int position = parent.getChildAdapterPosition(view);
|
||||
|
||||
final RecyclerView.Adapter<?> adapter = parent.getAdapter();
|
||||
final boolean isLast = adapter != null && position == adapter.getItemCount() - 1;
|
||||
|
||||
final int bottom = isLast
|
||||
? bottomPadding + dividerHeight
|
||||
: dividerHeight;
|
||||
|
||||
outRect.set(0, 0, 0, bottom);
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package ru.noties.markwon.sample;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import ru.noties.adapt.Holder;
|
||||
import ru.noties.adapt.ItemView;
|
||||
import ru.noties.markwon.Markwon;
|
||||
|
||||
class SampleItemView extends ItemView<SampleItem, SampleItemView.SampleHolder> {
|
||||
|
||||
private final Markwon markwon;
|
||||
|
||||
// instance specific factory
|
||||
private final NoCopySpannableFactory factory;
|
||||
|
||||
// instance specific cache
|
||||
private final EnumMap<SampleItem, Spanned> cache;
|
||||
|
||||
SampleItemView(@NonNull Markwon markwon) {
|
||||
this.markwon = markwon;
|
||||
this.factory = new NoCopySpannableFactory();
|
||||
this.cache = new EnumMap<>(SampleItem.class);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SampleHolder createHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
|
||||
|
||||
final SampleHolder holder = new SampleHolder(inflater.inflate(
|
||||
R.layout.adapt_sample_item,
|
||||
parent,
|
||||
false));
|
||||
|
||||
// set Spannable.Factory so when TextView will receive a new content
|
||||
// it won't create new Spannable and copy all the spans but instead
|
||||
// re-use existing Spannable thus improving performance
|
||||
holder.textView.setSpannableFactory(factory);
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindHolder(@NonNull SampleHolder holder, @NonNull SampleItem item) {
|
||||
|
||||
// retrieve an item from cache or create new one
|
||||
// simple lazy loading pattern (cache on first call then re-use)
|
||||
Spanned spanned = cache.get(item);
|
||||
if (spanned == null) {
|
||||
spanned = markwon.toMarkdown(context(holder).getString(item.textResId()));
|
||||
cache.put(item, spanned);
|
||||
}
|
||||
|
||||
holder.textView.setText(spanned);
|
||||
}
|
||||
|
||||
static class SampleHolder extends Holder {
|
||||
|
||||
final TextView textView;
|
||||
|
||||
SampleHolder(@NonNull View view) {
|
||||
super(view);
|
||||
|
||||
this.textView = requireView(R.id.text);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NoCopySpannableFactory extends Spannable.Factory {
|
||||
@Override
|
||||
public Spannable newSpannable(CharSequence source) {
|
||||
return source instanceof Spannable
|
||||
? (Spannable) source
|
||||
: new SpannableString(source);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
package ru.noties.markwon.sample.core;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.commonmark.node.Heading;
|
||||
import org.commonmark.node.Node;
|
||||
import org.commonmark.node.Paragraph;
|
||||
|
||||
import ru.noties.markwon.AbstractMarkwonPlugin;
|
||||
import ru.noties.markwon.Markwon;
|
||||
import ru.noties.markwon.MarkwonPlugin;
|
||||
import ru.noties.markwon.MarkwonSpansFactory;
|
||||
import ru.noties.markwon.MarkwonVisitor;
|
||||
import ru.noties.markwon.core.CorePlugin;
|
||||
import ru.noties.markwon.core.MarkwonTheme;
|
||||
|
||||
public class CoreActivity extends Activity {
|
||||
|
||||
private TextView textView;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
textView = new TextView(this);
|
||||
setContentView(textView);
|
||||
|
||||
step_1();
|
||||
|
||||
step_2();
|
||||
|
||||
step_3();
|
||||
|
||||
step_4();
|
||||
|
||||
step_5();
|
||||
|
||||
step_6();
|
||||
|
||||
step_7();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple instance of Markwon with only Core plugin registered
|
||||
* this will handle all _natively_ supported by commonmark-java nodes:
|
||||
* <ul>
|
||||
* <li>StrongEmphasis</li>
|
||||
* <li>Emphasis</li>
|
||||
* <li>BlockQuote</li>
|
||||
* <li>Code</li>
|
||||
* <li>FencedCodeBlock</li>
|
||||
* <li>IndentedCodeBlock</li>
|
||||
* <li>ListItem (bullet-list and ordered list</li>
|
||||
* <li>Heading</li>
|
||||
* <li>Link</li>
|
||||
* <li>ThematicBreak</li>
|
||||
* <li>Paragraph (please note that there is no default span for a paragraph registered)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* and basic core functionality:
|
||||
* <ul>
|
||||
* <li>Append text</li>
|
||||
* <li>Insert new lines (soft and hard breaks)</li>
|
||||
* </ul>
|
||||
*/
|
||||
private void step_1() {
|
||||
|
||||
// short call
|
||||
final Markwon markwon = Markwon.create(this);
|
||||
|
||||
// this is the same as calling
|
||||
final Markwon markwon2 = Markwon.builder(this)
|
||||
.usePlugin(CorePlugin.create())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* To simply apply raw (non-parsed) markdown call {@link Markwon#setMarkdown(TextView, String)}
|
||||
*/
|
||||
private void step_2() {
|
||||
|
||||
// this is raw markdown
|
||||
final String markdown = "Hello **markdown**!";
|
||||
|
||||
final Markwon markwon = Markwon.create(this);
|
||||
|
||||
// this will parse raw markdown and set parsed content to specified TextView
|
||||
markwon.setMarkdown(textView, markdown);
|
||||
}
|
||||
|
||||
/**
|
||||
* To apply markdown in a different context (other than textView) use {@link Markwon#toMarkdown(String)}
|
||||
* <p>
|
||||
* Please note that some features won't work unless they are used in a TextView context. For example
|
||||
* there might be misplaced ordered lists (ordered list must have TextPaint in order to properly measure
|
||||
* its number). But also images and tables (they belong to independent modules now). Images and tables
|
||||
* are using some work-arounds in order to be displayed in relatively limited context without proper way
|
||||
* of invalidation. But if a Toast for example is created with a custom view
|
||||
* ({@code new Toast(this).setView(...) }) and has access to a TextView everything <em>should</em> work.
|
||||
*/
|
||||
private void step_3() {
|
||||
|
||||
final String markdown = "*Toast* __here__!\n\n> And a quote!";
|
||||
|
||||
final Markwon markwon = Markwon.create(this);
|
||||
|
||||
final Spanned spanned = markwon.toMarkdown(markdown);
|
||||
|
||||
Toast.makeText(this, spanned, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* To apply already parsed markdown use {@link Markwon#setParsedMarkdown(TextView, Spanned)}
|
||||
*/
|
||||
private void step_4() {
|
||||
|
||||
final String markdown = "This **is** pre-parsed [markdown](#)";
|
||||
|
||||
final Markwon markwon = Markwon.create(this);
|
||||
|
||||
// parse markdown to obtain a Node
|
||||
final Node node = markwon.parse(markdown);
|
||||
|
||||
// create a spanned content from parsed node
|
||||
final Spanned spanned = markwon.render(node);
|
||||
|
||||
// apply parsed markdown
|
||||
markwon.setParsedMarkdown(textView, spanned);
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to apply paragraph spans a custom plugin should be created (CorePlugin will take care
|
||||
* of everything else).
|
||||
* <p>
|
||||
* Please note that when a plugin is registered and it <em>depends</em> on CorePlugin, there is no
|
||||
* need to explicitly specify it. By default all plugins that extend AbstractMarkwonPlugin do declare
|
||||
* it\'s dependency on CorePlugin ({@link MarkwonPlugin#priority()}).
|
||||
* <p>
|
||||
* Order in which plugins are specified to the builder is of little importance as long as each
|
||||
* plugin clearly states what dependencies it has
|
||||
*/
|
||||
private void step_5() {
|
||||
|
||||
final String markdown = "# Hello!\n\nA paragraph?\n\nIt should be!";
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||
builder.setFactory(Paragraph.class, (configuration, props) ->
|
||||
new ForegroundColorSpan(Color.GREEN));
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, markdown);
|
||||
}
|
||||
|
||||
/**
|
||||
* To disable some nodes from rendering another custom plugin can be used
|
||||
*/
|
||||
private void step_6() {
|
||||
|
||||
final String markdown = "# Heading 1\n\n## Heading 2\n\n**other** content [here](#)";
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||
// for example to disable rendering of heading:
|
||||
// try commenting this out to see that otherwise headings will be rendered
|
||||
builder.on(Heading.class, null);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, markdown);
|
||||
}
|
||||
|
||||
/**
|
||||
* To customize core theme plugins can be used again
|
||||
*/
|
||||
private void step_7() {
|
||||
|
||||
final String markdown = "`A code` that is rendered differently\n\n```\nHello!\n```";
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
|
||||
builder
|
||||
.codeBackgroundColor(Color.BLACK)
|
||||
.codeTextColor(Color.RED);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, markdown);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package ru.noties.markwon.sample.customextension;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
public class CustomExtensionActivity extends Activity {
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package ru.noties.markwon.sample.latex;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class LatexActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
}
|
||||
}
|
15
sample/src/main/res/layout/activity_main.xml
Normal file
15
sample/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
</FrameLayout>
|
13
sample/src/main/res/layout/adapt_sample_item.xml
Normal file
13
sample/src/main/res/layout/adapt_sample_item.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:lineSpacingExtra="2dip"
|
||||
android:padding="16dip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#212121"
|
||||
android:textSize="17sp"
|
||||
tools:text="# This is text" />
|
6
sample/src/main/res/values-v21/styles.xml
Normal file
6
sample/src/main/res/values-v21/styles.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
|
||||
|
||||
<style name="BaseAppTheme" parent="android:Theme.Material.Light.DarkActionBar" />
|
||||
|
||||
</resources>
|
10
sample/src/main/res/values/strings-samples.xml
Normal file
10
sample/src/main/res/values/strings-samples.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!--Ignore missing translation warning-->
|
||||
|
||||
<string name="sample_core"># \# Core\n\nSimple usage example</string>
|
||||
<string name="sample_latex"># \# LaTeX\n\nShows how to display a **LaTeX** formula in a Markwon powered application</string>
|
||||
<string name="sample_custom_extension"># \# Custom extension\n\nShows how to create a custom extension to display an icon referenced in markdown as `@ic-android-black-24`</string>
|
||||
|
||||
</resources>
|
@ -1,8 +1,7 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
<style name="BaseAppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
|
||||
|
||||
<style name="AppTheme" parent="BaseAppTheme" />
|
||||
|
||||
</resources>
|
||||
|
@ -0,0 +1,25 @@
|
||||
package ru.noties.markwon.sample;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE)
|
||||
public class MainActivityTest {
|
||||
|
||||
@Test
|
||||
public void all_sample_items_have_activity_associated() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
for (SampleItem item : SampleItem.values()) {
|
||||
// we assert as not null, but in case of an error this method should throw
|
||||
assertNotNull(MainActivity.sampleItemIntent(context, item));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user