@@ -3,17 +3,18 @@ package io.github.kbiakov.codeview
3
3
import android.animation.Animator
4
4
import android.animation.AnimatorListenerAdapter
5
5
import android.content.Context
6
- import android.os.Handler
7
6
import android.support.v7.widget.LinearLayoutManager
8
7
import android.support.v7.widget.RecyclerView
9
8
import android.util.AttributeSet
10
9
import android.view.LayoutInflater
11
10
import android.view.View
12
11
import android.view.ViewPropertyAnimator
13
12
import android.widget.RelativeLayout
13
+ import io.github.kbiakov.codeview.adapters.AbstractCodeAdapter
14
+ import io.github.kbiakov.codeview.Thread.delayed
15
+ import io.github.kbiakov.codeview.adapters.CodeWithNotesAdapter
14
16
import io.github.kbiakov.codeview.highlight.ColorTheme
15
17
import io.github.kbiakov.codeview.highlight.ColorThemeData
16
- import io.github.kbiakov.codeview.highlight.color
17
18
import java.util.*
18
19
19
20
/* *
@@ -55,7 +56,15 @@ class CodeView : RelativeLayout {
55
56
* (and awaiting for build) or view was built & code is presented.
56
57
*/
57
58
private var state: ViewState
59
+ set(newState) {
60
+ if (newState == ViewState .PRESENTED )
61
+ hidePlaceholder()
62
+ field = newState
63
+ }
58
64
65
+ /* *
66
+ * Default constructor.
67
+ */
59
68
constructor (context: Context , attrs: AttributeSet ) : super (context, attrs) {
60
69
val inflater = context.getSystemService(Context .LAYOUT_INFLATER_SERVICE ) as LayoutInflater
61
70
inflater.inflate(R .layout.layout_code_view, this , true )
@@ -69,13 +78,13 @@ class CodeView : RelativeLayout {
69
78
rvCodeContent.layoutManager = LinearLayoutManager (context)
70
79
rvCodeContent.isNestedScrollingEnabled = true
71
80
72
- tasks = LinkedList ()
73
-
74
81
state = ViewState .BUILD
82
+
83
+ tasks = LinkedList ()
75
84
}
76
85
77
86
/* *
78
- * Code view states .
87
+ * Code view state to control build flow .
79
88
*/
80
89
enum class ViewState {
81
90
BUILD ,
@@ -84,22 +93,28 @@ class CodeView : RelativeLayout {
84
93
}
85
94
86
95
/* *
87
- * Public getter for accessing view state.
88
- * It may be useful if code view state is unknown.
89
- * If code view was built it is not safe to use operations chaining.
96
+ * Public getters for checking view state.
97
+ * May be useful when code view state is unknown.
98
+ * If view was built it is unsafe to use operations chaining.
99
+ *
100
+ * @return Result of state check
90
101
*/
91
- fun getState () = state
102
+ fun isBuilding () = state == ViewState .BUILD
103
+ fun isPrepared () = state == ViewState .PREPARE
104
+ fun isPresented () = state == ViewState .PRESENTED
92
105
93
106
/* *
94
107
* Accessor/mutator to reduce frequently used actions.
95
108
*/
96
- var adapter: CodeContentAdapter
109
+ var adapter: AbstractCodeAdapter < * >
97
110
get() {
98
- return rvCodeContent.adapter as CodeContentAdapter
111
+ return rvCodeContent.adapter as AbstractCodeAdapter < * >
99
112
}
100
113
set(adapter) {
101
- rvCodeContent.adapter = adapter
102
- state = ViewState .PRESENTED
114
+ delayed { // prevent UI overhead & initialization inconsistency
115
+ rvCodeContent.adapter = adapter
116
+ state = ViewState .PRESENTED
117
+ }
103
118
}
104
119
105
120
// - Build processor
@@ -116,7 +131,7 @@ class CodeView : RelativeLayout {
116
131
ViewState .BUILD ->
117
132
tasks.add(task)
118
133
ViewState .PREPARE ->
119
- Thread . delayed(task)
134
+ delayed(body = task)
120
135
ViewState .PRESENTED ->
121
136
task()
122
137
}
@@ -180,6 +195,13 @@ class CodeView : RelativeLayout {
180
195
adapter.codeListener = listener
181
196
}
182
197
198
+ /* *
199
+ * Remove code listener.
200
+ */
201
+ fun removeCodeListener () = addTask {
202
+ adapter.codeListener = null
203
+ }
204
+
183
205
/* *
184
206
* Control shadows visibility to provide more sensitive UI.
185
207
*
@@ -202,7 +224,7 @@ class CodeView : RelativeLayout {
202
224
ViewState .BUILD ->
203
225
build(content)
204
226
ViewState .PREPARE ->
205
- Thread . delayed {
227
+ delayed {
206
228
update(content)
207
229
}
208
230
ViewState .PRESENTED ->
@@ -224,8 +246,8 @@ class CodeView : RelativeLayout {
224
246
measurePlaceholder(linesCount)
225
247
state = ViewState .PREPARE
226
248
227
- Thread . delayed {
228
- rvCodeContent.adapter = CodeContentAdapter (context, content)
249
+ delayed {
250
+ rvCodeContent.adapter = CodeWithNotesAdapter (context, content)
229
251
processBuildTasks()
230
252
setupShadows()
231
253
hidePlaceholder()
@@ -264,13 +286,13 @@ class CodeView : RelativeLayout {
264
286
val lineHeight = dpToPx(context, 24 )
265
287
val topPadding = dpToPx(context, 8 )
266
288
267
- // double padding (top & bottom) for big view , one is enough for small
289
+ // double padding (top & bottom), one is enough for single line view
268
290
val padding = (if (linesCount > 1 ) 2 else 1 ) * topPadding
269
291
270
292
val height = linesCount * lineHeight + padding
271
293
272
- vPlaceholder.layoutParams = RelativeLayout . LayoutParams (
273
- RelativeLayout . LayoutParams .MATCH_PARENT , height)
294
+ vPlaceholder.layoutParams = LayoutParams (
295
+ LayoutParams .MATCH_PARENT , height)
274
296
vPlaceholder.visibility = View .VISIBLE
275
297
}
276
298
@@ -296,16 +318,9 @@ class CodeView : RelativeLayout {
296
318
* Provides listener to code line clicks.
297
319
*/
298
320
interface OnCodeLineClickListener {
299
- fun onCodeLineClicked (n : Int )
321
+ fun onCodeLineClicked (n : Int , line : String )
300
322
}
301
323
302
- /* *
303
- * Extension for delayed block call.
304
- *
305
- * @param body Operation body
306
- */
307
- fun Thread.delayed (body : () -> Unit ) = Handler ().postDelayed(body, 150 )
308
-
309
324
/* *
310
325
* More readable form for animation listener (hi, iOS & Cocoa Touch!).
311
326
*
0 commit comments