Rendering markdown into a singleDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/tutosrive/mcbfc/llms.txt
Use this file to discover all available pages before exploring further.
TextView is the simplest way to display formatted text on Android, but it has a hard ceiling: every node in the document is measured and drawn at once, which causes noticeable jank when the document is long. MarkwonAdapter solves this by mapping each top-level CommonMark AST node to its own RecyclerView item. Android can then recycle the views for nodes that scroll off screen, keeping memory usage flat and frame rate consistent regardless of document length.
How MarkwonAdapter works
When you calladapter.setMarkdown(markwon, text), Markwon parses the raw string into a CommonMark AST and walks its top-level nodes. For each node type it finds a registered Entry — a paired ViewHolder factory and binder — and uses that entry to create and populate a list item. Node types with no registered entry fall back to the default text Entry supplied via builderTextViewIsRoot(layoutId), which renders the node into a plain TextView.
Because every node is its own list item, RecyclerView’s built-in view recycling handles the heavy lifting: a heading, a paragraph, a blockquote, and a fenced code block each get the right view type and are reused as the user scrolls.
The markdown wrapper class
The markdown class encapsulates all Markwon and RecyclerView wiring in a single, reusable object.
markdown.kt
Markwon.builder(ctx).build()— constructs the coreMarkwoninstance. Additional plugins (images, syntax highlighting, tables, etc.) can be chained here beforebuild().MarkwonAdapter.builderTextViewIsRoot(R.layout.adapter_default_entry)— creates anMarkwonAdapter.Builderthat usesadapter_default_entry.xmlas the default layout. That layout is a singleTextViewwhose root is the item view, soMarkwonAdaptercan callMarkwon.setParsedMarkdowndirectly on it for paragraphs, headings, and all other non-code nodes..include<FencedCodeBlock>(FencedCodeBlock::class.java, BlockCodeEntry(ctx))— registersBlockCodeEntryas theEntryfor everyFencedCodeBlocknode. When the adapter encounters a fenced code block in the AST it delegates creation and binding to this entry instead of the defaultTextViewpath.LinearLayoutManager+DefaultItemAnimator— standardRecyclerViewwiring.LinearLayoutManagerstacks items vertically;DefaultItemAnimatorprovides the default add/remove animations.sett(text)— the single public method callers use to display new markdown. It callsadapter.setMarkdown(mark, text)to re-parse and diff the node list, thennotifyDataSetChanged()to tell theRecyclerViewto rebind all visible items.
Setting up the RecyclerView in XML
TheRecyclerView lives inside a LinearLayout in activity_main.xml. Its id recyclerMark is the reference point used in code to attach the adapter.
activity_main.xml
EditText above the RecyclerView so you can paste text into the field and verify the copy button works — a useful debug affordance that can be removed in production.
Binding markdown in an Activity
MainActivity.onCreate creates the markdown wrapper and immediately loads a test document from raw resources:
MainActivity.kt
getRawTest() opens res/raw/test_markdown as a buffered stream and returns its full contents as a String. You can replace this call with any string source — a network response, a local file, or a user-supplied input.