Converts a simple html page in to A RecyclerView
with Native android widgets powered by Jsoup library and inspired by Medium Textview
Note this is under development and unstable
- Paragraph
- H1...H6
- Image
- Video
- Audio
- Ordered List
- Unordered List
- Description List
- Anchor Link
- IFrame
- Table
- DIV
val networkSource = NetworkSource("https://gist.githubusercontent.com/m7mdra/f22c62bc6941e08064b4fbceb4832a90/raw/ea8574d986635cf214541f1f5702ef37cc731aaf/article.html")
HtmlRecycler.Builder(this@MainActivity)
.setSource(networkSource)
.setAdapter(DefaultElementsAdapter(this@MainActivity)
{ element, i, view ->
}}).setRecyclerView(recyclerView)
.setLoadingCallback(object : HtmlRecycler.LoadCallback {
override fun onLoadingStart() {
progressBar.visibility = View.VISIBLE
}
override fun onLoaded(document: Document?) {
progressBar.visibility = View.GONE
}
})
.build()
the above code uses the existing implementation of DefaultElementsAdapter
which extends
ElementsAdapter
class which inherently is a RecylcerView Adpater
the DefaultElementsAdapter
uses a layout resources files defined by me but they not styled probably and are very buggy(especially the video, audio and iframe ones)
want to create your own adapter ? just simply extend ElementsAdapter
and override methods
class BetterImplementationThanTheAuthorsAdapter : ElementsAdapter() {
override fun onCreateElement(parent: ViewGroup, elementType: ElementType): RecyclerView.ViewHolder {
when (elementType) {
ElementType.Paragraph -> {
return ParagraphViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_paragarph, parent, false))
}
//.
// .
// .
//other elements defined here }
}
override fun onBindElement(holder: RecyclerView.ViewHolder, position: Int) {
val element = elements[position] //current element
if (holder is ParagraphViewHolder){
val paragraphElement = element as ParagraphElement
holder.paragraphText.text= paragraphElement.text
}
}
}
after that replace your adapter with the default implementation
HtmlRecycler.Builder(this)
.setSource(StringSource(Data.data))
.setAdapter(BetterImplementationThanTheAuthorsAdapter()) // this is a custom adapter
.setRecyclerView(recyclerView)
.build()
Data can come from different sources , the library support the following
- Assets
- File
- String
- Network (runs on
UI thread
by default so you have to run it on different thread or write your own Source Implementation )
simply implement the Source
interface which will return a Document
of the parsed Source
class FileSource(val file: File) : Source {
override fun get(): Document {
return Jsoup.parse(file, "UTF-8")
}
}
in DefaultElemetsAdapter
class at line #27 l i defined a higher-order-function in the constructor method (which dose the same as defining an interface) and on line #75 we envoke the method passing our element and the position of the clicked view.
Add it in your root build.gradle at the end of repositories: Gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.m7mdra:HtmlRecycler:0.1.1'
}
Maven
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.m7mdra</groupId>
<artifactId>HtmlRecycler</artifactId>
<version>0.1.1</version>
</dependency>
- Define a standard Layout styling.
- allow
NetworkSource
to run onUI thread
without crashing. - Support the following elements:
-
Table
-
Div
-
Section
-
- Test Element Extractors for different data sets.
- other thing that i come up with...
PR are welcome just use crtl+alt+L or (command + alt+L for mac ... idk if right) after every time your finish write code to format it.