Skip to content

Commit f2f48f2

Browse files
committed
Finished adapter customization, added ability to put custom footer view
1 parent b522c7b commit f2f48f2

File tree

7 files changed

+144
-93
lines changed

7 files changed

+144
-93
lines changed

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

Lines changed: 14 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import io.github.kbiakov.codeview.adapters.CodeWithNotesAdapter
1616
import io.github.kbiakov.codeview.highlight.ColorTheme
1717
import io.github.kbiakov.codeview.highlight.ColorThemeData
1818
import java.util.*
19-
import kotlin.reflect.KClass
2019

2120
/**
2221
* @class CodeView
@@ -35,7 +34,7 @@ import kotlin.reflect.KClass
3534
*
3635
* @author Kirill Biakov
3736
*/
38-
class CodeView<T> : RelativeLayout {
37+
class CodeView : RelativeLayout {
3938

4039
private val vPlaceholder: View
4140
private val vShadowRight: View
@@ -57,6 +56,11 @@ class CodeView<T> : RelativeLayout {
5756
* (and awaiting for build) or view was built & code is presented.
5857
*/
5958
private var state: ViewState
59+
set(newState) {
60+
if (newState == ViewState.PRESENTED)
61+
hidePlaceholder()
62+
field = newState
63+
}
6064

6165
/**
6266
* Default constructor.
@@ -99,53 +103,19 @@ class CodeView<T> : RelativeLayout {
99103
fun isPrepared() = state == ViewState.PREPARE
100104
fun isPresented() = state == ViewState.PRESENTED
101105

102-
/**
103-
* TODO
104-
*/
105-
private var AdapterClass: KClass<out AbstractCodeAdapter<T>>? = null
106-
107-
fun registerAdapterClass(adapterClass: KClass<out AbstractCodeAdapter<T>>) {
108-
if (state == ViewState.BUILD)
109-
AdapterClass = adapterClass
110-
else throw RuntimeException("CodeView is already registered with " +
111-
"${AdapterClass?.simpleName} class name. Please, check the build flow.")
112-
}
113-
114-
fun registerAdapterClass(adapterClass: Class<out AbstractCodeAdapter<T>>) =
115-
registerAdapterClass(adapterClass.kotlin)
116-
117106
/**
118107
* Accessor/mutator to reduce frequently used actions.
119108
*/
120-
private var adapter: AbstractCodeAdapter<T>
109+
var adapter: AbstractCodeAdapter<*>
121110
get() {
122-
return rvCodeContent.adapter as AbstractCodeAdapter<T>
111+
return rvCodeContent.adapter as AbstractCodeAdapter<*>
123112
}
124113
set(adapter) {
125-
rvCodeContent.adapter = adapter
126-
state = ViewState.PRESENTED
127-
}
128-
129-
/**
130-
* TODO
131-
*/
132-
private fun createAdapter(content: String) =
133-
(AdapterClass ?: CodeWithNotesAdapter::class)
134-
.constructors
135-
.first()
136-
.call(context, content)
137-
138-
/**
139-
* TODO
140-
*/
141-
private fun setupInitAdapter(content: String) {
142-
try {
143-
rvCodeContent.adapter = createAdapter(content)
144-
} catch (e: IllegalArgumentException) {
145-
throw IllegalArgumentException("You're registered ${AdapterClass?.simpleName}, " +
146-
"but default constructor with 2 params (context & code content) not found.")
114+
delayed { // to prevent UI overhead & initialization inconsistency
115+
rvCodeContent.adapter = adapter
116+
state = ViewState.PRESENTED
117+
}
147118
}
148-
}
149119

150120
// - Build processor
151121

@@ -156,7 +126,7 @@ class CodeView<T> : RelativeLayout {
156126
*
157127
* @param task Task to process
158128
*/
159-
private fun addTask(task: () -> Unit): CodeView<T> {
129+
private fun addTask(task: () -> Unit): CodeView {
160130
when (state) {
161131
ViewState.BUILD ->
162132
tasks.add(task)
@@ -237,25 +207,6 @@ class CodeView<T> : RelativeLayout {
237207
vShadowBottomContent.visibility = visibility
238208
}
239209

240-
/**
241-
* Add entities to code snippet as footer.
242-
*
243-
* @param entities Map of entities (line number -> list of entities)
244-
*/
245-
fun addFooterEntities(entities: HashMap<Int, List<T>>) = addTask {
246-
adapter.footerEntities = entities
247-
}
248-
249-
/**
250-
* Add footer entity to code line.
251-
*
252-
* @param num Line number
253-
* @param entity Entity content
254-
*/
255-
fun addFooterEntity(num: Int, entity: T) = addTask {
256-
adapter.addFooterEntity(num, entity)
257-
}
258-
259210
/**
260211
* Update code content if view was built or, finally, build code view.
261212
*
@@ -289,7 +240,7 @@ class CodeView<T> : RelativeLayout {
289240
state = ViewState.PREPARE
290241

291242
delayed {
292-
setupInitAdapter(content)
243+
rvCodeContent.adapter = CodeWithNotesAdapter(context, content)
293244
processBuildTasks()
294245
setupShadows()
295246
hidePlaceholder()

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

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import java.util.*
1919
/**
2020
* @class AbstractCodeAdapter
2121
*
22-
* Adapter for code view.
22+
* Basic adapter for code view.
2323
*
2424
* @author Kirill Biakov
2525
*/
@@ -103,7 +103,7 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
103103
mLines = lines
104104
}
105105

106-
// - User interaction interface
106+
// - Adapter interface
107107

108108
/**
109109
* Update code with new content.
@@ -156,6 +156,15 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
156156
}
157157
}
158158

159+
/**
160+
* Mapper from entity to footer view.
161+
*
162+
* @param context Context
163+
* @param entity Entity to init view
164+
* @return Footer view
165+
*/
166+
abstract fun createFooter(context: Context, entity: T): View
167+
159168
// - Helpers (for accessors)
160169

161170
private fun updateContent(codeLines: List<String>, onUpdated: () -> Unit) {
@@ -175,7 +184,7 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
175184
updateContent(lines, onReady)
176185
}
177186

178-
internal fun showAllBottomNote() = mContext.getString(R.string.show_all)
187+
private fun showAllBottomNote() = mContext.getString(R.string.show_all)
179188

180189
private fun monoTypeface() = MonoFontCache.getInstance(mContext).typeface
181190

@@ -206,13 +215,13 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
206215
}
207216

208217
setupLine(position, codeLine, holder)
209-
displayFooterEntities(position, holder)
218+
displayLineFooter(position, holder)
210219
addExtraPadding(position, holder)
211220
}
212221

213222
override fun getItemCount() = mLines.size
214223

215-
// Helpers (for view holder)
224+
// - Helpers (for view holder)
216225

217226
private fun setupLine(position: Int, line: String, holder: ViewHolder) {
218227
holder.tvLineContent.text = html(line)
@@ -227,7 +236,7 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
227236
}
228237
}
229238

230-
private fun displayFooterEntities(position: Int, holder: ViewHolder) {
239+
private fun displayLineFooter(position: Int, holder: ViewHolder) {
231240
val entityList = footerEntities[position]
232241

233242
holder.llLineFooter.removeAllViews()
@@ -243,40 +252,36 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
243252
footerView.setPadding(dpToPx(mContext, 46), if (isFirst) dp8 else 0, dp8, dp8)
244253

245254
holder.llLineFooter.addView(footerView)
255+
246256
isFirst = false
247257
}
248258
}
249259
}
250260

251-
abstract fun createFooter(context: Context, entity: T): View
252-
253261
private fun addExtraPadding(position: Int, holder: ViewHolder) {
254262
val dp8 = dpToPx(mContext, 8)
255263
val isFirst = position == 0
256264
val isLast = position == itemCount - 1
257265

258266
if (isFirst || isLast) {
259-
// holder.itemView.layoutParams.height = dp8 * 4
260-
261267
val topPadding = if (isFirst) dp8 else 0
262268
val bottomPadding = if (isLast) dp8 else 0
263269
holder.tvLineNum.setPadding(0, topPadding, 0, bottomPadding)
264270
holder.tvLineContent.setPadding(0, topPadding, 0, bottomPadding)
265271
} else {
266-
// holder.itemView.layoutParams.height = dp8 * 3
267-
268272
holder.tvLineNum.setPadding(0, 0, 0, 0)
269273
holder.tvLineContent.setPadding(0, 0, 0, 0)
270274
}
271-
272-
// TODO: measure height
273-
// holder.tvLineNum.layoutParams.height = holder.itemView.layoutParams.height
274275
}
275276

276277
companion object {
277278
internal const val MAX_SHORTCUT_LINES = 6
278279
}
279280

281+
/**
282+
* View holder for code adapter.
283+
* Stores all views related to code line layout.
284+
*/
280285
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
281286
var tvLineNum: TextView
282287
var tvLineContent: TextView

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import io.github.kbiakov.codeview.highlight.color
55
import io.github.kbiakov.codeview.views.LineNoteView
66

77
/**
8+
* @class CodeWithNotesAdapter
89
*
10+
* Default code content adapter.
11+
*
12+
* @author Kirill Biakov
913
*/
1014
class CodeWithNotesAdapter : AbstractCodeAdapter<String> {
1115
/**
@@ -14,14 +18,14 @@ class CodeWithNotesAdapter : AbstractCodeAdapter<String> {
1418
constructor(context: Context, content: String) : super(context, content)
1519

1620
/**
17-
* Add note to code line.
21+
* Create footer view.
1822
*
19-
* @param num Line number
23+
* @param context Context
2024
* @param entity Note content
2125
*/
2226
override fun createFooter(context: Context, entity: String) =
2327
LineNoteView.create(context,
24-
noteText = entity,
28+
text = entity,
2529
bgColor = colorTheme.bgNum.color(),
2630
textColor = colorTheme.noteColor.color())
2731
}

codeview/src/main/java/io/github/kbiakov/codeview/views/LineNoteView.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import android.content.Context
44
import android.widget.TextView
55

66
/**
7-
* Simple note view for code line.
7+
* @class LineNoteView
8+
*
9+
* Note view for code line. Default footer view.
810
*
911
* @author Kirill Biakov
1012
*/
@@ -15,15 +17,15 @@ class LineNoteView(context: Context?) : TextView(context) {
1517
* Simple factory method to create note view.
1618
*
1719
* @param context Context
18-
* @param noteText Note text
20+
* @param text Note text
1921
* @param bgColor Background color
2022
* @param textColor Text Color
2123
* @return Created line note view
2224
*/
23-
fun create(context: Context, noteText: String, bgColor: Int, textColor: Int): LineNoteView {
25+
fun create(context: Context, text: String, bgColor: Int, textColor: Int): LineNoteView {
2426
val noteView = LineNoteView(context)
2527
noteView.textSize = 12f
26-
noteView.text = noteText
28+
noteView.text = text
2729
noteView.setTextColor(textColor)
2830
noteView.setBackgroundColor(bgColor)
2931

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.github.kbiakov.codeviewexample;
2+
3+
import android.content.Context;
4+
import android.view.LayoutInflater;
5+
import android.view.View;
6+
import android.widget.TextView;
7+
8+
import org.jetbrains.annotations.NotNull;
9+
10+
import io.github.kbiakov.codeview.adapters.AbstractCodeAdapter;
11+
12+
public class CustomAdapter extends AbstractCodeAdapter<CustomAdapter.CustomModel> {
13+
14+
public CustomAdapter(@NotNull Context context, @NotNull String content) {
15+
super(context, content, true, 10, context.getString(R.string.show_all), null);
16+
}
17+
18+
@NotNull
19+
@Override
20+
public View createFooter(@NotNull Context context, CustomModel entity) {
21+
View footerView = LayoutInflater.from(context).inflate(R.layout.custom_footer, null);
22+
((TextView) footerView.findViewById(R.id.tv_footer_title)).setText(entity.firstName);
23+
((TextView) footerView.findViewById(R.id.tv_footer_description)).setText(entity.lastName);
24+
return footerView;
25+
}
26+
27+
public static class CustomModel {
28+
private String firstName;
29+
private String lastName;
30+
31+
public CustomModel(String firstName, String lastName) {
32+
this.firstName = firstName;
33+
this.lastName = lastName;
34+
}
35+
36+
public String getFirstName() {
37+
return firstName;
38+
}
39+
40+
public String getLastName() {
41+
return lastName;
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)