sample app (WIP)
This commit is contained in:
parent
2076b83675
commit
7e8ed3ea0b
@ -43,6 +43,11 @@ kapt {
|
||||
dependencies {
|
||||
kapt project(':sample-utils:processor')
|
||||
|
||||
implementation 'io.noties:debug:5.1.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
deps.with {
|
||||
api it['x-recycler-view']
|
||||
api it['adapt']
|
||||
api it['debug']
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,14 @@
|
||||
[]
|
||||
[
|
||||
{
|
||||
"javaClassName": "io.noties.markwon.app.samples.FirstSample",
|
||||
"id": "202006164150023",
|
||||
"title": "First Sample",
|
||||
"description": "This **is** _the first_ sample",
|
||||
"artifacts": [
|
||||
"CORE"
|
||||
],
|
||||
"tags": [
|
||||
"test"
|
||||
]
|
||||
}
|
||||
]
|
@ -2,13 +2,60 @@ package io.noties.markwon.app
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.noties.adapt.Adapt
|
||||
import io.noties.debug.Debug
|
||||
import io.noties.markwon.app.adapt.SampleItem
|
||||
import io.noties.markwon.app.base.SearchBar
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
|
||||
class MainActivity : Activity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
/**/
|
||||
val searchBar: SearchBar = findViewById(R.id.search_bar)
|
||||
searchBar.onSearchListener = {
|
||||
Debug.i("search: '$it'")
|
||||
}
|
||||
|
||||
val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
|
||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
recyclerView.itemAnimator = DefaultItemAnimator()
|
||||
recyclerView.setHasFixedSize(true)
|
||||
recyclerView.clipToPadding = false
|
||||
|
||||
searchBar.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
|
||||
override fun onPreDraw(): Boolean {
|
||||
searchBar.viewTreeObserver.removeOnPreDrawListener(this)
|
||||
recyclerView.setPadding(
|
||||
recyclerView.paddingLeft,
|
||||
recyclerView.paddingTop + searchBar.height,
|
||||
recyclerView.paddingRight,
|
||||
recyclerView.paddingBottom
|
||||
)
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
val adapt = Adapt.create()
|
||||
recyclerView.adapter = adapt
|
||||
|
||||
val list = listOf(
|
||||
MarkwonSampleItem(
|
||||
"first",
|
||||
"1",
|
||||
"Title first",
|
||||
"Description her egoes and goes ang goes, so will it ever stop?",
|
||||
listOf(MarkwonArtifact.CORE, MarkwonArtifact.EDITOR),
|
||||
listOf("first", "second")
|
||||
)
|
||||
)
|
||||
|
||||
adapt.setItems(list.map { SampleItem(it) })
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package io.noties.markwon.app
|
||||
|
||||
abstract class MarkwonSample {
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package io.noties.markwon.app
|
||||
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
|
||||
data class MarkwonSampleItem(
|
||||
val javaClassName: String,
|
||||
val id: String,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val artifacts: List<MarkwonArtifact>,
|
||||
val tags: List<String>
|
||||
)
|
@ -0,0 +1,22 @@
|
||||
package io.noties.markwon.app.adapt
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import io.noties.adapt.Item
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
|
||||
class ArtifactItem(artifact: MarkwonArtifact): Item<ArtifactItem.Holder>(artifact.name.hashCode().toLong()) {
|
||||
|
||||
override fun createHolder(inflater: LayoutInflater, parent: ViewGroup): Holder {
|
||||
return Holder(inflater.inflate(0, parent, false))
|
||||
}
|
||||
|
||||
override fun render(holder: Holder) {
|
||||
}
|
||||
|
||||
class Holder(itemView: View): Item.Holder(itemView) {
|
||||
val textView: TextView = requireView(0)
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package io.noties.markwon.app.adapt
|
||||
|
||||
import android.graphics.Color
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.TextPaint
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import io.noties.adapt.Item
|
||||
import io.noties.debug.Debug
|
||||
import io.noties.markwon.app.MarkwonSampleItem
|
||||
import io.noties.markwon.app.R
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
|
||||
class SampleItem(private val item: MarkwonSampleItem) : Item<SampleItem.Holder>(item.id.hashCode().toLong()) {
|
||||
|
||||
var search: String? = null
|
||||
|
||||
override fun createHolder(inflater: LayoutInflater, parent: ViewGroup): Holder {
|
||||
val holder = Holder(inflater.inflate(R.layout.adapt_sample, parent, false))
|
||||
holder.artifactsAndTags.movementMethod = LinkMovementMethod.getInstance()
|
||||
return holder
|
||||
}
|
||||
|
||||
override fun render(holder: Holder) {
|
||||
holder.apply {
|
||||
title.text = item.title
|
||||
description.text = item.description
|
||||
artifactsAndTags.text = buildArtifactsAndTags
|
||||
}
|
||||
}
|
||||
|
||||
private val buildArtifactsAndTags: CharSequence
|
||||
get() {
|
||||
val builder = SpannableStringBuilder()
|
||||
|
||||
item.artifacts
|
||||
.forEach {
|
||||
val length = builder.length
|
||||
builder.append("\u00a0${it.name}\u00a0")
|
||||
builder.setSpan(ArtifactSpan(it), length, builder.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
if (!builder.isEmpty()) {
|
||||
builder.append("\n")
|
||||
}
|
||||
|
||||
item.tags
|
||||
.forEach {
|
||||
val length = builder.length
|
||||
builder.append("\u00a0$it\u00a0")
|
||||
builder.setSpan(TagSpan(it), length, builder.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
class Holder(itemView: View) : Item.Holder(itemView) {
|
||||
val title: TextView = requireView(R.id.title)
|
||||
val description: TextView = requireView(R.id.description)
|
||||
val artifactsAndTags: TextView = requireView(R.id.artifacts_and_tags)
|
||||
}
|
||||
|
||||
private class ArtifactSpan(val artifact: MarkwonArtifact) : ClickableSpan() {
|
||||
override fun onClick(widget: View) {
|
||||
Debug.i("clicked artifact: $artifact")
|
||||
}
|
||||
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
ds.isUnderlineText = false
|
||||
ds.bgColor = Color.GREEN
|
||||
}
|
||||
}
|
||||
|
||||
private class TagSpan(val tag: String) : ClickableSpan() {
|
||||
override fun onClick(widget: View) {
|
||||
Debug.i("clicked tag: $tag")
|
||||
}
|
||||
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
ds.isUnderlineText = false
|
||||
ds.bgColor = Color.BLUE
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package io.noties.markwon.app.base
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
|
||||
class FlowLayout(context: Context, attrs: AttributeSet) : ViewGroup(context, attrs) {
|
||||
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||
for (i in 0 until childCount) {
|
||||
val child = getChildAt(i)
|
||||
val params = child.layoutParams as LayoutParams
|
||||
val left = paddingLeft + params.x
|
||||
val top = paddingTop + params.y
|
||||
child.layout(
|
||||
left,
|
||||
top,
|
||||
left + child.measuredWidth,
|
||||
top + child.measuredHeight
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
}
|
||||
|
||||
override fun generateDefaultLayoutParams(): ViewGroup.LayoutParams {
|
||||
return LayoutParams()
|
||||
}
|
||||
|
||||
override fun checkLayoutParams(p: ViewGroup.LayoutParams?): Boolean {
|
||||
return p is LayoutParams
|
||||
}
|
||||
|
||||
override fun generateLayoutParams(attrs: AttributeSet): ViewGroup.LayoutParams {
|
||||
return LayoutParams(context, attrs)
|
||||
}
|
||||
|
||||
override fun generateLayoutParams(p: ViewGroup.LayoutParams): ViewGroup.LayoutParams {
|
||||
return LayoutParams(p)
|
||||
}
|
||||
|
||||
class LayoutParams : ViewGroup.LayoutParams {
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
constructor(width: Int, height: Int) : super(width, height)
|
||||
constructor(params: ViewGroup.LayoutParams) : super(params)
|
||||
constructor() : this(WRAP_CONTENT, WRAP_CONTENT)
|
||||
|
||||
var x: Int = 0
|
||||
var y: Int = 0
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package io.noties.markwon.app.base
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import io.noties.markwon.app.R
|
||||
import io.noties.markwon.app.utils.KeyEventUtils
|
||||
import io.noties.markwon.app.utils.KeyboardUtils
|
||||
import io.noties.markwon.app.utils.TextWatcherAdapter
|
||||
import io.noties.markwon.app.utils.hidden
|
||||
|
||||
|
||||
class SearchBar(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
|
||||
|
||||
private val focus: View
|
||||
private val textField: TextField
|
||||
private val clear: View
|
||||
private val cancel: View
|
||||
|
||||
var onSearchListener: ((String?) -> Unit)? = null
|
||||
|
||||
init {
|
||||
orientation = HORIZONTAL
|
||||
gravity = Gravity.CENTER_VERTICAL
|
||||
|
||||
View.inflate(context, R.layout.view_search_bar, this)
|
||||
|
||||
focus = findViewById(R.id.focus)
|
||||
textField = findViewById(R.id.text_field)
|
||||
clear = findViewById(R.id.clear)
|
||||
cancel = findViewById(R.id.cancel)
|
||||
|
||||
// listen for text state
|
||||
textField.addTextChangedListener(TextWatcherAdapter.afterTextChanged {
|
||||
textFieldChanged(it)
|
||||
})
|
||||
|
||||
fun looseFocus() {
|
||||
KeyboardUtils.hide(textField)
|
||||
focus.requestFocus()
|
||||
}
|
||||
|
||||
// on back pressed - lose focus and hide keyboard
|
||||
textField.onBackPressedListener = {
|
||||
// hide keyboard and lose focus
|
||||
looseFocus()
|
||||
}
|
||||
|
||||
textField.setOnFocusChangeListener { _, hasFocus ->
|
||||
cancel.hidden = textField.text.isEmpty() && !hasFocus
|
||||
}
|
||||
|
||||
textField.setOnEditorActionListener { _, _, event ->
|
||||
if (KeyEventUtils.isActionUp(event)) {
|
||||
looseFocus()
|
||||
}
|
||||
return@setOnEditorActionListener true
|
||||
}
|
||||
|
||||
clear.setOnClickListener {
|
||||
textField.setText("")
|
||||
}
|
||||
|
||||
cancel.setOnClickListener {
|
||||
textField.setText("")
|
||||
looseFocus()
|
||||
}
|
||||
}
|
||||
|
||||
private fun textFieldChanged(text: CharSequence) {
|
||||
val isEmpty = text.isEmpty()
|
||||
clear.hidden = isEmpty
|
||||
cancel.hidden = isEmpty && !textField.hasFocus()
|
||||
|
||||
onSearchListener?.invoke(if (text.isEmpty()) null else text.toString())
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package io.noties.markwon.app.base
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.KeyEvent
|
||||
import android.widget.EditText
|
||||
import io.noties.markwon.app.utils.KeyEventUtils
|
||||
|
||||
class TextField(context: Context, attrs: AttributeSet?) : EditText(context, attrs) {
|
||||
var onBackPressedListener: (() -> Unit)? = null
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
onBackPressedListener = null
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
override fun onKeyPreIme(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
if (isAttachedToWindow) {
|
||||
onBackPressedListener?.also { listener ->
|
||||
if (hasFocus()
|
||||
&& KeyEvent.KEYCODE_BACK == keyCode
|
||||
&& KeyEventUtils.isActionUp(event)) {
|
||||
listener()
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKeyPreIme(keyCode, event)
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.noties.markwon.app.samples
|
||||
|
||||
import io.noties.markwon.app.MarkwonSample
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
||||
|
||||
@MarkwonSampleInfo(
|
||||
id = "202006164150023",
|
||||
title = "First Sample",
|
||||
description = "This **is** _the first_ sample",
|
||||
artifacts = [MarkwonArtifact.CORE],
|
||||
tags = ["test"]
|
||||
)
|
||||
class FirstSample : MarkwonSample() {
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package io.noties.markwon.app.utils
|
||||
|
||||
import android.view.KeyEvent
|
||||
|
||||
object KeyEventUtils {
|
||||
fun isActionUp(event: KeyEvent?): Boolean {
|
||||
return event == null || KeyEvent.ACTION_UP == event.action
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package io.noties.markwon.app.utils
|
||||
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
|
||||
object KeyboardUtils {
|
||||
|
||||
fun show(view: View) {
|
||||
view.context.getSystemService(InputMethodManager::class.java)
|
||||
?.showSoftInput(view, 0)
|
||||
}
|
||||
|
||||
fun hide(view: View) {
|
||||
view.context.getSystemService(InputMethodManager::class.java)
|
||||
?.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package io.noties.markwon.app.utils;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public abstract class TextWatcherAdapter implements TextWatcher {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
|
||||
public interface AfterTextChanged {
|
||||
void afterTextChanged(Editable s);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static TextWatcher afterTextChanged(@NonNull AfterTextChanged afterTextChanged) {
|
||||
return new TextWatcherAdapter() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
afterTextChanged.afterTextChanged(s);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.noties.markwon.app.utils
|
||||
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
|
||||
var View.hidden: Boolean
|
||||
get() = visibility == GONE
|
||||
set(value) {
|
||||
visibility = if (value) GONE else VISIBLE
|
||||
}
|
15
app-sample/src/main/res/drawable/bg_artifact.xml
Normal file
15
app-sample/src/main/res/drawable/bg_artifact.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_activated="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/red" />
|
||||
<corners android:radius="128dip" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/gray" />
|
||||
<corners android:radius="128dip" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
13
app-sample/src/main/res/drawable/bg_tag.xml
Normal file
13
app-sample/src/main/res/drawable/bg_tag.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_activated="true">
|
||||
<shape>
|
||||
<solid android:color="@color/red" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="@color/accent" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
10
app-sample/src/main/res/drawable/ic_close_white_24dp.xml
Normal file
10
app-sample/src/main/res/drawable/ic_close_white_24dp.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
|
||||
</vector>
|
10
app-sample/src/main/res/drawable/ic_search_white_24dp.xml
Normal file
10
app-sample/src/main/res/drawable/ic_search_white_24dp.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
|
||||
</vector>
|
51
app-sample/src/main/res/layout/activity_main.xml
Normal file
51
app-sample/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?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:elevation="4dip"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
style="@style/AppBarIcon"
|
||||
android:contentDescription="@null"
|
||||
android:padding="8dip"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/app_bar_height"
|
||||
android:gravity="center"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</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"
|
||||
tools:translationY="56dip" />
|
||||
|
||||
<io.noties.markwon.app.base.SearchBar
|
||||
android:id="@+id/search_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:padding="@dimen/content_padding" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
17
app-sample/src/main/res/layout/adapt_artifact.xml
Normal file
17
app-sample/src/main/res/layout/adapt_artifact.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"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_artifact"
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingTop="2dip"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="2dip"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="@color/white"
|
||||
tools:text="core" />
|
51
app-sample/src/main/res/layout/adapt_sample.xml
Normal file
51
app-sample/src/main/res/layout/adapt_sample.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?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="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!--textView instead of icon, so we align baseline-->
|
||||
<TextView
|
||||
android:layout_width="@dimen/adapt_sample_hash_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="#"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="?android:attr/colorSecondary"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
tools:text="Title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/adapt_sample_hash_width"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
tools:text="Description goes here" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/artifacts_and_tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/adapt_sample_hash_width"
|
||||
tools:text="recycler-view adapt another" />
|
||||
|
||||
</LinearLayout>
|
83
app-sample/src/main/res/layout/view_search_bar.xml
Normal file
83
app-sample/src/main/res/layout/view_search_bar.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:background="#eee"
|
||||
tools:gravity="center_vertical"
|
||||
tools:layout_height="wrap_content"
|
||||
tools:layout_widht="match_parent"
|
||||
tools:orientation="horizontal"
|
||||
tools:padding="@dimen/content_padding"
|
||||
tools:parentTag="android.widget.LinearLayout">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/white"
|
||||
android:paddingTop="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding">
|
||||
|
||||
<View
|
||||
android:id="@+id/focus"
|
||||
android:layout_width="1px"
|
||||
android:layout_height="1px"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true">
|
||||
|
||||
<requestFocus />
|
||||
|
||||
</View>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/search_bar_icon_side"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_search_white_24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:tint="@color/gray" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/clear"
|
||||
android:layout_width="@dimen/search_bar_icon_side"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_close_white_24dp"
|
||||
android:tint="@color/gray"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<io.noties.markwon.app.base.TextField
|
||||
android:id="@+id/text_field"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/search_bar_icon_side"
|
||||
android:layout_marginEnd="@dimen/search_bar_icon_side"
|
||||
android:autofillHints="@null"
|
||||
android:background="@null"
|
||||
android:hint="@android:string/search_go"
|
||||
android:inputType="textVisiblePassword"
|
||||
android:lines="1"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/content_padding"
|
||||
android:text="@android:string/cancel"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="@color/accent"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</merge>
|
@ -1,4 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="accent">#5CB85C</color>
|
||||
<color name="accent">#009900</color>
|
||||
|
||||
<color name="gray">#777777</color>
|
||||
<color name="gray_light">#999999</color>
|
||||
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="window_background">#EEEEEE</color>
|
||||
<color name="red">#FF0000</color>
|
||||
</resources>
|
10
app-sample/src/main/res/values/dimens.xml
Normal file
10
app-sample/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="app_bar_height">56dip</dimen>
|
||||
|
||||
<dimen name="content_padding">8dip</dimen>
|
||||
<dimen name="content_padding_double">16dip</dimen>
|
||||
|
||||
<dimen name="search_bar_icon_side">36dip</dimen>
|
||||
<dimen name="adapt_sample_hash_width">36dip</dimen>
|
||||
</resources>
|
@ -1,8 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppThemeBase" parent="android:Theme.Material.Light.NoActionBar">
|
||||
|
||||
<style name="AppThemeBase" parent="android:Theme.Material.Light.NoActionBar">
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="android:colorPrimary">@color/gray_light</item>
|
||||
<item name="android:colorPrimaryDark">@color/gray</item>
|
||||
<item name="android:windowBackground">@color/window_background</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme" parent="AppThemeBase" />
|
||||
|
||||
<style name="AppBarContainer">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">@dimen/app_bar_height</item>
|
||||
<item name="android:background">@color/gray_light</item>
|
||||
</style>
|
||||
|
||||
<style name="AppBarIcon">
|
||||
<item name="android:layout_width">@dimen/app_bar_height</item>
|
||||
<item name="android:layout_height">@dimen/app_bar_height</item>
|
||||
<item name="android:scaleType">centerInside</item>
|
||||
<item name="android:background">?android:attr/selectableItemBackgroundBorderless</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
64
art/ic_hash_white_24dp.svg
Normal file
64
art/ic_hash_white_24dp.svg
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="ic_hash_white_24dp.svg"
|
||||
inkscape:version="1.0beta2 (2b71d25, 2019-12-03)"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
height="24mm"
|
||||
width="24mm">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="813"
|
||||
inkscape:window-width="1440"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="75.396079"
|
||||
inkscape:cx="72.78404"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
style="font-style:normal;font-weight:normal;font-size:26.70579999999999998px;line-height:1.25;font-family:sans-serif;fill:#800000;fill-opacity:1;stroke:none;stroke-width:0.667646"
|
||||
id="text12"
|
||||
aria-label="#">
|
||||
<path
|
||||
id="path62"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Semi-Bold';fill:#800000;stroke-width:0.667646"
|
||||
d="m 16.28362,10.174409 -0.717197,3.703343 h 3.520785 v 2.19071 h -3.951103 l -1.043195,5.450695 h -2.321109 l 1.043195,-5.450695 H 9.5810905 L 8.5378953,21.519157 H 6.2689455 L 7.259981,16.068462 H 3.9999958 v -2.19071 H 7.6902991 L 8.4335757,10.174409 H 4.9910313 V 7.9836987 H 8.811734 L 9.8549293,2.4808436 h 2.3471897 l -1.043196,5.5028551 h 3.286066 l 1.043195,-5.5028551 h 2.26895 l -1.043196,5.5028551 h 3.286065 v 2.1907103 z m -6.2982913,3.703343 h 3.2599853 l 0.743277,-3.703343 h -3.259986 z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
@ -77,8 +77,8 @@ ext {
|
||||
'jlatexmath-android' : 'ru.noties:jlatexmath-android:0.2.0',
|
||||
'okhttp' : 'com.squareup.okhttp3:okhttp:3.9.0',
|
||||
'prism4j' : 'io.noties:prism4j:2.0.0',
|
||||
'debug' : 'io.noties:debug:5.0.0@jar',
|
||||
'adapt' : 'io.noties:adapt:2.0.0',
|
||||
'debug' : 'io.noties:debug:5.1.0',
|
||||
'adapt' : 'io.noties:adapt:2.2.0',
|
||||
'dagger' : "com.google.dagger:dagger:$daggerVersion",
|
||||
'picasso' : 'com.squareup.picasso:picasso:2.71828',
|
||||
'glide' : 'com.github.bumptech.glide:glide:4.9.0',
|
||||
|
Loading…
x
Reference in New Issue
Block a user