@@ -12,6 +12,8 @@ import android.widget.TextView
1212import io.github.kbiakov.codeview.*
1313import io.github.kbiakov.codeview.Thread.async
1414import io.github.kbiakov.codeview.Thread.ui
15+ import io.github.kbiakov.codeview.adapters.AbstractCodeAdapter.ViewHolderType.Companion.BordersCount
16+ import io.github.kbiakov.codeview.adapters.AbstractCodeAdapter.ViewHolderType.Companion.LineStartIdx
1517import io.github.kbiakov.codeview.classifier.CodeClassifier
1618import io.github.kbiakov.codeview.classifier.CodeProcessor
1719import io.github.kbiakov.codeview.highlight.*
@@ -174,33 +176,38 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
174176 val tvLineContent = lineView.findViewById(R .id.tv_line_content) as TextView
175177 tvLineContent.typeface = options.font
176178
177- val holder = ViewHolder (lineView)
178- holder.setIsRecyclable(false )
179- return holder
179+ val isLine = viewType == ViewHolderType .Line .viewType
180+ val lineViewHeight = if (isLine) R .dimen.line_height else R .dimen.line_border_height
181+ lineView.layoutParams.height = context.resources.getDimension(lineViewHeight).toInt()
182+
183+ if (isLine) {
184+ val holder = LineViewHolder (lineView)
185+ holder.setIsRecyclable(false )
186+ return holder
187+ } else {
188+ return BorderViewHolder (lineView)
189+ }
180190 }
181191
182192 override fun onBindViewHolder (holder : ViewHolder , pos : Int ) {
183- val codeLine = lines[pos]
184- holder.mItem = codeLine
185-
186- options.lineClickListener?.let {
187- holder.itemView.setOnClickListener {
188- options.lineClickListener?.onCodeLineClicked(pos, codeLine)
193+ if (holder is LineViewHolder ) {
194+ val lineNum = pos - LineStartIdx
195+ val lineCode = lines[lineNum]
196+ holder.mItem = lineCode
197+
198+ options.lineClickListener?.let {
199+ holder.itemView.setOnClickListener {
200+ options.lineClickListener?.onCodeLineClicked(lineNum, lineCode)
201+ }
189202 }
203+ setupLine(lineNum, lineCode, holder)
204+ displayLineFooter(lineNum, holder)
190205 }
191-
192- setupLine(pos, codeLine, holder)
193- displayLineFooter(pos, holder)
194- addExtraPadding(pos, holder)
195206 }
196207
197- override fun getItemCount () = lines.size
208+ override fun getItemCount () = lines.size + BordersCount // lines + borders
198209
199- private fun Int.isFirst () = this == 0
200- private fun Int.isLast () = this == itemCount - 1
201- private fun Int.isJustFirst () = isFirst() && ! isLast()
202- private fun Int.isJustLast () = isLast() && ! isFirst()
203- private fun Int.isBorder () = isFirst() || isLast()
210+ override fun getItemViewType (pos : Int ) = ViewHolderType .get(pos, itemCount)
204211
205212 // - Helpers (for view holder)
206213
@@ -209,7 +216,7 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
209216 holder.tvLineContent.text = html(line)
210217 holder.tvLineContent.setTextColor(options.theme.noteColor.color())
211218
212- if (options.shortcut && pos == MAX_SHORTCUT_LINES ) {
219+ if (options.shortcut && pos == MaxShortcutLines ) {
213220 holder.tvLineNum.textSize = 10f
214221 holder.tvLineNum.text = context.getString(R .string.dots)
215222 } else {
@@ -233,31 +240,38 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
233240 }
234241 }
235242
236- private fun addExtraPadding (pos : Int , holder : ViewHolder ) {
237- if (pos.isBorder()) {
238- val dp8 = dpToPx(context, 8 )
239- val topPadding = if (pos.isJustFirst()) dp8 else 0
240- val bottomPadding = if (pos.isJustLast()) dp8 else 0
241- holder.tvLineNum.setPadding(0 , topPadding, 0 , bottomPadding)
242- holder.tvLineContent.setPadding(0 , topPadding, 0 , bottomPadding)
243- } else {
244- holder.tvLineNum.setPadding(0 , 0 , 0 , 0 )
245- holder.tvLineContent.setPadding(0 , 0 , 0 , 0 )
246- }
247- }
248-
249243 companion object {
250- private const val MAX_SHORTCUT_LINES = 6
244+ private const val MaxShortcutLines = 6
251245
252246 private fun Pair <List <String >, List<String>>.linesToShow () = first
253247 private fun Pair <List <String >, List<String>>.droppedLines () = second
254248 }
255249
250+ // - ViewHolder
251+
252+ enum class ViewHolderType (val viewType : Int ) {
253+ Line (0 ), Border (1 );
254+
255+ companion object {
256+ const val LineStartIdx = 1
257+ const val BordersCount = 2
258+
259+ fun Int.lineEndIdx () = this - BordersCount
260+
261+ fun get (pos : Int , n : Int ) = when (pos) {
262+ in LineStartIdx .. n.lineEndIdx() ->
263+ ViewHolderType .Line .viewType
264+ else ->
265+ ViewHolderType .Border .viewType
266+ }
267+ }
268+ }
269+
256270 /* *
257271 * View holder for code adapter.
258272 * Stores all views related to code line layout.
259273 */
260- class ViewHolder (itemView : View ) : RecyclerView.ViewHolder(itemView) {
274+ open class ViewHolder (itemView : View ) : RecyclerView.ViewHolder(itemView) {
261275 val tvLineNum = itemView.findViewById(R .id.tv_line_num) as TextView
262276 val tvLineContent = itemView.findViewById(R .id.tv_line_content) as TextView
263277 val llLineFooter = itemView.findViewById(R .id.ll_line_footer) as LinearLayout
@@ -266,6 +280,14 @@ abstract class AbstractCodeAdapter<T> : RecyclerView.Adapter<AbstractCodeAdapter
266280
267281 override fun toString () = " ${super .toString()} '$mItem '"
268282 }
283+
284+ class LineViewHolder (itemView : View ) : ViewHolder(itemView)
285+
286+ /* *
287+ * View holder for padding.
288+ * Stores all views related to code line layout.
289+ */
290+ class BorderViewHolder (itemView : View ) : ViewHolder(itemView)
269291}
270292
271293/* *
0 commit comments