diff --git a/README.md b/README.md index 2527e5b..b81a2d2 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ https://github.com/pokeum/jsonviewer-xml/assets/102505472/e2f260f0-cc28-4607-9ec - [Usage](#usage) - [Basic](#basic) - [Advance](#advance) +- [Custom Styles](#styles) ## Installation @@ -150,3 +151,45 @@ implementation 'com.github.pokeum:jsonviewer-xml:0.0.0' } } ``` + +## Custom Styles + +### Color + +| | | +| -- | -- | +| Key | `"friends"`, `"0"`, `"name"`, `"age"` | +| Value | `"Alice"`, `28` | +| Splitter | `:` | +| Type | `ABC`, `123` | +| Arrow | `\/` | +| Bracket | `[ ]`, `{ }` | +| Divider | `│` | + +#### Use JsonRecyclerView + + ```xml + + ``` + +#### Use RecyclerView + + ```kotlin + recyclerView.adapter = JsonViewerAdapter(/* JsonElement */).apply { + setKeyColor(JVColor(/* Default Color[, Dark Mode Color] */)) + setValueColor(JVColor(/* ... */)) + setSplitterColor(JVColor(/* ... */)) + setTypeColor(JVColor(/* ... */)) + setArrowColor(JVColor(/* ... */)) + setBracketColor(JVColor(/* ... */)) + setDividerColor(JVColor(/* ... */)) + } + ``` diff --git a/app/build.gradle b/app/build.gradle index 4d3a949..75e08f5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,7 +59,8 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) - implementation 'com.github.pokeum:jsonviewer-xml:0.0.0' + //implementation 'com.github.pokeum:jsonviewer-xml:0.0.0' + implementation(project(":jsonviewer")) implementation stdlib.kotlin implementation androidx.core diff --git a/app/src/main/java/kr/pokeum/app/presentation/activity/JsonViewerActivity.kt b/app/src/main/java/kr/pokeum/app/presentation/activity/JsonViewerActivity.kt index 1e50df8..bd31a0c 100644 --- a/app/src/main/java/kr/pokeum/app/presentation/activity/JsonViewerActivity.kt +++ b/app/src/main/java/kr/pokeum/app/presentation/activity/JsonViewerActivity.kt @@ -41,7 +41,8 @@ class JsonViewerActivity : AppCompatActivity() { private fun initRecyclerView() { jsonElement?.let { - binding.jsonRecyclerView.adapter = JsonViewerAdapter(it) + val adapter = JsonViewerAdapter(it) + binding.jsonRecyclerView.adapter = adapter } } diff --git a/image/screenshot/styles-color.png b/image/screenshot/styles-color.png new file mode 100644 index 0000000..daba288 Binary files /dev/null and b/image/screenshot/styles-color.png differ diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/JsonRecyclerView.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/JsonRecyclerView.kt index 2f201a9..967e356 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/JsonRecyclerView.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/JsonRecyclerView.kt @@ -5,7 +5,9 @@ import android.util.AttributeSet import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kr.pokeum.jsonviewer_xml.adapter.JsonViewerAdapter +import kr.pokeum.jsonviewer_xml.util.JVColor +@Suppress("DEPRECATION") class JsonRecyclerView @JvmOverloads constructor( @@ -15,12 +17,28 @@ constructor( private var text: String + private var keyColor: Int + private var valueColor: Int + private var splitterColor: Int + private var typeColor: Int + private var arrowColor: Int + private var bracketColor: Int + private var dividerColor: Int + init { val typedArray = context.obtainStyledAttributes( attrs, R.styleable.JsonRecyclerView, 0, 0 ) try { text = typedArray.getString(R.styleable.JsonRecyclerView_text) ?: DEFAULT_TEXT + + keyColor = typedArray.getColor(R.styleable.JsonRecyclerView_keyColor, resources.getColor(R.color.jv_key_color)) + valueColor = typedArray.getColor(R.styleable.JsonRecyclerView_valueColor, resources.getColor(R.color.jv_value_color)) + splitterColor = typedArray.getColor(R.styleable.JsonRecyclerView_splitterColor, resources.getColor(R.color.jv_splitter_color)) + typeColor = typedArray.getColor(R.styleable.JsonRecyclerView_typeColor, resources.getColor(R.color.jv_type_color)) + arrowColor = typedArray.getColor(R.styleable.JsonRecyclerView_arrowColor, resources.getColor(R.color.jv_arrow_color)) + bracketColor = typedArray.getColor(R.styleable.JsonRecyclerView_bracketColor, resources.getColor(R.color.jv_bracket_color)) + dividerColor = typedArray.getColor(R.styleable.JsonRecyclerView_dividerColor, resources.getColor(R.color.jv_divider_color)) } finally { typedArray.recycle() } @@ -36,7 +54,15 @@ constructor( jsonParser.parse(text) } catch (_: Throwable) { jsonParser.parse(DEFAULT_TEXT) - }) + }).apply { + setKeyColor(JVColor(keyColor)) + setValueColor(JVColor(valueColor)) + setSplitterColor(JVColor(splitterColor)) + setTypeColor(JVColor(typeColor)) + setArrowColor(JVColor(arrowColor)) + setBracketColor(JVColor(bracketColor)) + setDividerColor(JVColor(dividerColor)) + } } companion object { diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/BaseJsonViewerAdapter.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/BaseJsonViewerAdapter.kt new file mode 100644 index 0000000..6bd4df0 --- /dev/null +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/BaseJsonViewerAdapter.kt @@ -0,0 +1,29 @@ +package kr.pokeum.jsonviewer_xml.adapter + +import androidx.recyclerview.widget.RecyclerView +import kr.pokeum.jsonviewer_xml.util.JVColor + +abstract class BaseJsonViewerAdapter : RecyclerView.Adapter() +{ +// abstract fun expandAll() +// abstract fun collapseAll() + + fun setKeyColor(color: JVColor) { KEY_COLOR = color } + fun setValueColor(color: JVColor) { VALUE_COLOR = color } + fun setSplitterColor(color: JVColor) { SPLITTER_COLOR = color } + fun setTypeColor(color: JVColor) { TYPE_COLOR = color } + fun setArrowColor(color: JVColor) { ARROW_COLOR = color } + fun setBracketColor(color: JVColor) { BRACKET_COLOR = color } + fun setDividerColor(color: JVColor) { DIVIDER_COLOR = color } + + companion object { + internal var KEY_COLOR = JVColor(0xFF000000.toInt(), 0xFFFFFFFF.toInt()) + internal var VALUE_COLOR = JVColor(0xFF888888.toInt()) + internal var SPLITTER_COLOR = JVColor(0xFF000000.toInt(), 0xFFFFFFFF.toInt()) + internal var TYPE_COLOR = JVColor(0xFF2196F3.toInt()) + internal var ARROW_COLOR = JVColor(0xFFF44336.toInt()) + internal var BRACKET_COLOR = JVColor(0xFF4CAF50.toInt()) + internal var DIVIDER_COLOR = JVColor(0x1E000000.toInt(), 0x1EFFFFFF.toInt()) + } +} + diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/JsonViewerAdapter.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/JsonViewerAdapter.kt index 00a78ec..c75f6c8 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/JsonViewerAdapter.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/adapter/JsonViewerAdapter.kt @@ -19,7 +19,7 @@ import kr.pokeum.jsonviewer_xml.viewholder.JsonPrimitiveViewHolder class JsonViewerAdapter( jsonElement: JsonElement? = null, recyclerViewPool: RecyclerView.RecycledViewPool? = null -) : RecyclerView.Adapter() { +) : BaseJsonViewerAdapter() { private val elements: MutableList private val recyclerViewPool: RecyclerView.RecycledViewPool diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/SpansUtils.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/SpansUtils.kt index 16fe5a3..7a88665 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/SpansUtils.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/SpansUtils.kt @@ -6,8 +6,7 @@ import android.text.Html.FROM_HTML_MODE_LEGACY import android.text.Spanned import android.view.View import androidx.annotation.ColorInt -import androidx.core.content.ContextCompat -import kr.pokeum.jsonviewer_xml.R +import kr.pokeum.jsonviewer_xml.adapter.BaseJsonViewerAdapter internal fun fromHtml(htmlText: String): Spanned { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { @@ -21,9 +20,9 @@ internal fun keyValueHtmlGenerator( splitter: String, view: View, /* Support dark mode */ ): String { - return textColorHtmlGenerator(key, ContextCompat.getColor(view.context, R.color.jv_key_color)) + - textColorHtmlGenerator(splitter, ContextCompat.getColor(view.context, R.color.jv_splitter_color)) + - textColorHtmlGenerator(value, ContextCompat.getColor(view.context, R.color.jv_value_color)) + return textColorHtmlGenerator(key, BaseJsonViewerAdapter.KEY_COLOR.getColor(view)) + + textColorHtmlGenerator(splitter, BaseJsonViewerAdapter.SPLITTER_COLOR.getColor(view)) + + textColorHtmlGenerator(value, BaseJsonViewerAdapter.VALUE_COLOR.getColor(view)) } /** diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/StyleUtils.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/StyleUtils.kt new file mode 100644 index 0000000..4427310 --- /dev/null +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/util/StyleUtils.kt @@ -0,0 +1,17 @@ +package kr.pokeum.jsonviewer_xml.util + +import android.content.res.Configuration +import android.view.View +import androidx.annotation.ColorInt + +class JVColor( + @ColorInt private val default: Int, + @ColorInt private val night: Int +) { + constructor(@ColorInt default: Int) : this(default, default) + + internal fun getColor(view: View) = when (view.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { + Configuration.UI_MODE_NIGHT_YES -> night + else -> default + } +} \ No newline at end of file diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonArrayViewHolder.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonArrayViewHolder.kt index 5a549f5..0b4101a 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonArrayViewHolder.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonArrayViewHolder.kt @@ -1,7 +1,9 @@ package kr.pokeum.jsonviewer_xml.viewholder +import android.annotation.SuppressLint import android.view.View import androidx.recyclerview.widget.RecyclerView +import kr.pokeum.jsonviewer_xml.adapter.BaseJsonViewerAdapter import kr.pokeum.jsonviewer_xml.adapter.JsonViewerAdapter import kr.pokeum.jsonviewer_xml.databinding.ItemJsonArrayBinding import kr.pokeum.jsonviewer_xml.model.JsonArray @@ -27,11 +29,14 @@ internal class JsonArrayViewHolder( binding.childRecyclerView.setRecycledViewPool(recycledViewPool) } + @SuppressLint("SetTextI18n") fun bind(jsonArray: JsonArray) { target = jsonArray expandableUI(jsonArray.isExpanded()) binding.keyLabel.text = "\"${jsonArray.key}\"" childAdapter.setElements(jsonArray.elements) + + setStyle() } private fun expandableUI(isExpanded: Boolean) { @@ -39,4 +44,12 @@ internal class JsonArrayViewHolder( binding.arrowImage.rotation = rotation binding.expandableLayout.visibility = if (isExpanded) View.VISIBLE else View.GONE } + + private fun setStyle() { + // COLOR + binding.arrowImage.setColorFilter(BaseJsonViewerAdapter.ARROW_COLOR.getColor(binding.root)) + binding.keyDescriptionLabel.setTextColor(BaseJsonViewerAdapter.BRACKET_COLOR.getColor(binding.root)) + binding.keyLabel.setTextColor(BaseJsonViewerAdapter.KEY_COLOR.getColor(binding.root)) + binding.divider.setBackgroundColor(BaseJsonViewerAdapter.DIVIDER_COLOR.getColor(binding.root)) + } } \ No newline at end of file diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonNullViewHolder.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonNullViewHolder.kt index ffab500..8372d3b 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonNullViewHolder.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonNullViewHolder.kt @@ -2,6 +2,7 @@ package kr.pokeum.jsonviewer_xml.viewholder import android.view.View import androidx.recyclerview.widget.RecyclerView +import kr.pokeum.jsonviewer_xml.adapter.BaseJsonViewerAdapter import kr.pokeum.jsonviewer_xml.databinding.ItemJsonNullBinding import kr.pokeum.jsonviewer_xml.model.JsonNull import kr.pokeum.jsonviewer_xml.util.fromHtml @@ -22,6 +23,13 @@ internal class JsonNullViewHolder( view = binding.root ) ) + + setStyle() + } + + private fun setStyle() { + // COLOR + binding.keyDescriptionLabel.setTextColor(BaseJsonViewerAdapter.TYPE_COLOR.getColor(binding.root)) } companion object { diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonObjectViewHolder.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonObjectViewHolder.kt index cbe8798..312d173 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonObjectViewHolder.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonObjectViewHolder.kt @@ -1,9 +1,11 @@ package kr.pokeum.jsonviewer_xml.viewholder +import android.annotation.SuppressLint import android.view.View import android.view.View.GONE import android.view.View.VISIBLE import androidx.recyclerview.widget.RecyclerView +import kr.pokeum.jsonviewer_xml.adapter.BaseJsonViewerAdapter import kr.pokeum.jsonviewer_xml.adapter.JsonViewerAdapter import kr.pokeum.jsonviewer_xml.databinding.ItemJsonObjectBinding import kr.pokeum.jsonviewer_xml.model.JsonObject @@ -29,11 +31,14 @@ internal class JsonObjectViewHolder( binding.childRecyclerView.setRecycledViewPool(recycledViewPool) } + @SuppressLint("SetTextI18n") fun bind(jsonObject: JsonObject) { target = jsonObject expandableUI(jsonObject.isExpanded()) binding.keyLabel.text = "\"${jsonObject.key}\"" childAdapter.setElements(jsonObject.elements) + + setStyle() } private fun expandableUI(isExpanded: Boolean) { @@ -41,4 +46,12 @@ internal class JsonObjectViewHolder( binding.arrowImage.rotation = rotation binding.expandableLayout.visibility = if (isExpanded) VISIBLE else GONE } + + private fun setStyle() { + // COLOR + binding.arrowImage.setColorFilter(BaseJsonViewerAdapter.ARROW_COLOR.getColor(binding.root)) + binding.keyDescriptionLabel.setTextColor(BaseJsonViewerAdapter.BRACKET_COLOR.getColor(binding.root)) + binding.keyLabel.setTextColor(BaseJsonViewerAdapter.KEY_COLOR.getColor(binding.root)) + binding.divider.setBackgroundColor(BaseJsonViewerAdapter.DIVIDER_COLOR.getColor(binding.root)) + } } \ No newline at end of file diff --git a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonPrimitiveViewHolder.kt b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonPrimitiveViewHolder.kt index 43bd5fb..af5c479 100644 --- a/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonPrimitiveViewHolder.kt +++ b/jsonviewer/src/main/java/kr/pokeum/jsonviewer_xml/viewholder/JsonPrimitiveViewHolder.kt @@ -2,6 +2,7 @@ package kr.pokeum.jsonviewer_xml.viewholder import android.view.View import androidx.recyclerview.widget.RecyclerView +import kr.pokeum.jsonviewer_xml.adapter.BaseJsonViewerAdapter import kr.pokeum.jsonviewer_xml.databinding.ItemJsonPrimitiveBinding import kr.pokeum.jsonviewer_xml.model.JsonPrimitive import kr.pokeum.jsonviewer_xml.util.fromHtml @@ -38,6 +39,13 @@ internal class JsonPrimitiveViewHolder( view = binding.root ) ) + + setStyle() + } + + private fun setStyle() { + // COLOR + binding.keyDescriptionLabel.setTextColor(BaseJsonViewerAdapter.TYPE_COLOR.getColor(binding.root)) } companion object { diff --git a/jsonviewer/src/main/res/layout/item_json_array.xml b/jsonviewer/src/main/res/layout/item_json_array.xml index daefb88..16a3a95 100644 --- a/jsonviewer/src/main/res/layout/item_json_array.xml +++ b/jsonviewer/src/main/res/layout/item_json_array.xml @@ -21,7 +21,7 @@ android:layout_marginLeft="@dimen/json_key_margin_start" android:layout_marginStart="@dimen/json_key_margin_start" app:srcCompat="@drawable/ic_arrow_white_24dp" - app:tint="@color/red_500" + app:tint="@color/jv_arrow_color" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -41,7 +41,7 @@ android:layout_gravity="center" android:text="@string/json_array_key_description_label" android:textSize="@dimen/json_key_description_label_size" - android:textColor="@color/green_500" + android:textColor="@color/jv_bracket_color" android:textStyle="bold" /> @@ -53,7 +53,7 @@ android:layout_marginLeft="@dimen/json_key_margin_start" android:layout_marginStart="@dimen/json_key_margin_start" android:textSize="@dimen/json_key_label_size" - android:textColor="@color/jv_array_index_color" + android:textColor="@color/jv_key_color" android:textStyle="bold" tools:text="@string/json_key_label" app:layout_constrainedWidth="true" @@ -73,6 +73,7 @@ app:layout_constraintTop_toBottomOf="@+id/headerLayout" > diff --git a/jsonviewer/src/main/res/layout/item_json_object.xml b/jsonviewer/src/main/res/layout/item_json_object.xml index ddf1a90..6cfc234 100644 --- a/jsonviewer/src/main/res/layout/item_json_object.xml +++ b/jsonviewer/src/main/res/layout/item_json_object.xml @@ -20,7 +20,7 @@ android:layout_marginLeft="@dimen/json_key_margin_start" android:layout_marginStart="@dimen/json_key_margin_start" app:srcCompat="@drawable/ic_arrow_white_24dp" - app:tint="@color/red_500" + app:tint="@color/jv_arrow_color" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -40,7 +40,7 @@ android:layout_gravity="center" android:text="@string/json_object_key_description_label" android:textSize="@dimen/json_key_description_label_size" - android:textColor="@color/green_500" + android:textColor="@color/jv_bracket_color" android:textStyle="bold" /> @@ -52,7 +52,7 @@ android:layout_marginLeft="@dimen/json_key_margin_start" android:layout_marginStart="@dimen/json_key_margin_start" android:textSize="@dimen/json_key_label_size" - android:textColor="@color/jv_object_key_color" + android:textColor="@color/jv_key_color" android:textStyle="bold" tools:text="@string/json_key_label" app:layout_constrainedWidth="true" @@ -72,6 +72,7 @@ app:layout_constraintTop_toBottomOf="@+id/headerLayout" > diff --git a/jsonviewer/src/main/res/values-night/colors.xml b/jsonviewer/src/main/res/values-night/colors.xml index ecc6143..6f9798d 100644 --- a/jsonviewer/src/main/res/values-night/colors.xml +++ b/jsonviewer/src/main/res/values-night/colors.xml @@ -12,12 +12,11 @@ #FF4CAF50 - #1EFFFFFF - @color/white @color/gray @color/white - - @color/light_gray - @color/light_gray + @color/blue_500 + @color/red_500 + @color/green_500 + #1EFFFFFF \ No newline at end of file diff --git a/jsonviewer/src/main/res/values/attrs.xml b/jsonviewer/src/main/res/values/attrs.xml index b7bdca3..5077f25 100644 --- a/jsonviewer/src/main/res/values/attrs.xml +++ b/jsonviewer/src/main/res/values/attrs.xml @@ -2,5 +2,12 @@ + + + + + + + \ No newline at end of file diff --git a/jsonviewer/src/main/res/values/colors.xml b/jsonviewer/src/main/res/values/colors.xml index 7c091ce..b69a4d7 100644 --- a/jsonviewer/src/main/res/values/colors.xml +++ b/jsonviewer/src/main/res/values/colors.xml @@ -12,12 +12,11 @@ #FF4CAF50 - #1E000000 - @color/black @color/gray @color/black - - @color/dark_gray - @color/dark_gray + @color/blue_500 + @color/red_500 + @color/green_500 + #1E000000 \ No newline at end of file