Added library-view module

This commit is contained in:
Dimitry Ivanov 2017-05-27 15:51:41 +03:00
parent 1ea0450025
commit 332675cdee
13 changed files with 369 additions and 1 deletions

View File

@ -29,6 +29,7 @@ ext {
// Dependencies
final def supportVersion = '25.3.1'
SUPPORT_ANNOTATIONS = "com.android.support:support-annotations:$supportVersion"
SUPPORT_APP_COMPAT = "com.android.support:appcompat-v7:$supportVersion"
final def commonMarkVersion = '0.9.0'
COMMON_MARK = "com.atlassian.commonmark:commonmark:$commonMarkVersion"

23
library-view/build.gradle Normal file
View File

@ -0,0 +1,23 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion TARGET_SDK
buildToolsVersion BUILD_TOOLS
defaultConfig {
minSdkVersion MIN_SDK
targetSdkVersion TARGET_SDK
versionCode 1
versionName version
}
}
dependencies {
compile project(':library')
provided SUPPORT_APP_COMPAT
}
if (project.hasProperty('release')) {
apply from: 'https://raw.githubusercontent.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
}

View File

@ -0,0 +1,31 @@
package ru.noties.markwon.view.debug;
import android.content.Context;
import android.support.annotation.NonNull;
import ru.noties.markwon.SpannableConfiguration;
import ru.noties.markwon.spans.SpannableTheme;
import ru.noties.markwon.view.IMarkwonView;
public class DebugConfigurationProvider implements IMarkwonView.ConfigurationProvider {
private SpannableConfiguration cached;
@NonNull
@Override
public SpannableConfiguration provide(@NonNull Context context) {
if (cached == null) {
cached = SpannableConfiguration.builder(context)
.theme(debugTheme(context))
.build();
}
return cached;
}
private static SpannableTheme debugTheme(@NonNull Context context) {
return SpannableTheme.builderWithDefaults(context)
.blockQuoteColor(0xFFff0000)
.codeBackgroundColor(0x40FF0000)
.build();
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ru.noties.markwon.view.MarkwonView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:textColor="#333"
app:mv_configurationProvider="ru.noties.markwon.view.debug.DebugConfigurationProvider"
app:mv_markdown="@string/debug_markdown"/>
</ScrollView>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ru.noties.markwon.view.MarkwonViewCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:textColor="#333"
app:mv_configurationProvider="ru.noties.markwon.view.debug.DebugConfigurationProvider"
app:mv_markdown="@string/debug_markdown"/>
</ScrollView>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="debug_markdown">
<![CDATA[
# Hello
\n
**Bold title, right (layout preview somehow cannot render it)?**
\n
> Quote
\n
>> Quote #2
\n
>>> Quote `#3`
\n
---
\n
```
\n
// this is some amazing code block
\n
```
\n
* First
\n
* Second
\n
* * Second-First
\n
* * Second-Second
\n
* * * Second-Second-First
\n
* And out of blue - Third
]]>
</string>
</resources>

View File

@ -0,0 +1 @@
<manifest package="ru.noties.markwon.view" />

View File

@ -0,0 +1,23 @@
package ru.noties.markwon.view;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.SpannableConfiguration;
public interface IMarkwonView {
interface ConfigurationProvider {
@NonNull
SpannableConfiguration provide(@NonNull Context context);
}
void setConfigurationProvider(@NonNull ConfigurationProvider provider);
void setMarkdown(@Nullable String markdown);
void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown);
@Nullable
String getMarkdown();
}

View File

@ -0,0 +1,50 @@
package ru.noties.markwon.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.TextView;
import ru.noties.markwon.SpannableConfiguration;
@SuppressLint("AppCompatCustomView")
public class MarkwonView extends TextView implements IMarkwonView {
private MarkwonViewHelper helper;
public MarkwonView(Context context) {
super(context);
init(context, null);
}
public MarkwonView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attributeSet) {
helper = MarkwonViewHelper.create(this);
helper.init(context, attributeSet);
}
@Override
public void setConfigurationProvider(@NonNull ConfigurationProvider provider) {
helper.setConfigurationProvider(provider);
}
public void setMarkdown(@Nullable String markdown) {
helper.setMarkdown(markdown);
}
public void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown) {
helper.setMarkdown(configuration, markdown);
}
@Nullable
@Override
public String getMarkdown() {
return helper.getMarkdown();
}
}

View File

@ -0,0 +1,50 @@
package ru.noties.markwon.view;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import ru.noties.markwon.SpannableConfiguration;
public class MarkwonViewCompat extends AppCompatTextView implements IMarkwonView {
private MarkwonViewHelper helper;
public MarkwonViewCompat(Context context) {
super(context);
init(context, null);
}
public MarkwonViewCompat(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attributeSet) {
helper = MarkwonViewHelper.create(this);
helper.init(context, attributeSet);
}
@Override
public void setConfigurationProvider(@NonNull ConfigurationProvider provider) {
helper.setConfigurationProvider(provider);
}
@Override
public void setMarkdown(@Nullable String markdown) {
helper.setMarkdown(markdown);
}
@Override
public void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown) {
helper.setMarkdown(configuration, markdown);
}
@Nullable
@Override
public String getMarkdown() {
return helper.getMarkdown();
}
}

View File

@ -0,0 +1,105 @@
package ru.noties.markwon.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.SpannableConfiguration;
public class MarkwonViewHelper implements IMarkwonView {
public static <V extends TextView> MarkwonViewHelper create(@NonNull V view) {
return new MarkwonViewHelper(view);
}
private final TextView textView;
private ConfigurationProvider provider;
private SpannableConfiguration configuration;
private String markdown;
private MarkwonViewHelper(@NonNull TextView textView) {
this.textView = textView;
}
public void init(Context context, AttributeSet attributeSet) {
if (attributeSet != null) {
final TypedArray array = context.obtainStyledAttributes(attributeSet, R.styleable.MarkwonView);
try {
final String configurationProvider = array.getString(R.styleable.MarkwonView_mv_configurationProvider);
final ConfigurationProvider provider;
if (!TextUtils.isEmpty(configurationProvider)) {
provider = MarkwonViewHelper.obtainProvider(configurationProvider);
} else {
provider = null;
}
if (provider != null) {
setConfigurationProvider(provider);
}
final String markdown = array.getString(R.styleable.MarkwonView_mv_markdown);
if (!TextUtils.isEmpty(markdown)) {
setMarkdown(markdown);
}
} finally {
array.recycle();
}
}
}
@Override
public void setConfigurationProvider(@NonNull ConfigurationProvider provider) {
this.provider = provider;
this.configuration = provider.provide(textView.getContext());
if (!TextUtils.isEmpty(markdown)) {
// invalidate rendered markdown
setMarkdown(markdown);
}
}
@Override
public void setMarkdown(@Nullable String markdown) {
setMarkdown(null, markdown);
}
@Override
public void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown) {
this.markdown = markdown;
if (configuration == null) {
if (this.configuration == null) {
if (provider != null) {
this.configuration = provider.provide(textView.getContext());
} else {
this.configuration = SpannableConfiguration.create(textView.getContext());
}
}
configuration = this.configuration;
}
Markwon.setMarkdown(textView, configuration, markdown);
}
@Nullable
@Override
public String getMarkdown() {
return markdown;
}
@Nullable
public static IMarkwonView.ConfigurationProvider obtainProvider(@NonNull String className) {
try {
final Class<?> cl = Class.forName(className);
return (IMarkwonView.ConfigurationProvider) cl.newInstance();
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MarkwonView">
<attr name="mv_configurationProvider" format="string" />
<attr name="mv_markdown" format="string" />
</declare-styleable>
</resources>

View File

@ -1 +1 @@
include ':app', ':library', ':library-image-loader'
include ':app', ':library', ':library-image-loader', ':library-view'