From a5201e5fabeb137fe052ffb32b1baec9c50c1106 Mon Sep 17 00:00:00 2001 From: Kirill Biakov Date: Sat, 26 Aug 2017 22:46:40 +0300 Subject: [PATCH 1/2] Updated versions, code cleanings --- build.gradle | 4 +- codeview/build.gradle | 8 +-- .../io/github/kbiakov/codeview/CodeView.kt | 49 ++++++++++--------- .../java/io/github/kbiakov/codeview/Utils.kt | 32 ++++++------ example/build.gradle | 12 ++--- .../codeviewexample/ListingsActivity.java | 13 +++-- .../src/main/res/layout/activity_listings.xml | 4 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 8 files changed, 65 insertions(+), 61 deletions(-) diff --git a/build.gradle b/build.gradle index e747c9f..1f9ae80 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.0.3' + ext.kotlin_version = '1.1.2-5' repositories { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.android.tools.build:gradle:2.3.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/codeview/build.gradle b/codeview/build.gradle index 79feaca..52578c5 100644 --- a/codeview/build.gradle +++ b/codeview/build.gradle @@ -3,13 +3,13 @@ apply plugin: 'kotlin-android' android { compileSdkVersion 25 - buildToolsVersion "25.0.1" + buildToolsVersion '25.0.3' defaultConfig { minSdkVersion 15 targetSdkVersion 25 versionCode 1 - versionName "1.0" + versionName '1.0' } buildTypes { release { @@ -25,8 +25,8 @@ android { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - compile 'com.android.support:appcompat-v7:25.0.1' - compile 'com.android.support:recyclerview-v7:25.0.1' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' } repositories { mavenCentral() diff --git a/codeview/src/main/java/io/github/kbiakov/codeview/CodeView.kt b/codeview/src/main/java/io/github/kbiakov/codeview/CodeView.kt index 830b266..35b3951 100644 --- a/codeview/src/main/java/io/github/kbiakov/codeview/CodeView.kt +++ b/codeview/src/main/java/io/github/kbiakov/codeview/CodeView.kt @@ -30,24 +30,17 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context, * Primary constructor. */ init { - val isAnimateOnStart = visibility == VISIBLE && { ctx: Context, ats: AttributeSet -> - val a = ctx.theme.obtainStyledAttributes(ats, R.styleable.CodeView, 0, 0) - - try { - a.getBoolean(R.styleable.CodeView_animateOnStart, true) - } finally { - a.recycle() - } - }(context, attrs) - - alpha = if (isAnimateOnStart) 0f else Consts.ALPHA - inflate(context, R.layout.layout_code_view, this) - if (isAnimateOnStart) + if (visibility == VISIBLE && isAnimateOnStart(context, attrs)) { + alpha = Const.Alpha.Invisible + animate() - .setDuration(Consts.DELAY * 5) - .alpha(Consts.ALPHA) + .setDuration(Const.DefaultDelay * 5) + .alpha(Const.Alpha.Initial) + } else { + alpha = Const.Alpha.Initial + } // TODO: add shadow color customization vShadowRight = findViewById(R.id.v_shadow_right) @@ -67,7 +60,7 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context, getAdapter()?.highlight { animate() - .setDuration(Consts.DELAY * 2) + .setDuration(Const.DefaultDelay * 2) .alpha(.1f) delayed { @@ -121,7 +114,7 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context, /** * View options accessor. */ - fun getOptions(): Options? = getAdapter()?.options + fun getOptions() = getAdapter()?.options fun getOptionsOrDefault() = getOptions() ?: Options(context) /** @@ -130,10 +123,8 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context, * @param options Options */ fun updateOptions(options: Options) { - if (getAdapter() == null) - setOptions(options) - else - getAdapter()!!.options = options + getAdapter() ?: setOptions(options) + getAdapter()?.options = options } // - Adapter @@ -169,7 +160,7 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context, */ fun setCode(code: String) { getAdapter() ?: prepare() - getAdapter()!!.updateCode(code) + getAdapter()?.updateCode(code) } /** @@ -185,7 +176,19 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context, fun setCode(code: String, language: String) { val options = getOptionsOrDefault() updateOptions(options.withLanguage(language)) - getAdapter()!!.updateCode(code) + getAdapter()?.updateCode(code) + } + + companion object { + + private fun isAnimateOnStart(context: Context, attr: AttributeSet): Boolean { + context.theme.obtainStyledAttributes(attr, R.styleable.CodeView, 0, 0).apply { + val flag = getBoolean(R.styleable.CodeView_animateOnStart, false) + recycle() + return@isAnimateOnStart flag + } + return false + } } } diff --git a/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt b/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt index 66b3283..1b94398 100644 --- a/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt +++ b/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt @@ -4,15 +4,19 @@ import android.content.Context import android.os.Handler import android.os.Looper import android.text.Html -import android.text.Spanned import android.util.TypedValue import java.io.BufferedReader import java.io.InputStreamReader import java.util.concurrent.Executors -object Consts { - val ALPHA = 0.7F - val DELAY = 250L +object Const { + val DefaultDelay = 250L + + object Alpha { + val Initial = 0.7f + val Invisible = 0f + val Visible = 1f + } } /** @@ -22,7 +26,7 @@ object Consts { * @param dp Dip value * @return Converted to px value */ -fun dpToPx(context: Context, dp: Int): Int = +fun dpToPx(context: Context, dp: Int) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), context.resources.displayMetrics).toInt() @@ -49,7 +53,7 @@ fun extractLines(source: String) = listOf(*source.split("\n").toTypedArray()) * @return Spanned HTML string */ @Suppress("deprecation") -fun html(content: String): Spanned = +fun html(content: String) = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY) else @@ -80,15 +84,14 @@ object Thread { * @param body Operation body * @param delayMs Delay in m */ - fun delayed(delayMs: Long = Consts.DELAY, body: () -> Unit) = - Handler().postDelayed(body, delayMs) + fun delayed(delayMs: Long = Const.DefaultDelay, body: () -> Unit) { + Handler().postDelayed(body, delayMs) + } // - Extensions for block manipulations fun (() -> Unit).ui(isUi: Boolean = true) { - if (isUi) ui { - this() - } else this() + if (isUi) ui(this) else this() } } @@ -113,15 +116,12 @@ object Files { var content = "" ls(context, path).forEach { filename -> - val input = context.assets.open(path + '/' + filename) + val input = context.assets.open("$path/$filename") BufferedReader(InputStreamReader(input, "UTF-8")).useLines { - it.forEach { line -> - content += line - } + content += it.reduce { acc, line -> acc + line } } } - return content } } diff --git a/example/build.gradle b/example/build.gradle index 2ef892b..168846b 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -2,15 +2,15 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - compileSdkVersion 24 - buildToolsVersion "24.0.2" + compileSdkVersion 25 + buildToolsVersion '25.0.3' defaultConfig { - applicationId "io.github.kbiakov.codeviewexample" + applicationId 'io.github.kbiakov.codeviewexample' minSdkVersion 15 - targetSdkVersion 24 + targetSdkVersion 25 versionCode 1 - versionName "1.0" + versionName '1.0' } buildTypes { release { @@ -24,7 +24,7 @@ android { } dependencies { - compile 'com.android.support:appcompat-v7:24.2.0' + compile 'com.android.support:appcompat-v7:25.3.1' compile project(path: ':codeview') compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" } diff --git a/example/src/main/java/io/github/kbiakov/codeviewexample/ListingsActivity.java b/example/src/main/java/io/github/kbiakov/codeviewexample/ListingsActivity.java index 1771daf..b1d8417 100644 --- a/example/src/main/java/io/github/kbiakov/codeviewexample/ListingsActivity.java +++ b/example/src/main/java/io/github/kbiakov/codeviewexample/ListingsActivity.java @@ -24,7 +24,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { final CodeView codeView = (CodeView) findViewById(R.id.code_view); - /** + /* * 1: set code content */ @@ -34,7 +34,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { // specify language for code listing codeView.setCode(getString(R.string.listing_py), "py"); - /** + /* * 2: working with options */ @@ -66,7 +66,7 @@ public void onCodeLineClicked(int n, @NotNull String line) { } })); - /** + /* * 3: color themes */ @@ -79,7 +79,7 @@ public void onCodeLineClicked(int n, @NotNull String line) { codeView.getOptions().setTheme(myTheme); - /** + /* * 4: custom adapter with footer views */ @@ -94,7 +94,7 @@ public void onCodeLineClicked(int n, @NotNull String line) { } }); - /** + /* * 5: diff adapter with footer views */ @@ -107,8 +107,7 @@ public void onCodeLineClicked(int n, @NotNull String line) { diffsAdapter.addFooterEntity(16, new DiffModel(getString(R.string.py_addition_16), true)); diffsAdapter.addFooterEntity(11, new DiffModel(getString(R.string.py_deletion_11), false)); - - /** + /* * 6: shortcut adapter with footer views */ diff --git a/example/src/main/res/layout/activity_listings.xml b/example/src/main/res/layout/activity_listings.xml index 442ae1d..57e5276 100644 --- a/example/src/main/res/layout/activity_listings.xml +++ b/example/src/main/res/layout/activity_listings.xml @@ -1,6 +1,7 @@ + android:layout_height="wrap_content" + app:animateOnStart="true"/> diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cb45e12..c1b0c03 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Aug 17 15:40:39 MSK 2016 +#Sat Aug 26 20:57:29 MSK 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip From 0c46245b73cb0dbc8cf4ce20b5275125c73410ff Mon Sep 17 00:00:00 2001 From: Kirill Biakov Date: Sun, 27 Aug 2017 00:14:57 +0300 Subject: [PATCH 2/2] Fixed tabs/spaces trimming --- .../java/io/github/kbiakov/codeview/Utils.kt | 16 +++- .../codeview/adapters/AbstractCodeAdapter.kt | 91 ++++++++----------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt b/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt index 1b94398..bb9ef52 100644 --- a/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt +++ b/codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt @@ -4,9 +4,11 @@ import android.content.Context import android.os.Handler import android.os.Looper import android.text.Html +import android.text.Spanned import android.util.TypedValue import java.io.BufferedReader import java.io.InputStreamReader +import java.util.* import java.util.concurrent.Executors object Const { @@ -46,6 +48,14 @@ fun spaceSplit(source: String) = source.split("\\s".toRegex()) */ fun extractLines(source: String) = listOf(*source.split("\n").toTypedArray()) +/** + * Slice list by index. + * + * @param idx Index to slice + * @return Pair of lists with head and tail + */ +fun List.slice(idx: Int) = Pair(this.subList(0, idx), this.subList(idx, this.lastIndex)) + /** * Get HTML from string. * @@ -55,9 +65,11 @@ fun extractLines(source: String) = listOf(*source.split("\n").toTypedArray()) @Suppress("deprecation") fun html(content: String) = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) - Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY) + Html.fromHtml(content.htmlSafe(), Html.FROM_HTML_MODE_LEGACY) else - Html.fromHtml(content) + Html.fromHtml(content.htmlSafe()) + +fun String.htmlSafe() = replace(" ", " ") object Thread { /** diff --git a/codeview/src/main/java/io/github/kbiakov/codeview/adapters/AbstractCodeAdapter.kt b/codeview/src/main/java/io/github/kbiakov/codeview/adapters/AbstractCodeAdapter.kt index e6decf3..d908c1c 100644 --- a/codeview/src/main/java/io/github/kbiakov/codeview/adapters/AbstractCodeAdapter.kt +++ b/codeview/src/main/java/io/github/kbiakov/codeview/adapters/AbstractCodeAdapter.kt @@ -1,5 +1,6 @@ package io.github.kbiakov.codeview.adapters +import android.annotation.SuppressLint import android.content.Context import android.support.v7.widget.RecyclerView import android.view.LayoutInflater @@ -55,17 +56,13 @@ abstract class AbstractCodeAdapter : RecyclerView.Adapter : RecyclerView.Adapter : RecyclerView.Adapter : RecyclerView.Adapter Unit) { - async() { + async { val language = options.language ?: classifyContent() highlighting(language, onReady) } @@ -159,10 +156,7 @@ abstract class AbstractCodeAdapter : RecyclerView.Adapter Unit) { options.code = code prepareCodeLines() - - ui { - onUpdated() - } + ui(onUpdated) } private fun monoTypeface() = MonoFontCache.getInstance(context).typeface @@ -187,19 +181,19 @@ abstract class AbstractCodeAdapter : RecyclerView.Adapter : RecyclerView.Adapter - val footerView = createFooter(context, entity, isFirst) + it.forEachIndexed { idx, entity -> + val footerView = createFooter(context, entity, idx == 0) holder.llLineFooter.addView(footerView) - isFirst = false } } } - private fun addExtraPadding(position: Int, holder: ViewHolder) { - if (position.isBorder()) { + private fun addExtraPadding(pos: Int, holder: ViewHolder) { + if (pos.isBorder()) { val dp8 = dpToPx(context, 8) - val topPadding = if (position.isJustFirst()) dp8 else 0 - val bottomPadding = if (position.isJustLast()) dp8 else 0 + val topPadding = if (pos.isJustFirst()) dp8 else 0 + val bottomPadding = if (pos.isJustLast()) dp8 else 0 holder.tvLineNum.setPadding(0, topPadding, 0, bottomPadding) holder.tvLineContent.setPadding(0, topPadding, 0, bottomPadding) } else { @@ -257,7 +249,10 @@ abstract class AbstractCodeAdapter : RecyclerView.Adapter, List>.linesToShow() = first + private fun Pair, List>.droppedLines() = second } /** @@ -265,18 +260,12 @@ abstract class AbstractCodeAdapter : RecyclerView.Adapter