Sample app readme functionality
This commit is contained in:
parent
860d70d6d1
commit
45d205ba8c
@ -45,19 +45,46 @@ androidExtensions {
|
|||||||
features = ["parcelize"]
|
features = ["parcelize"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
exclude group: 'org.jetbrains', module: 'annotations-java5'
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
kapt project(':sample-utils:processor')
|
kapt project(':sample-utils:processor')
|
||||||
|
deps['annotationProcessor'].with {
|
||||||
|
kapt it['prism4j-bundler']
|
||||||
|
}
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
|
||||||
implementation project(':markwon-core')
|
implementation project(':markwon-core')
|
||||||
|
implementation project(':markwon-editor')
|
||||||
|
implementation project(':markwon-ext-latex')
|
||||||
|
implementation project(':markwon-ext-strikethrough')
|
||||||
|
implementation project(':markwon-ext-tables')
|
||||||
|
implementation project(':markwon-ext-tasklist')
|
||||||
|
implementation project(':markwon-html')
|
||||||
|
implementation project(':markwon-image')
|
||||||
|
implementation project(':markwon-inline-parser')
|
||||||
|
implementation project(':markwon-linkify')
|
||||||
|
implementation project(':markwon-recycler')
|
||||||
|
implementation project(':markwon-recycler-table')
|
||||||
|
implementation project(':markwon-simple-ext')
|
||||||
|
implementation project(':markwon-syntax-highlight')
|
||||||
|
|
||||||
|
implementation project(':markwon-image-picasso')
|
||||||
|
implementation project(':markwon-image-glide')
|
||||||
|
|
||||||
deps.with {
|
deps.with {
|
||||||
implementation it['x-recycler-view']
|
implementation it['x-recycler-view']
|
||||||
implementation it['x-cardview']
|
implementation it['x-cardview']
|
||||||
implementation it['x-fragment']
|
implementation it['x-fragment']
|
||||||
|
implementation it['okhttp']
|
||||||
|
implementation it['prism4j']
|
||||||
implementation it['gson']
|
implementation it['gson']
|
||||||
implementation it['adapt']
|
implementation it['adapt']
|
||||||
implementation it['debug']
|
implementation it['debug']
|
||||||
|
implementation it['android-svg']
|
||||||
|
implementation it['android-gif']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Hey!" />
|
android:text="Hey!" />
|
||||||
|
|
||||||
<io.noties.markwon.app.base.FlowLayout
|
<io.noties.markwon.app.widget.FlowLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="@dimen/content_padding"
|
android:paddingTop="@dimen/content_padding"
|
||||||
@ -86,9 +86,9 @@
|
|||||||
android:background="@drawable/bg_artifact"
|
android:background="@drawable/bg_artifact"
|
||||||
android:text="core" />
|
android:text="core" />
|
||||||
|
|
||||||
</io.noties.markwon.app.base.FlowLayout>
|
</io.noties.markwon.app.widget.FlowLayout>
|
||||||
|
|
||||||
<io.noties.markwon.app.base.FlowLayout
|
<io.noties.markwon.app.widget.FlowLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="@dimen/content_padding"
|
android:paddingTop="@dimen/content_padding"
|
||||||
@ -161,6 +161,6 @@
|
|||||||
android:background="@drawable/bg_tag"
|
android:background="@drawable/bg_tag"
|
||||||
android:text="core" />
|
android:text="core" />
|
||||||
|
|
||||||
</io.noties.markwon.app.base.FlowLayout>
|
</io.noties.markwon.app.widget.FlowLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -3,6 +3,8 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="io.noties.markwon.app">
|
package="io.noties.markwon.app">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -13,12 +15,32 @@
|
|||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
||||||
|
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".sample.MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".readme.ReadMeActivity"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
|
<!-- github markdown files handling -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data
|
||||||
|
android:host="github.com"
|
||||||
|
android:pathPattern=".*\\.md"
|
||||||
|
android:scheme="https" />
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
1
app-sample/src/main/assets/README.md
Symbolic link
1
app-sample/src/main/assets/README.md
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../README.md
|
@ -3,6 +3,8 @@ package io.noties.markwon.app
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import io.noties.debug.AndroidLogDebugOutput
|
import io.noties.debug.AndroidLogDebugOutput
|
||||||
import io.noties.debug.Debug
|
import io.noties.debug.Debug
|
||||||
|
import io.noties.markwon.app.sample.SampleManager
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@ -13,10 +15,12 @@ class App : Application() {
|
|||||||
|
|
||||||
Debug.init(AndroidLogDebugOutput(BuildConfig.DEBUG))
|
Debug.init(AndroidLogDebugOutput(BuildConfig.DEBUG))
|
||||||
|
|
||||||
sampleManager = SampleManager(this, Executors.newCachedThreadPool())
|
executorService = Executors.newCachedThreadPool()
|
||||||
|
sampleManager = SampleManager(this, executorService)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
lateinit var executorService: ExecutorService
|
||||||
lateinit var sampleManager: SampleManager
|
lateinit var sampleManager: SampleManager
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.noties.markwon.app.readme
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.text.TextUtils
|
||||||
|
import io.noties.markwon.image.destination.ImageDestinationProcessor
|
||||||
|
import io.noties.markwon.image.destination.ImageDestinationProcessorRelativeToAbsolute
|
||||||
|
|
||||||
|
class GithubImageDestinationProcessor(
|
||||||
|
username: String = "noties",
|
||||||
|
repository: String = "Markwon",
|
||||||
|
branch: String = "master"
|
||||||
|
) : ImageDestinationProcessor() {
|
||||||
|
|
||||||
|
private val processor = ImageDestinationProcessorRelativeToAbsolute("https://github.com/$username/$repository/raw/$branch/")
|
||||||
|
|
||||||
|
override fun process(destination: String): String {
|
||||||
|
// process only images without scheme information
|
||||||
|
val uri = Uri.parse(destination)
|
||||||
|
return if (TextUtils.isEmpty(uri.scheme)) {
|
||||||
|
processor.process(destination)
|
||||||
|
} else {
|
||||||
|
destination
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
package io.noties.markwon.app.readme
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import io.noties.debug.Debug
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import io.noties.markwon.MarkwonVisitor
|
||||||
|
import io.noties.markwon.app.R
|
||||||
|
import io.noties.markwon.app.utils.ReadMeUtils
|
||||||
|
import io.noties.markwon.app.utils.hidden
|
||||||
|
import io.noties.markwon.app.utils.loadReadMe
|
||||||
|
import io.noties.markwon.app.utils.textOrHide
|
||||||
|
import io.noties.markwon.ext.tasklist.TaskListPlugin
|
||||||
|
import io.noties.markwon.html.HtmlPlugin
|
||||||
|
import io.noties.markwon.image.ImagesPlugin
|
||||||
|
import io.noties.markwon.recycler.MarkwonAdapter
|
||||||
|
import io.noties.markwon.recycler.SimpleEntry
|
||||||
|
import io.noties.markwon.recycler.table.TableEntry
|
||||||
|
import io.noties.markwon.recycler.table.TableEntryPlugin
|
||||||
|
import io.noties.markwon.syntax.Prism4jThemeDefault
|
||||||
|
import io.noties.markwon.syntax.SyntaxHighlightPlugin
|
||||||
|
import io.noties.prism4j.Prism4j
|
||||||
|
import io.noties.prism4j.annotations.PrismBundle
|
||||||
|
import okhttp3.Call
|
||||||
|
import okhttp3.Callback
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.commonmark.ext.gfm.tables.TableBlock
|
||||||
|
import org.commonmark.node.FencedCodeBlock
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
@PrismBundle(includeAll = true)
|
||||||
|
class ReadMeActivity : Activity() {
|
||||||
|
|
||||||
|
private lateinit var progressBar: View
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_read_me)
|
||||||
|
|
||||||
|
progressBar = findViewById(R.id.progress_bar)
|
||||||
|
|
||||||
|
val data = intent.data
|
||||||
|
|
||||||
|
Debug.i(data)
|
||||||
|
|
||||||
|
initAppBar(data)
|
||||||
|
|
||||||
|
initRecyclerView(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val markwon: Markwon
|
||||||
|
get() = Markwon.builder(this)
|
||||||
|
.usePlugin(ImagesPlugin.create())
|
||||||
|
.usePlugin(HtmlPlugin.create())
|
||||||
|
.usePlugin(TableEntryPlugin.create(this))
|
||||||
|
.usePlugin(SyntaxHighlightPlugin.create(Prism4j(GrammarLocatorDef()), Prism4jThemeDefault.create(0)))
|
||||||
|
.usePlugin(TaskListPlugin.create(this))
|
||||||
|
.usePlugin(ReadMeImageDestinationPlugin(intent.data))
|
||||||
|
.usePlugin(object : AbstractMarkwonPlugin() {
|
||||||
|
override fun configureVisitor(builder: MarkwonVisitor.Builder) {
|
||||||
|
builder.on(FencedCodeBlock::class.java) { visitor, block ->
|
||||||
|
// we actually won't be applying code spans here, as our custom view will
|
||||||
|
// draw background and apply mono typeface
|
||||||
|
//
|
||||||
|
// NB the `trim` operation on literal (as code will have a new line at the end)
|
||||||
|
val code = visitor.configuration()
|
||||||
|
.syntaxHighlight()
|
||||||
|
.highlight(block.info, block.literal.trim())
|
||||||
|
visitor.builder().append(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
private fun initAppBar(data: Uri?) {
|
||||||
|
val appBar = findViewById<View>(R.id.app_bar)
|
||||||
|
appBar.findViewById<View>(R.id.app_bar_icon).setOnClickListener { onBackPressed() }
|
||||||
|
|
||||||
|
val (title: String, subtitle: String?) = if (data == null) {
|
||||||
|
Pair("README.md", null)
|
||||||
|
} else {
|
||||||
|
Pair(data.lastPathSegment ?: "", data.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
appBar.findViewById<TextView>(R.id.title).text = title
|
||||||
|
appBar.findViewById<TextView>(R.id.subtitle).textOrHide(subtitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initRecyclerView(data: Uri?) {
|
||||||
|
|
||||||
|
val adapter = MarkwonAdapter.builder(R.layout.adapter_node, R.id.text_view)
|
||||||
|
.include(FencedCodeBlock::class.java, SimpleEntry.create(R.layout.adapter_node_code_block, R.id.text_view))
|
||||||
|
.include(TableBlock::class.java, TableEntry.create {
|
||||||
|
it
|
||||||
|
.tableLayout(R.layout.adapter_node_table_block, R.id.table_layout)
|
||||||
|
.textLayoutIsRoot(R.layout.view_table_entry_cell)
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
|
recyclerView.setHasFixedSize(true)
|
||||||
|
recyclerView.itemAnimator = DefaultItemAnimator()
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
|
||||||
|
load(applicationContext, data) { result ->
|
||||||
|
|
||||||
|
when (result) {
|
||||||
|
is Result.Failure -> Debug.e(result.throwable)
|
||||||
|
is Result.Success -> {
|
||||||
|
val markwon = markwon
|
||||||
|
val node = markwon.parse(result.markdown)
|
||||||
|
if (window != null) {
|
||||||
|
recyclerView.post {
|
||||||
|
adapter.setParsedMarkdown(markwon, node)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
progressBar.hidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class Result {
|
||||||
|
data class Success(val markdown: String) : Result()
|
||||||
|
data class Failure(val throwable: Throwable) : Result()
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
fun load(context: Context, data: Uri?, callback: (Result) -> Unit) = try {
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
callback.invoke(Result.Success(loadReadMe(context)))
|
||||||
|
} else {
|
||||||
|
val request = Request.Builder()
|
||||||
|
.get()
|
||||||
|
.url(ReadMeUtils.buildRawGithubUrl(data))
|
||||||
|
.build()
|
||||||
|
OkHttpClient().newCall(request).enqueue(object : Callback {
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
callback.invoke(Result.Failure(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
val md = response.body()?.string() ?: ""
|
||||||
|
callback.invoke(Result.Success(md))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
callback.invoke(Result.Failure(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package io.noties.markwon.app.readme
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin
|
||||||
|
import io.noties.markwon.MarkwonConfiguration
|
||||||
|
import io.noties.markwon.app.utils.ReadMeUtils
|
||||||
|
|
||||||
|
class ReadMeImageDestinationPlugin(private val data: Uri?) : AbstractMarkwonPlugin() {
|
||||||
|
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
|
||||||
|
val info = ReadMeUtils.parseInfo(data)
|
||||||
|
if (info == null) {
|
||||||
|
builder.imageDestinationProcessor(GithubImageDestinationProcessor())
|
||||||
|
} else {
|
||||||
|
builder.imageDestinationProcessor(GithubImageDestinationProcessor(
|
||||||
|
username = info.username,
|
||||||
|
repository = info.repository,
|
||||||
|
branch = info.branch
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package io.noties.markwon.app
|
package io.noties.markwon.app.sample
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import io.noties.markwon.app.ui.SampleListFragment
|
import io.noties.markwon.app.sample.ui.SampleListFragment
|
||||||
|
|
||||||
class MainActivity : FragmentActivity() {
|
class MainActivity : FragmentActivity() {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app
|
package io.noties.markwon.app.sample
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.adapt
|
package io.noties.markwon.app.sample
|
||||||
|
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -8,8 +8,7 @@ import android.widget.TextView
|
|||||||
import io.noties.adapt.Item
|
import io.noties.adapt.Item
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import io.noties.markwon.app.R
|
import io.noties.markwon.app.R
|
||||||
import io.noties.markwon.app.Sample
|
import io.noties.markwon.app.widget.FlowLayout
|
||||||
import io.noties.markwon.app.base.FlowLayout
|
|
||||||
import io.noties.markwon.app.utils.displayName
|
import io.noties.markwon.app.utils.displayName
|
||||||
import io.noties.markwon.app.utils.hidden
|
import io.noties.markwon.app.utils.hidden
|
||||||
import io.noties.markwon.app.utils.tagDisplayName
|
import io.noties.markwon.app.utils.tagDisplayName
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app
|
package io.noties.markwon.app.sample
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import io.noties.markwon.app.utils.Cancellable
|
import io.noties.markwon.app.utils.Cancellable
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app
|
package io.noties.markwon.app.sample
|
||||||
|
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.ui
|
package io.noties.markwon.app.sample.ui
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.ui
|
package io.noties.markwon.app.sample.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
@ -0,0 +1,74 @@
|
|||||||
|
package io.noties.markwon.app.sample.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import io.noties.markwon.app.App
|
||||||
|
import io.noties.markwon.app.R
|
||||||
|
import io.noties.markwon.app.sample.Sample
|
||||||
|
import io.noties.markwon.app.utils.hidden
|
||||||
|
import io.noties.markwon.app.utils.readCode
|
||||||
|
import io.noties.markwon.syntax.Prism4jSyntaxHighlight
|
||||||
|
import io.noties.markwon.syntax.Prism4jThemeDefault
|
||||||
|
import io.noties.prism4j.Prism4j
|
||||||
|
import io.noties.prism4j.annotations.PrismBundle
|
||||||
|
|
||||||
|
@PrismBundle(include = ["java", "kotlin"], grammarLocatorClassName = ".GrammarLocatorSourceCode")
|
||||||
|
class SampleCodeFragment : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var progressBar: View
|
||||||
|
private lateinit var textView: TextView
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_sample_code, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
progressBar = view.findViewById(R.id.progress_bar)
|
||||||
|
textView = view.findViewById(R.id.text_view)
|
||||||
|
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun load() {
|
||||||
|
App.executorService.submit {
|
||||||
|
val code = sample.readCode(requireContext())
|
||||||
|
val prism = Prism4j(GrammarLocatorSourceCode())
|
||||||
|
val highlight = Prism4jSyntaxHighlight.create(prism, Prism4jThemeDefault.create(0))
|
||||||
|
val language = when (code.language) {
|
||||||
|
Sample.Language.KOTLIN -> "kotlin"
|
||||||
|
Sample.Language.JAVA -> "java"
|
||||||
|
}
|
||||||
|
val text = highlight.highlight(language, code.sourceCode)
|
||||||
|
|
||||||
|
textView.post {
|
||||||
|
//attached
|
||||||
|
if (context != null) {
|
||||||
|
progressBar.hidden = true
|
||||||
|
textView.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val sample: Sample by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
|
arguments!!.getParcelable<Sample>(ARG_SAMPLE)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val ARG_SAMPLE = "arg.Sample"
|
||||||
|
|
||||||
|
fun init(sample: Sample): SampleCodeFragment {
|
||||||
|
return SampleCodeFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putParcelable(ARG_SAMPLE, sample)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.ui
|
package io.noties.markwon.app.sample.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -8,7 +8,7 @@ import android.widget.TextView
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentTransaction
|
import androidx.fragment.app.FragmentTransaction
|
||||||
import io.noties.markwon.app.R
|
import io.noties.markwon.app.R
|
||||||
import io.noties.markwon.app.Sample
|
import io.noties.markwon.app.sample.Sample
|
||||||
import io.noties.markwon.app.utils.active
|
import io.noties.markwon.app.utils.active
|
||||||
|
|
||||||
class SampleFragment : Fragment() {
|
class SampleFragment : Fragment() {
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.ui
|
package io.noties.markwon.app.sample.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -19,11 +19,11 @@ import io.noties.debug.Debug
|
|||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import io.noties.markwon.app.App
|
import io.noties.markwon.app.App
|
||||||
import io.noties.markwon.app.R
|
import io.noties.markwon.app.R
|
||||||
import io.noties.markwon.app.Sample
|
import io.noties.markwon.app.sample.Sample
|
||||||
import io.noties.markwon.app.SampleManager
|
import io.noties.markwon.app.sample.SampleManager
|
||||||
import io.noties.markwon.app.SampleSearch
|
import io.noties.markwon.app.sample.SampleSearch
|
||||||
import io.noties.markwon.app.adapt.SampleItem
|
import io.noties.markwon.app.sample.SampleItem
|
||||||
import io.noties.markwon.app.base.SearchBar
|
import io.noties.markwon.app.widget.SearchBar
|
||||||
import io.noties.markwon.app.utils.Cancellable
|
import io.noties.markwon.app.utils.Cancellable
|
||||||
import io.noties.markwon.app.utils.displayName
|
import io.noties.markwon.app.utils.displayName
|
||||||
import io.noties.markwon.app.utils.onPreDraw
|
import io.noties.markwon.app.utils.onPreDraw
|
@ -1,11 +1,11 @@
|
|||||||
package io.noties.markwon.app.ui
|
package io.noties.markwon.app.sample.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import io.noties.markwon.app.Sample
|
import io.noties.markwon.app.sample.Sample
|
||||||
|
|
||||||
class SamplePreviewFragment : Fragment() {
|
class SamplePreviewFragment : Fragment() {
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package io.noties.markwon.app.samples
|
package io.noties.markwon.app.samples
|
||||||
|
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import io.noties.markwon.app.ui.MarkwonTextViewSample
|
import io.noties.markwon.app.sample.ui.MarkwonTextViewSample
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.noties.markwon.app.samples.nested
|
package io.noties.markwon.app.samples.nested
|
||||||
|
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import io.noties.markwon.app.ui.MarkwonTextViewSample
|
import io.noties.markwon.app.sample.ui.MarkwonTextViewSample
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.noties.markwon.app.samples.nested;
|
package io.noties.markwon.app.samples.nested;
|
||||||
|
|
||||||
import io.noties.markwon.Markwon;
|
import io.noties.markwon.Markwon;
|
||||||
import io.noties.markwon.app.ui.MarkwonTextViewSample;
|
import io.noties.markwon.app.sample.ui.MarkwonTextViewSample;
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
||||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo;
|
import io.noties.markwon.sample.annotations.MarkwonSampleInfo;
|
||||||
|
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
package io.noties.markwon.app.ui
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import io.noties.markwon.app.R
|
|
||||||
import io.noties.markwon.app.Sample
|
|
||||||
import io.noties.markwon.app.utils.readCode
|
|
||||||
|
|
||||||
class SampleCodeFragment : Fragment() {
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
|
||||||
return inflater.inflate(R.layout.fragment_sample_code, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
val textView: TextView = view.findViewById(R.id.text_view)
|
|
||||||
val code = sample.readCode(requireContext())
|
|
||||||
|
|
||||||
textView.text = code.sourceCode
|
|
||||||
}
|
|
||||||
|
|
||||||
private val sample: Sample by lazy(LazyThreadSafetyMode.NONE) {
|
|
||||||
arguments!!.getParcelable<Sample>(ARG_SAMPLE)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val ARG_SAMPLE = "arg.Sample"
|
|
||||||
|
|
||||||
fun init(sample: Sample): SampleCodeFragment {
|
|
||||||
return SampleCodeFragment().apply {
|
|
||||||
arguments = Bundle().apply {
|
|
||||||
putParcelable(ARG_SAMPLE, sample)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,21 @@
|
|||||||
|
package io.noties.markwon.app.utils
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.util.Scanner
|
||||||
|
|
||||||
|
fun InputStream.readStringAndClose(): String {
|
||||||
|
try {
|
||||||
|
val scanner = Scanner(this).useDelimiter("\\A")
|
||||||
|
if (scanner.hasNext()) {
|
||||||
|
return scanner.next()
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
close()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package io.noties.markwon.app.utils
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
object ReadMeUtils {
|
||||||
|
// username, repo, branch, lastPathSegment
|
||||||
|
private val RE = Pattern.compile("^https:\\/\\/github\\.com\\/(\\w+?)\\/(\\w+?)\\/(?:blob|raw)\\/(\\w+?)\\/(.+)")
|
||||||
|
|
||||||
|
data class GithubInfo(
|
||||||
|
val username: String,
|
||||||
|
val repository: String,
|
||||||
|
val branch: String,
|
||||||
|
val fileName: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun parseInfo(data: Uri?): GithubInfo? {
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val matcher = RE.matcher(data.toString())
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return GithubInfo(
|
||||||
|
username = matcher.group(1),
|
||||||
|
repository = matcher.group(2),
|
||||||
|
branch = matcher.group(3),
|
||||||
|
fileName = matcher.group(4)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildRawGithubUrl(data: Uri): String {
|
||||||
|
val info = parseInfo(data)
|
||||||
|
return if (info == null) {
|
||||||
|
data.toString()
|
||||||
|
} else {
|
||||||
|
"https://github.com/${info.username}/${info.repository}/raw/${info.branch}/${info.fileName}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.noties.markwon.app.Sample;
|
import io.noties.markwon.app.sample.Sample;
|
||||||
|
|
||||||
public abstract class SampleUtils {
|
public abstract class SampleUtils {
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package io.noties.markwon.app.utils
|
package io.noties.markwon.app.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import io.noties.markwon.app.Sample
|
import io.noties.markwon.app.sample.Sample
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.Scanner
|
|
||||||
|
|
||||||
val MarkwonArtifact.displayName: String
|
val MarkwonArtifact.displayName: String
|
||||||
get() = "@${artifactName()}"
|
get() = "@${artifactName()}"
|
||||||
@ -22,11 +21,6 @@ fun Sample.readCode(context: Context): Sample.Code {
|
|||||||
.removePrefix(SAMPLE_PREFIX)
|
.removePrefix(SAMPLE_PREFIX)
|
||||||
.replace('.', '/')
|
.replace('.', '/')
|
||||||
|
|
||||||
// now, we have 2 possibilities -> Kotlin or Java
|
|
||||||
fun read(stream: InputStream): String {
|
|
||||||
return Scanner(stream).useDelimiter("\\A").next()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun obtain(path: String): InputStream? {
|
fun obtain(path: String): InputStream? {
|
||||||
return try {
|
return try {
|
||||||
assets.open(path)
|
assets.open(path)
|
||||||
@ -35,6 +29,7 @@ fun Sample.readCode(context: Context): Sample.Code {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now, we have 2 possibilities -> Kotlin or Java
|
||||||
var language: Sample.Language = Sample.Language.KOTLIN
|
var language: Sample.Language = Sample.Language.KOTLIN
|
||||||
var stream = obtain("$path.kt")
|
var stream = obtain("$path.kt")
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
@ -46,13 +41,12 @@ fun Sample.readCode(context: Context): Sample.Code {
|
|||||||
throw IllegalStateException("Cannot obtain sample file at path: $path")
|
throw IllegalStateException("Cannot obtain sample file at path: $path")
|
||||||
}
|
}
|
||||||
|
|
||||||
val code = read(stream)
|
val code = stream.readStringAndClose()
|
||||||
|
|
||||||
try {
|
|
||||||
stream.close()
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
return Sample.Code(language, code)
|
return Sample.Code(language, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loadReadMe(context: Context): String {
|
||||||
|
val stream = context.assets.open("README.md")
|
||||||
|
return stream.readStringAndClose()
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package io.noties.markwon.app.utils
|
||||||
|
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.widget.TextView
|
||||||
|
|
||||||
|
fun TextView.textOrHide(text: CharSequence?) {
|
||||||
|
this.text = text
|
||||||
|
this.hidden = TextUtils.isEmpty(text)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.base
|
package io.noties.markwon.app.widget
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.base
|
package io.noties.markwon.app.widget
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
@ -1,4 +1,4 @@
|
|||||||
package io.noties.markwon.app.base
|
package io.noties.markwon.app.widget
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
70
app-sample/src/main/res/layout/activity_read_me.xml
Normal file
70
app-sample/src/main/res/layout/activity_read_me.xml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
style="@style/AppBarContainer"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
style="@style/AppBarIcon"
|
||||||
|
android:src="@drawable/ic_arrow_back_white_24dp"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="README.md" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subtitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
tools:text="https://blah.blah/README.md" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.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:paddingTop="@dimen/content_padding"
|
||||||
|
android:paddingBottom="36dip" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
android:layout_width="@dimen/progress_bar_side"
|
||||||
|
android:layout_height="@dimen/progress_bar_side"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -54,7 +54,7 @@
|
|||||||
android:textAppearance="?android:attr/textAppearance"
|
android:textAppearance="?android:attr/textAppearance"
|
||||||
tools:text="Description goes here" />
|
tools:text="Description goes here" />
|
||||||
|
|
||||||
<io.noties.markwon.app.base.FlowLayout
|
<io.noties.markwon.app.widget.FlowLayout
|
||||||
android:id="@+id/artifacts"
|
android:id="@+id/artifacts"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -66,9 +66,9 @@
|
|||||||
<!-- we are actually fine with pre-inflating a single view -->
|
<!-- we are actually fine with pre-inflating a single view -->
|
||||||
<include layout="@layout/view_artifact" />
|
<include layout="@layout/view_artifact" />
|
||||||
|
|
||||||
</io.noties.markwon.app.base.FlowLayout>
|
</io.noties.markwon.app.widget.FlowLayout>
|
||||||
|
|
||||||
<io.noties.markwon.app.base.FlowLayout
|
<io.noties.markwon.app.widget.FlowLayout
|
||||||
android:id="@+id/tags"
|
android:id="@+id/tags"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
<include layout="@layout/view_tag" />
|
<include layout="@layout/view_tag" />
|
||||||
|
|
||||||
</io.noties.markwon.app.base.FlowLayout>
|
</io.noties.markwon.app.widget.FlowLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
17
app-sample/src/main/res/layout/adapter_node.xml
Normal file
17
app-sample/src/main/res/layout/adapter_node.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?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_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dip"
|
||||||
|
android:layout_marginRight="16dip"
|
||||||
|
android:breakStrategy="simple"
|
||||||
|
android:hyphenationFrequency="none"
|
||||||
|
android:lineSpacingExtra="2dip"
|
||||||
|
android:paddingTop="8dip"
|
||||||
|
android:paddingBottom="8dip"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textColor="#000"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="Hello" />
|
26
app-sample/src/main/res/layout/adapter_node_code_block.xml
Normal file
26
app-sample/src/main/res/layout/adapter_node_code_block.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:paddingLeft="16dip"
|
||||||
|
android:paddingRight="16dip"
|
||||||
|
android:scrollbarStyle="outsideInset">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#0f000000"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:lineSpacingExtra="2dip"
|
||||||
|
android:paddingLeft="16dip"
|
||||||
|
android:paddingTop="8dip"
|
||||||
|
android:paddingRight="16dip"
|
||||||
|
android:paddingBottom="8dip"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
19
app-sample/src/main/res/layout/adapter_node_table_block.xml
Normal file
19
app-sample/src/main/res/layout/adapter_node_table_block.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingLeft="16dip"
|
||||||
|
android:paddingTop="8dip"
|
||||||
|
android:paddingRight="16dip"
|
||||||
|
android:paddingBottom="8dip"
|
||||||
|
android:scrollbarStyle="outsideInset">
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:id="@+id/table_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:stretchColumns="*" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
@ -1,9 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -20,9 +24,18 @@
|
|||||||
android:fontFamily="monospace"
|
android:fontFamily="monospace"
|
||||||
android:lineSpacingExtra="2dip"
|
android:lineSpacingExtra="2dip"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:text="package io.noties.markwon" />
|
tools:text="package io.noties.markwon" />
|
||||||
|
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
android:layout_width="@dimen/progress_bar_side"
|
||||||
|
android:layout_height="@dimen/progress_bar_side"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -42,7 +42,7 @@
|
|||||||
android:paddingBottom="36dip"
|
android:paddingBottom="36dip"
|
||||||
tools:layout_marginTop="56dip" />
|
tools:layout_marginTop="56dip" />
|
||||||
|
|
||||||
<io.noties.markwon.app.base.SearchBar
|
<io.noties.markwon.app.widget.SearchBar
|
||||||
android:id="@+id/search_bar"
|
android:id="@+id/search_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<io.noties.markwon.app.base.TextField
|
<io.noties.markwon.app.widget.TextField
|
||||||
android:id="@+id/text_field"
|
android:id="@+id/text_field"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
9
app-sample/src/main/res/layout/view_table_entry_cell.xml
Normal file
9
app-sample/src/main/res/layout/view_table_entry_cell.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?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:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textColor="#000"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="Table content" />
|
@ -11,4 +11,7 @@
|
|||||||
|
|
||||||
<dimen name="divider_height">1dip</dimen>
|
<dimen name="divider_height">1dip</dimen>
|
||||||
<dimen name="tab_bar_height">56dip</dimen>
|
<dimen name="tab_bar_height">56dip</dimen>
|
||||||
|
|
||||||
|
<dimen name="progress_bar_side">64dip</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -4,4 +4,5 @@
|
|||||||
|
|
||||||
<string name="tab_bar_preview">Preview</string>
|
<string name="tab_bar_preview">Preview</string>
|
||||||
<string name="tab_bar_code">Code</string>
|
<string name="tab_bar_code">Code</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -60,6 +60,7 @@ dependencies {
|
|||||||
implementation it['debug']
|
implementation it['debug']
|
||||||
implementation it['adapt']
|
implementation it['adapt']
|
||||||
implementation it['android-svg']
|
implementation it['android-svg']
|
||||||
|
implementation it['android-gif']
|
||||||
}
|
}
|
||||||
|
|
||||||
deps['annotationProcessor'].with {
|
deps['annotationProcessor'].with {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user