Skip to content

Commit 2d30d18

Browse files
committed
Changed base view
* Add click listener for link
1 parent c8eb940 commit 2d30d18

File tree

16 files changed

+163
-57
lines changed

16 files changed

+163
-57
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Add the dependency:
5454

5555
```groovy
5656
dependencies {
57-
implementation 'com.github.imcloudfloating:markdown-it-android:1.0.3'
57+
implementation 'com.github.imcloudfloating:markdown-it-android:1.0.4'
5858
}
5959
```
6060

@@ -69,7 +69,6 @@ Data Binding:
6969
android:id="@+id/markdown_view"
7070
android:layout_width="match_parent"
7171
android:layout_height="match_parent"
72-
app:fitSystemTheme="true"
7372
app:markdownString="@{viewModel.content}" />
7473
```
7574

@@ -85,8 +84,9 @@ findViewById<MarkdownIt>(R.id.markdown_view).markdownString = md
8584
8685
### Fields and methods
8786

88-
| Field/Method | Note |
89-
| ---------------- | ------------------------------------------------------------ |
90-
| `fitSystemTheme` | Default is `true`, auto fit system theme. |
91-
| `markdownString` | The markdown content you want to show. |
92-
| `setDarkTheme()` | Forced to use dark theme, this function will set `fitSystemTheme` to `false`. |
87+
| Field/Method | Note |
88+
| ------------------ | ------------------------------------------------------------ |
89+
| `fitSystemTheme` | Default is `true`, auto fit system theme. |
90+
| `darkTheme` | Use dark theme when `fitSystemTheme = false` |
91+
| `markdownString` | The markdown content you want to show. |
92+
| `urlClickListener` | Click listener for link. |

app/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ android {
4141

4242
dependencies {
4343
implementation project(":markdown-it")
44-
implementation 'androidx.core:core-ktx:1.3.2'
45-
implementation 'androidx.appcompat:appcompat:1.2.0'
44+
implementation 'androidx.core:core-ktx:1.5.0'
45+
implementation 'androidx.appcompat:appcompat:1.3.0'
4646
implementation 'com.google.android.material:material:1.3.0'
4747
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
4848
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
49-
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
50-
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0'
49+
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
50+
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
5151
testImplementation 'junit:junit:4.13.2'
5252
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
5353
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

app/src/main/java/com/github/imcloudfloating/markdown/demo/DemoViewModel.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
package com.github.imcloudfloating.markdown.demo
22

33
import android.app.Application
4+
import androidx.core.content.res.ResourcesCompat
5+
import androidx.databinding.ObservableBoolean
46
import androidx.databinding.ObservableField
57
import androidx.lifecycle.AndroidViewModel
68
import java.io.BufferedReader
79
import java.io.InputStreamReader
810
import java.util.stream.Collectors
911

1012
class DemoViewModel(application: Application) : AndroidViewModel(application) {
13+
private val lightIcon =
14+
ResourcesCompat.getDrawable(application.resources, R.drawable.ic_light, null)
15+
private val nightIcon =
16+
ResourcesCompat.getDrawable(application.resources, R.drawable.ic_night, null)
17+
18+
var fitSystemTheme = ObservableBoolean(false)
19+
var darkTheme = ObservableBoolean(false)
20+
var theme = ObservableField(nightIcon)
1121
var content = ObservableField<String>()
1222

1323
init {
@@ -19,4 +29,9 @@ class DemoViewModel(application: Application) : AndroidViewModel(application) {
1929
).lines().collect(Collectors.joining("\n"))
2030
)
2131
}
32+
33+
fun toggleTheme() {
34+
darkTheme.set(!darkTheme.get())
35+
if (darkTheme.get()) theme.set(lightIcon) else theme.set(nightIcon)
36+
}
2237
}

app/src/main/res/drawable/ic_launcher_foreground.xml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
android:height="108dp"
44
android:viewportWidth="108"
55
android:viewportHeight="108">
6-
<group android:scaleX="0.081"
7-
android:scaleY="0.081"
8-
android:translateX="28.08"
9-
android:translateY="33.264">
10-
<path
11-
android:fillColor="@color/primaryVariant"
12-
android:pathData="M593.8,59.1L46.2,59.1C20.7,59.1 0,79.8 0,105.2v301.5c0,25.5 20.7,46.2 46.2,46.2h547.7c25.5,0 46.2,-20.7 46.1,-46.1L640,105.2c0,-25.4 -20.7,-46.1 -46.2,-46.1zM338.5,360.6L277,360.6v-120l-61.5,76.9 -61.5,-76.9v120L92.3,360.6L92.3,151.4h61.5l61.5,76.9 61.5,-76.9h61.5v209.2zM473.8,363.7L381.5,256L443,256L443,151.4h61.5L504.5,256L566,256z" />
13-
</group>
6+
<group
7+
android:scaleX="0.081"
8+
android:scaleY="0.081"
9+
android:translateX="28.08"
10+
android:translateY="33.264">
11+
<path
12+
android:fillColor="@color/primaryVariant"
13+
android:pathData="M593.8,59.1L46.2,59.1C20.7,59.1 0,79.8 0,105.2v301.5c0,25.5 20.7,46.2 46.2,46.2h547.7c25.5,0 46.2,-20.7 46.1,-46.1L640,105.2c0,-25.4 -20.7,-46.1 -46.2,-46.1zM338.5,360.6L277,360.6v-120l-61.5,76.9 -61.5,-76.9v120L92.3,360.6L92.3,151.4h61.5l61.5,76.9 61.5,-76.9h61.5v209.2zM473.8,363.7L381.5,256L443,256L443,151.4h61.5L504.5,256L566,256z" />
14+
</group>
1415
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:tint="#F0F0F0"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M20,15.31L23.31,12 20,8.69V4h-4.69L12,0.69 8.69,4H4v4.69L0.69,12 4,15.31V20h4.69L12,23.31 15.31,20H20v-4.69zM12,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6z" />
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:tint="#333333"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M20,8.69V4h-4.69L12,0.69 8.69,4H4v4.69L0.69,12 4,15.31V20h4.69L12,23.31 15.31,20H20v-4.69L23.31,12 20,8.69zM12,18c-0.89,0 -1.74,-0.2 -2.5,-0.55C11.56,16.5 13,14.42 13,12s-1.44,-4.5 -3.5,-5.45C10.26,6.2 11.11,6 12,6c3.31,0 6,2.69 6,6s-2.69,6 -6,6z" />
10+
</vector>

app/src/main/res/layout/activity_main.xml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,31 @@
1111
type="com.github.imcloudfloating.markdown.demo.DemoViewModel" />
1212
</data>
1313

14-
<com.github.imcloudfloating.markdown.MarkdownIt
15-
android:id="@+id/markdown_view"
14+
<androidx.constraintlayout.widget.ConstraintLayout
1615
android:layout_width="match_parent"
17-
android:layout_height="match_parent"
18-
app:markdownString="@{vm.content}" />
16+
android:layout_height="match_parent">
17+
18+
<com.github.imcloudfloating.markdown.MarkdownIt
19+
android:id="@+id/markdown_view"
20+
android:layout_width="match_parent"
21+
android:layout_height="match_parent"
22+
app:darkTheme="@{vm.darkTheme}"
23+
app:fitSystemTheme="@{vm.fitSystemTheme}"
24+
app:markdownString="@{vm.content}">
25+
26+
</com.github.imcloudfloating.markdown.MarkdownIt>
27+
28+
<androidx.appcompat.widget.AppCompatImageButton
29+
android:layout_width="wrap_content"
30+
android:layout_height="wrap_content"
31+
android:layout_margin="16dp"
32+
android:background="@android:color/transparent"
33+
android:onClick="@{() -> vm.toggleTheme()}"
34+
android:src="@{vm.theme}"
35+
android:textColor="@color/white"
36+
app:layout_constraintBottom_toBottomOf="parent"
37+
app:layout_constraintEnd_toEndOf="parent" />
38+
39+
</androidx.constraintlayout.widget.ConstraintLayout>
1940

2041
</layout>

app/src/main/res/values/strings.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
<resources>
22
<string name="app_name">Markdown It Android</string>
3-
<string name="hint_input">Write something</string>
4-
<string name="tab_edit">Edit</string>
5-
<string name="tab_preview">Preview</string>
63
</resources>

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ buildscript {
55
mavenCentral()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:7.0.0-alpha09'
9-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.30"
8+
classpath 'com.android.tools.build:gradle:4.2.1'
9+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
1010

1111
// NOTE: Do not place your application dependencies here; they belong
1212
// in the individual module build.gradle files
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Mon Mar 15 12:11:08 CST 2021
22
distributionBase=GRADLE_USER_HOME
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
44
distributionPath=wrapper/dists
55
zipStorePath=wrapper/dists
66
zipStoreBase=GRADLE_USER_HOME

markdown-it/build.gradle

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ plugins {
55
}
66

77
android {
8-
def lib_version = "1.0.3"
8+
def lib_version = "1.0.4"
99
compileSdkVersion 30
1010
buildToolsVersion "30.0.3"
1111

1212
defaultConfig {
1313
minSdkVersion 22
1414
targetSdkVersion 30
15-
versionCode 1
16-
versionName lib_version
1715

1816
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1917
}
@@ -60,8 +58,8 @@ android {
6058
}
6159

6260
dependencies {
63-
implementation 'androidx.core:core-ktx:1.3.2'
64-
implementation 'androidx.appcompat:appcompat:1.2.0'
61+
implementation 'androidx.core:core-ktx:1.5.0'
62+
implementation 'androidx.appcompat:appcompat:1.3.0'
6563
implementation 'com.google.android.material:material:1.3.0'
6664
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
6765
implementation 'org.apache.commons:commons-text:1.9'

markdown-it/src/main/assets/markdown-it/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
<script>
2323
const darkTheme = window.android.isDarkTheme()
2424
if (darkTheme === true) {
25-
document.body.style.backgroundColor = "#0E1117"
2625
useDarkTheme()
2726
}
2827
</script>

markdown-it/src/main/assets/markdown-it/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ function setContent(content) {
7272
function useDarkTheme() {
7373
const container = document.getElementById("container")
7474
if (!container.classList.contains("dark")) {
75+
document.body.style.backgroundColor = "#0E1117"
7576
container.classList.add("dark")
7677
}
78+
}
79+
80+
function useLightTheme() {
81+
const container = document.getElementById("container")
82+
if (container.classList.contains("dark")) {
83+
document.body.style.backgroundColor = "#FFFFFF"
84+
container.classList.remove("dark")
85+
}
7786
}

markdown-it/src/main/java/com/github/imcloudfloating/markdown/MarkdownIt.kt

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,72 @@ package com.github.imcloudfloating.markdown
33
import android.annotation.SuppressLint
44
import android.content.Context
55
import android.content.Intent
6+
import android.net.Uri
67
import android.os.Build
78
import android.util.AttributeSet
89
import android.util.Log
910
import android.webkit.*
11+
import android.widget.FrameLayout
1012
import org.apache.commons.text.StringEscapeUtils
1113

1214
/**
13-
* Markdown-It View
15+
* Markdown View
1416
*
15-
* Based on [WebView]
17+
* Based on [FrameLayout] and [WebView]
1618
*
1719
* @author Cloud Li
1820
*/
1921
@SuppressLint("SetJavaScriptEnabled")
20-
class MarkdownIt(context: Context, attrs: AttributeSet) : WebView(context, attrs) {
22+
class MarkdownIt(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {
2123
companion object {
2224
private const val TAG = "MARKDOWN_IT_ANDROID"
2325
}
2426

27+
private lateinit var webView: WebView
2528
private var loaded = false
29+
2630
var fitSystemTheme = true
2731

32+
/**
33+
* Required [fitSystemTheme] = false
34+
*/
35+
var darkTheme: Boolean = false
36+
set(value) {
37+
field = value
38+
if (field) useDarkTheme() else useLightTheme()
39+
}
2840
var markdownString = String()
2941
set(value) {
3042
field = StringEscapeUtils.escapeEcmaScript(value)
3143
renderContent()
3244
}
3345

46+
var urlClickListener: ((Uri?) -> Any)? = null
47+
48+
/**
49+
* Client for WebView
50+
*/
3451
private val client = object : WebViewClient() {
3552
override fun onPageFinished(view: WebView?, url: String?) {
3653
super.onPageFinished(view, url)
3754
loaded = true
55+
if (darkTheme) useDarkTheme() else useLightTheme()
3856
renderContent()
39-
visibility = VISIBLE
57+
webView.visibility = VISIBLE
4058
}
4159

4260
override fun shouldOverrideUrlLoading(
4361
view: WebView?,
4462
request: WebResourceRequest?
4563
): Boolean {
46-
// Open link in external browser.
47-
val intent = Intent(Intent.ACTION_VIEW, request?.url)
48-
context.startActivity(intent)
64+
if (urlClickListener == null) {
65+
// Open link in external browser.
66+
val intent = Intent(Intent.ACTION_VIEW, request?.url)
67+
context.startActivity(intent)
68+
} else {
69+
urlClickListener?.invoke(request?.url)
70+
}
71+
4972
return true
5073
}
5174

@@ -63,26 +86,37 @@ class MarkdownIt(context: Context, attrs: AttributeSet) : WebView(context, attrs
6386

6487
init {
6588
if (!isInEditMode) {
66-
visibility = INVISIBLE
67-
loadUrl("file:///android_asset/markdown-it/index.html")
68-
addJavascriptInterface(WebAppInterface(context, fitSystemTheme), "android")
69-
settings.run {
89+
inflate(context, R.layout.layout_markdown, this)
90+
getAttrs(attrs)
91+
webView = findViewById(R.id.web_view)
92+
webView.visibility = INVISIBLE
93+
webView.loadUrl("file:///android_asset/markdown-it/index.html")
94+
webView.addJavascriptInterface(WebAppInterface(context, fitSystemTheme), "android")
95+
webView.settings.run {
7096
javaScriptEnabled = true
7197
blockNetworkImage = false
7298
mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
7399
}
74-
webViewClient = client
100+
webView.webViewClient = client
75101
}
76102
}
77103

78-
/**
79-
* Forced to use dark theme
80-
*
81-
* This function will set [fitSystemTheme] to false
82-
*/
83-
fun setDarkTheme() {
84-
fitSystemTheme = false
85-
execJavascript("javascript:useDarkTheme()")
104+
private fun getAttrs(attrs: AttributeSet) {
105+
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MarkdownIt)
106+
fitSystemTheme = typedArray.getBoolean(R.styleable.MarkdownIt_fitSystemTheme, true)
107+
darkTheme = typedArray.getBoolean(R.styleable.MarkdownIt_darkTheme, false)
108+
markdownString = typedArray.getString(R.styleable.MarkdownIt_markdownString).toString()
109+
typedArray.recycle()
110+
}
111+
112+
private fun useDarkTheme() {
113+
if (!fitSystemTheme)
114+
execJavascript("javascript:useDarkTheme()")
115+
}
116+
117+
private fun useLightTheme() {
118+
if (!fitSystemTheme)
119+
execJavascript("javascript:useLightTheme()")
86120
}
87121

88122
/**
@@ -94,7 +128,7 @@ class MarkdownIt(context: Context, attrs: AttributeSet) : WebView(context, attrs
94128

95129
private fun execJavascript(script: String) {
96130
if (loaded) {
97-
evaluateJavascript(script, null)
131+
webView.evaluateJavascript(script, null)
98132
Log.d(TAG, "Render")
99133
}
100134
}

0 commit comments

Comments
 (0)