Skip to content

Commit a25d487

Browse files
committed
Flag to control highlighting animation
1 parent 473b8c3 commit a25d487

File tree

4 files changed

+174
-132
lines changed

4 files changed

+174
-132
lines changed

codeview/src/main/java/io/github/kbiakov/codeview/CodeView.kt

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context,
2828
*/
2929
init {
3030
inflate(context, R.layout.layout_code_view, this)
31-
checkInitialAnimation(attrs)
31+
checkStartAnimation(attrs)
3232

3333
// TODO: add shadow color customization
3434
vShadows = listOf(
@@ -42,30 +42,37 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context,
4242
vCodeList.isNestedScrollingEnabled = true
4343
}
4444

45-
private fun checkInitialAnimation(attrs: AttributeSet) {
46-
if (visibility == VISIBLE && isAnimateOnStart(context, attrs)) {
45+
private fun checkStartAnimation(attrs: AttributeSet) {
46+
if (visibility == VISIBLE && attrs.isAnimateOnStart(context)) {
4747
alpha = Const.Alpha.Invisible
4848

4949
animate()
5050
.setDuration(Const.DefaultDelay * 5)
5151
.alpha(Const.Alpha.Initial)
52-
} else {
52+
} else
5353
alpha = Const.Alpha.Initial
54-
}
54+
}
55+
56+
private fun AbstractCodeAdapter<*>.checkHighlightAnimation(action: () -> Unit) {
57+
if (options.animateOnHighlight) {
58+
animate()
59+
.setDuration(Const.DefaultDelay * 2)
60+
.alpha(Const.Alpha.AlmostInvisible)
61+
delayed {
62+
animate().alpha(Const.Alpha.Visible)
63+
action()
64+
}
65+
} else action()
5566
}
5667

5768
/**
5869
* Highlight code with defined programming language.
5970
* It holds the placeholder on view until code is not highlighted.
6071
*/
6172
private fun highlight() {
62-
getAdapter()?.highlight {
63-
animate()
64-
.setDuration(Const.DefaultDelay * 2)
65-
.alpha(.1f)
66-
delayed {
67-
animate().alpha(Const.Alpha.Visible)
68-
getAdapter()?.notifyDataSetChanged()
73+
getAdapter()?.apply {
74+
highlight {
75+
checkHighlightAnimation(this::notifyDataSetChanged)
6976
}
7077
}
7178
}
@@ -124,6 +131,12 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context,
124131
getAdapter()?.options = options
125132
}
126133

134+
fun updateOptions(): Options {
135+
val options = getOptions() ?: getOptionsOrDefault()
136+
updateOptions(options)
137+
return options
138+
}
139+
127140
// - Adapter
128141

129142
/**
@@ -178,8 +191,8 @@ class CodeView(context: Context, attrs: AttributeSet) : RelativeLayout(context,
178191

179192
companion object {
180193

181-
private fun isAnimateOnStart(context: Context, attr: AttributeSet): Boolean {
182-
context.theme.obtainStyledAttributes(attr, R.styleable.CodeView, 0, 0).apply {
194+
private fun AttributeSet.isAnimateOnStart(context: Context): Boolean {
195+
context.theme.obtainStyledAttributes(this, R.styleable.CodeView, 0, 0).apply {
183196
val flag = getBoolean(R.styleable.CodeView_animateOnStart, false)
184197
recycle()
185198
return@isAnimateOnStart flag

codeview/src/main/java/io/github/kbiakov/codeview/Utils.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ object Const {
1616
val DefaultDelay = 250L
1717

1818
object Alpha {
19+
val Visible = 1f
1920
val Initial = 0.7f
21+
22+
val AlmostInvisible = 0.1f
2023
val Invisible = 0f
21-
val Visible = 1f
2224
}
2325
}
2426

codeview/src/main/java/io/github/kbiakov/codeview/adapters/AbstractCodeAdapter.kt

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,11 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
191191
override fun onBindViewHolder(holder: ViewHolder, pos: Int) {
192192
if (holder is LineViewHolder) {
193193
val num = pos - LineStartIdx
194-
val line = lines[num]
195-
holder.mItem = line
194+
holder.mItem = lines[num]
196195

197-
options.lineClickListener?.let {
198-
holder.itemView.setOnClickListener {
199-
options.lineClickListener?.onCodeLineClicked(num, line)
200-
}
201-
}
202-
setupLine(num, line, holder)
203-
displayLineFooter(num, holder)
196+
bindClickListener(num, holder)
197+
setupContent(num, holder)
198+
displayFooter(num, holder)
204199
}
205200
}
206201

@@ -210,24 +205,36 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
210205

211206
// - Helpers (for view holder)
212207

208+
private fun bindClickListener(pos: Int, holder: ViewHolder) {
209+
options.lineClickListener?.let {
210+
holder.itemView.setOnClickListener {
211+
options.lineClickListener?.onCodeLineClicked(pos, lines[pos])
212+
}
213+
}
214+
}
215+
213216
@SuppressLint("SetTextI18n")
214-
private fun setupLine(pos: Int, line: String, holder: ViewHolder) {
215-
val fontSize = options.format.fontSize
216-
217-
holder.tvLineContent.textSize = fontSize
218-
holder.tvLineContent.text = html(line)
219-
holder.tvLineContent.setTextColor(options.theme.noteColor.color())
220-
221-
if (options.shortcut && pos == MaxShortcutLines) {
222-
holder.tvLineNum.textSize = fontSize * Format.ShortcutScale
223-
holder.tvLineNum.text = context.getString(R.string.dots)
224-
} else {
225-
holder.tvLineNum.textSize = fontSize
226-
holder.tvLineNum.text = "${pos + 1}"
217+
private fun setupContent(pos: Int, holder: ViewHolder) {
218+
holder.apply {
219+
val fontSize = options.format.fontSize
220+
tvLineNum.apply {
221+
if (!options.shortcut || pos < MaxShortcutLines) {
222+
text = "${pos + 1}"
223+
textSize = fontSize
224+
} else {
225+
text = context.getString(R.string.dots)
226+
textSize = fontSize * Format.ShortcutScale
227+
}
228+
}
229+
tvLineContent.apply {
230+
text = html(lines[pos])
231+
textSize = fontSize
232+
setTextColor(options.theme.noteColor.color())
233+
}
227234
}
228235
}
229236

230-
private fun displayLineFooter(pos: Int, holder: ViewHolder) {
237+
private fun displayFooter(pos: Int, holder: ViewHolder) {
231238
val entityList = footerEntities[pos]
232239

233240
holder.llLineFooter.removeAllViews()
@@ -301,6 +308,9 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
301308
* @param code Code content
302309
* @param language Programming language to highlight
303310
* @param theme Color theme
311+
* @param font Font typeface
312+
* @param format How much space is content took?
313+
* @param animateOnHighlight Is animate on highlight?
304314
* @param shadows Is border shadows needed?
305315
* @param maxLines Max lines to show (when limit is reached, rest is dropped)
306316
* @param shortcut Do you want to show shortcut of code listing?
@@ -316,6 +326,7 @@ data class Options(
316326
var theme: ColorThemeData = ColorTheme.DEFAULT.theme(),
317327
var font: Typeface = FontCache.get(context).getTypeface(context),
318328
var format: Format = Format.Compact,
329+
var animateOnHighlight: Boolean = true,
319330
var shadows: Boolean = false,
320331
var shortcut: Boolean = false,
321332
var shortcutNote: String = context.getString(R.string.show_all),
@@ -373,6 +384,21 @@ data class Options(
373384
withFont(font)
374385
}
375386

387+
fun withFormat(format: Format): Options {
388+
this.format = format
389+
return this
390+
}
391+
392+
fun animateOnHighlight(): Options {
393+
this.animateOnHighlight = true
394+
return this
395+
}
396+
397+
fun disableHighlightAnimation(): Options {
398+
this.animateOnHighlight = false
399+
return this
400+
}
401+
376402
fun withShadows(): Options {
377403
this.shadows = true
378404
return this

0 commit comments

Comments
 (0)