aboutsummaryrefslogtreecommitdiff
path: root/about
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-08-03 15:18:20 -0700
committerGitHub <noreply@github.com>2017-08-03 15:18:20 -0700
commitbafc1996d803862d30a2c7d0c402d30c79c4f647 (patch)
tree5456960a330d7890ac43e1193a80f1db670a8b06 /about
parent84b9d3b40e342dc7715c5af13d102bb98529b0fb (diff)
downloadkau-bafc1996d803862d30a2c7d0c402d30c79c4f647.tar.gz
kau-bafc1996d803862d30a2c7d0c402d30c79c4f647.tar.bz2
kau-bafc1996d803862d30a2c7d0c402d30c79c4f647.zip
3.2.2 - Create faq parser and update sample (#19)3.2.3
* Test emulator * Update readme * Update fastadapter and about listing * Make faq parser asynchronous * Modularize about panels * Add basis for faq * Test and finalize the faq panel * Update readme * Update changelog * Remove emulator for now * Update sample
Diffstat (limited to 'about')
-rw-r--r--about/README.md9
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt184
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt198
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt33
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt12
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt86
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt34
-rw-r--r--about/src/main/res/layout/kau_iitem_faq.xml37
-rw-r--r--about/src/main/res/values/strings.xml1
-rw-r--r--about/src/main/res/values/strings_about.xml2
10 files changed, 441 insertions, 155 deletions
diff --git a/about/README.md b/about/README.md
index e7012b5..77a329d 100644
--- a/about/README.md
+++ b/about/README.md
@@ -11,9 +11,12 @@ and adds on the power of [About Libraries](https://github.com/mikepenz/AboutLibr
This activity can be easily added by extending `AboutActivityBase`.
Everything is already prepared, but you can modify the theme or other components through the config DSL or through the open functions.
-There are also numerous iitem cards already prepared (in this submodule and from `:adapter`)if you wish to add that in your main view.
-You may also easily launch the activity through the simple binder:
+If you wish to add custom panels, you will need to implement `AboutPanelContract`.
+The most common usage is with a recyclerview, so there is a simplified class `AboutPanelRecycler` that you may extend as well.
+Note that the viewpager by default will keep all panels in memory, so it's best to not have too many pages with expensive interactions.
+
+You may easily launch the activity through the binder:
```
Activity.kauLaunchAbout(YourClass::class.java)
```
@@ -22,7 +25,7 @@ Be sure to include the activity in your Manifest and have it extend `Kau.About`,
## Proguard
-Without auto detect, KAU about will retain the classes containing the lib strings by default.
+Without auto detection, KAU about will retain the classes containing the lib strings by default.
If you use proguard with auto detect, make sure to retain all R classes to make it possible
```
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
index 61a3bb2..442821f 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
@@ -4,8 +4,6 @@ import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v4.view.PagerAdapter
import android.support.v4.view.ViewPager
-import android.support.v7.app.AppCompatActivity
-import android.support.v7.widget.RecyclerView
import android.transition.TransitionInflater
import android.view.LayoutInflater
import android.view.View
@@ -13,19 +11,15 @@ import android.view.ViewGroup
import ca.allanwang.kau.adapters.FastItemThemedAdapter
import ca.allanwang.kau.adapters.ThemableIItemColors
import ca.allanwang.kau.adapters.ThemableIItemColorsDelegate
-import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
-import ca.allanwang.kau.animators.KauAnimator
-import ca.allanwang.kau.iitems.HeaderIItem
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout
import ca.allanwang.kau.ui.widgets.InkPageIndicator
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.AnimHolder
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.dimenPixelSize
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.entity.Library
import com.mikepenz.fastadapter.IItem
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
-import java.security.InvalidParameterException
/**
* Created by Allan Wang on 2017-06-28.
@@ -38,26 +32,21 @@ import java.security.InvalidParameterException
* Note that for the auto detection to work, the R fields must be excluded from Proguard
* Manual lib listings and other extra modifications can be done so by overriding the open functions
*/
-abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Configs.() -> Unit = {}) : KauBaseActivity(), ViewPager.OnPageChangeListener {
+abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilder: Configs.() -> Unit = {}) : KauBaseActivity(), ViewPager.OnPageChangeListener {
+
+ private val draggableFrame: ElasticDragDismissFrameLayout by bindView(R.id.about_draggable_frame)
+ private val pager: ViewPager by bindView(R.id.about_pager)
+ private val indicator: InkPageIndicator by bindView(R.id.about_indicator)
+
+ val currentPage
+ get() = pager.currentItem
- val draggableFrame: ElasticDragDismissFrameLayout by bindView(R.id.about_draggable_frame)
- val pager: ViewPager by bindView(R.id.about_pager)
- val indicator: InkPageIndicator by bindView(R.id.about_indicator)
/**
* Holds some common configurations that may be added directly from the constructor
* Applied lazily since it needs the context to fetch resources
*/
val configs: Configs by lazy { Configs().apply { configBuilder() } }
- /**
- * Number of pages in the adapter
- * Defaults to just the main view and lib view
- */
- open val pageCount: Int = 2
- /**
- * Page position for the libs
- * This is generated automatically if [inflateLibPage] is called
- */
- private var libPage: Int = -2
+
/**
* Holds that status of each page
* 0 means nothing has happened
@@ -65,98 +54,65 @@ abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Confi
* The rest is up to you
*/
lateinit var pageStatus: IntArray
- /**
- * Holds the lib items once they are fetched asynchronously
- */
- var libItems: List<LibraryIItem>? = null
- /**
- * Holds the adapter for the library page; this is generated later because it uses the config colors
- */
- lateinit var libAdapter: FastItemThemedAdapter<IItem<*, *>>
- /**
- * Global reference of the library recycler
- * This is set by default through [inflateLibPage] and is used to stop scrolling
- * When the draggable frame exits
- * It is not required, hence its nullability
- */
- private var libRecycler: RecyclerView? = null
+
+ val panels: List<AboutPanelContract> by lazy {
+ val defaultPanels = mutableListOf(AboutPanelMain(), AboutPanelLibs())
+ if (configs.faqXmlRes != -1) defaultPanels.add(AboutPanelFaqs())
+ defaultPanels
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.kau_activity_about)
- pageStatus = IntArray(pageCount)
- libAdapter = FastItemThemedAdapter(configs)
- LibraryIItem.bindClickEvents(libAdapter)
+ pageStatus = IntArray(panels.size)
+ pageStatus[0] = 2 //the first page is instantly visible
if (configs.textColor != null) indicator.setColour(configs.textColor!!)
with(pager) {
adapter = AboutPagerAdapter()
pageMargin = dimenPixelSize(R.dimen.kau_spacing_normal)
+ offscreenPageLimit = panels.size - 1
addOnPageChangeListener(this@AboutActivityBase)
}
indicator.setViewPager(pager)
draggableFrame.addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(this) {
override fun onDragDismissed() {
window.returnTransition = TransitionInflater.from(this@AboutActivityBase)
- .inflateTransition(if (draggableFrame.translationY > 0) configs.transitionExitBottom else configs.transitionExitTop)
-
- libRecycler?.stopScroll()
+ .inflateTransition(if (draggableFrame.translationY > 0) R.transition.kau_exit_slide_bottom else R.transition.kau_exit_slide_top)
+ panels[currentPage].recycler?.stopScroll()
finishAfterTransition()
}
})
+ panels.forEachIndexed { index, contract -> contract.loadItems(this, index) }
}
- inner class Configs : ThemableIItemColors by ThemableIItemColorsDelegate() {
+ class Configs : ThemableIItemColors by ThemableIItemColorsDelegate() {
var cutoutTextRes: Int = -1
var cutoutText: String? = null
var cutoutDrawableRes: Int = -1
var cutoutDrawable: Drawable? = null
var cutoutForeground: Int? = null
- var libPageTitleRes: Int = -1
- var libPageTitle: String? = string(R.string.kau_about_libraries_intro) //This is in the string by default since it's lower priority
-
- var transitionExitTop: Int = R.transition.kau_exit_slide_top
- var transitionExitBottom: Int = R.transition.kau_exit_slide_bottom
- }
-
- /**
- * Method to fetch the library list
- * This is fetched asynchronously and you may override it to customize the list
- */
- open fun getLibraries(libs: Libs): List<Library> = libs.prepareLibraries(this, null, null, true, true)!!
-
- /**
- * Gets the view associated with the given page position
- * Keep in mind that when inflating, do NOT add the view to the viewgroup
- * Use layoutInflater.inflate(id, parent, false)
- */
- open fun getPage(position: Int, layoutInflater: LayoutInflater, parent: ViewGroup): View {
- return when (position) {
- 0 -> inflateMainPage(layoutInflater, parent, position)
- pageCount - 1 -> inflateLibPage(layoutInflater, parent, position)
- else -> throw InvalidParameterException()
- }
- }
-
- /**
- * Create the main view with the cutout
- */
- open fun inflateMainPage(layoutInflater: LayoutInflater, parent: ViewGroup, position: Int): View {
- val fastAdapter = FastItemThemedAdapter<IItem<*, *>>(configs)
- val recycler = fullLinearRecycler(fastAdapter)
- fastAdapter.add(CutoutIItem {
- with(configs) {
- text = string(cutoutTextRes, cutoutText)
- drawable = drawable(cutoutDrawableRes, cutoutDrawable)
- if (configs.cutoutForeground != null) foregroundColor = configs.cutoutForeground!!
+ var libPageTitleRes: Int = R.string.kau_about_libraries_intro
+ var libPageTitle: String? = null
+ set(value) {
+ field = value
+ libPageTitleRes = -1 //reset res so we don't use our default
}
- }.apply {
- themeEnabled = configs.cutoutForeground == null
- })
- postInflateMainPage(fastAdapter)
- return recycler
+ var faqXmlRes: Int = -1
+ var faqPageTitleRes: Int = R.string.kau_about_faq_intro
+ var faqPageTitle: String? = null
+ set(value) {
+ field = value
+ faqPageTitleRes = -1 //reset res so we don't use our default
+ }
+ /**
+ * Whether new lines should be included
+ */
+ var faqParseNewLine: Boolean = true
}
/**
+ * For [mainPanel]
+ *
* Open hook called just before the main page view is returned
* Feel free to add your own items to the adapter in here
*/
@@ -165,32 +121,23 @@ abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Confi
}
/**
- * Create the lib view with the list of libraries
+ * For [libPanel]
+ *
+ * Method to fetch the library list
+ * This is fetched asynchronously and you may override it to customize the list
+ */
+ open fun getLibraries(libs: Libs): List<Library> = libs.prepareLibraries(this, null, null, true, true)!!
+
+ /*
+ * -------------------------------------------------------------------
+ * Page 3: FAQ
+ * -------------------------------------------------------------------
*/
- open fun inflateLibPage(layoutInflater: LayoutInflater, parent: ViewGroup, position: Int): View {
- libPage = position
- val v = layoutInflater.inflate(R.layout.kau_recycler_detached_background, parent, false)
- val recycler = v.findViewById<RecyclerView>(R.id.kau_recycler_detached)
- libRecycler = recycler
- recycler.withMarginDecoration(16, KAU_BOTTOM)
- recycler.adapter = libAdapter
- recycler.itemAnimator = KauAnimator(addAnimator = FadeScaleAnimatorAdd(scaleFactor = 0.7f, itemDelayFactor = 0.2f)).apply { addDuration = 300; interpolator = AnimHolder.decelerateInterpolator(this@AboutActivityBase) }
- val background = v.findViewById<View>(R.id.kau_recycler_detached_background)
- if (configs.backgroundColor != null) background.setBackgroundColor(configs.backgroundColor!!.colorToForeground())
- doAsync {
- libItems = getLibraries(
- if (rClass == null) Libs(this@AboutActivityBase) else Libs(this@AboutActivityBase, Libs.toStringArray(rClass.fields))
- ).map { LibraryIItem(it) }
- if (libPage >= 0 && pageStatus[libPage] == 1)
- uiThread { addLibItems() }
- }
- return v
- }
- inner class AboutPagerAdapter : PagerAdapter() {
+ private inner class AboutPagerAdapter : PagerAdapter() {
private val layoutInflater: LayoutInflater = LayoutInflater.from(this@AboutActivityBase)
- private val views = Array<View?>(pageCount) { null }
+ private val views = Array<View?>(panels.size) { null }
override fun instantiateItem(collection: ViewGroup, position: Int): Any {
val layout = getPage(position, collection)
@@ -203,7 +150,7 @@ abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Confi
views[position] = null
}
- override fun getCount(): Int = pageCount
+ override fun getCount(): Int = panels.size
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
@@ -211,7 +158,8 @@ abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Confi
* Only get page if view does not exist
*/
private fun getPage(position: Int, parent: ViewGroup): View {
- if (views[position] == null) views[position] = getPage(position, layoutInflater, parent)
+ if (views[position] == null) views[position] = panels[position]
+ .inflatePage(this@AboutActivityBase, parent, position)
return views[position]!!
}
}
@@ -222,19 +170,7 @@ abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Confi
override fun onPageSelected(position: Int) {
if (pageStatus[position] == 0) pageStatus[position] = 1 // mark as seen if previously null
- if (position == libPage && libItems != null && pageStatus[position] == 1) {
- pageStatus[position] = 2 //add libs and mark as such
- postDelayed(300) { addLibItems() } //delay so that the animations occur once the page is fully switched
- }
- }
-
- /**
- * Function that is called when the view is ready to add the lib items
- * Feel free to add your own items here
- */
- open fun addLibItems() {
- libAdapter.add(HeaderIItem(text = configs.libPageTitle, textRes = configs.libPageTitleRes))
- .add(libItems)
+ if (pageStatus[position] == 1) panels[position].addItems(this, position)
}
override fun onDestroy() {
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt
new file mode 100644
index 0000000..47b9ac4
--- /dev/null
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt
@@ -0,0 +1,198 @@
+package ca.allanwang.kau.about
+
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import ca.allanwang.kau.adapters.FastItemThemedAdapter
+import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
+import ca.allanwang.kau.animators.KauAnimator
+import ca.allanwang.kau.animators.NoAnimatorChange
+import ca.allanwang.kau.iitems.HeaderIItem
+import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.xml.kauParseFaq
+import com.mikepenz.aboutlibraries.Libs
+import com.mikepenz.fastadapter.IItem
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.uiThread
+
+/**
+ * Created by Allan Wang on 2017-08-02.
+ *
+ * The core logic for pages used in [AboutActivityBase]
+ */
+interface AboutPanelContract {
+ /**
+ * Model list to be added to [adapter]
+ */
+ var items: List<IItem<*, *>>?
+ /**
+ * The adapter, will be late initialized as it depends on configs
+ */
+ var adapter: FastItemThemedAdapter<IItem<*, *>>
+ /**
+ * Reference to the recyclerview, will be used to stop scrolling upon exit
+ */
+ var recycler: RecyclerView?
+
+ /**
+ * The base inflation method that will be called for new pages from the page adapter
+ * Keep in mind that when inflating, do NOT add the view to the viewgroup
+ * Use layoutInflater.inflate(id, parent, false)
+ */
+ fun inflatePage(activity: AboutActivityBase, parent: ViewGroup, position: Int): View
+
+ /**
+ * Convenience method called during [inflatePage]
+ * No return value necessary
+ */
+ fun onInflatingPage(activity: AboutActivityBase, recycler: RecyclerView, position: Int)
+
+ /**
+ * Triggers start of item loading
+ * Typically called with [inflatePage]
+ */
+ fun loadItems(activity: AboutActivityBase, position: Int)
+
+ /**
+ * Called when the [adapter] should take in the items
+ * This typically happens once the user has scroll to the page,
+ * so they may see a transition
+ *
+ * [AboutActivityBase.pageStatus] should be updated accordingly,
+ * as triggering this does not necessarily mean that the items are added
+ */
+ fun addItems(activity: AboutActivityBase, position: Int)
+}
+
+abstract class AboutPanelRecycler : AboutPanelContract {
+
+ override var items: List<IItem<*, *>>? = null
+
+ override lateinit var adapter: FastItemThemedAdapter<IItem<*, *>>
+
+ override var recycler: RecyclerView? = null
+
+ override fun onInflatingPage(activity: AboutActivityBase, recycler: RecyclerView, position: Int) {
+ recycler.adapter = adapter
+ recycler.itemAnimator = KauAnimator(
+ addAnimator = FadeScaleAnimatorAdd(scaleFactor = 0.7f, itemDelayFactor = 0.2f),
+ changeAnimator = NoAnimatorChange()
+ ).apply { addDuration = 300; interpolator = AnimHolder.decelerateInterpolator(recycler.context) }
+ }
+
+ override fun inflatePage(activity: AboutActivityBase, parent: ViewGroup, position: Int): View {
+ val v = LayoutInflater.from(activity).inflate(R.layout.kau_recycler_detached_background, parent, false)
+ adapter = FastItemThemedAdapter(activity.configs)
+ recycler = v.findViewById(R.id.kau_recycler_detached)
+ onInflatingPage(activity, recycler!!, position)
+ val background = v.findViewById<View>(R.id.kau_recycler_detached_background)
+ if (activity.configs.backgroundColor != null) background.setBackgroundColor(activity.configs.backgroundColor!!.colorToForeground())
+ loadItems(activity, position)
+ return v
+ }
+
+ override fun addItems(activity: AboutActivityBase, position: Int) {
+ if (items == null) return
+ activity.pageStatus[position] = 2
+ postDelayed(300) { addItemsImpl(activity, position) }
+ }
+
+ abstract fun addItemsImpl(activity: AboutActivityBase, position: Int)
+}
+
+/**
+ * Panel delegate for the main page
+ * The loading is synchronous, so it is done on inflation
+ * All other loading and adding methods are overridden to do nothing
+ * There is a [AboutActivityBase.postInflateMainPage] hook that can be overridden
+ * to update this panel without extending the whole delegate
+ */
+open class AboutPanelMain : AboutPanelRecycler() {
+
+ override fun onInflatingPage(activity: AboutActivityBase, recycler: RecyclerView, position: Int) {}
+
+ override fun inflatePage(activity: AboutActivityBase, parent: ViewGroup, position: Int): View {
+ with(activity) {
+ adapter = FastItemThemedAdapter<IItem<*, *>>(configs)
+ recycler = fullLinearRecycler(adapter)
+ adapter.add(CutoutIItem {
+ with(configs) {
+ text = string(cutoutTextRes, cutoutText)
+ drawable = drawable(cutoutDrawableRes, cutoutDrawable)
+ if (configs.cutoutForeground != null) foregroundColor = configs.cutoutForeground!!
+ }
+ }.apply {
+ themeEnabled = configs.cutoutForeground == null
+ })
+ postInflateMainPage(adapter)
+ return recycler!!
+ }
+ }
+
+ override fun loadItems(activity: AboutActivityBase, position: Int) {}
+ override fun addItems(activity: AboutActivityBase, position: Int) {
+ activity.pageStatus[position] = 2
+ }
+
+ override fun addItemsImpl(activity: AboutActivityBase, position: Int) {}
+
+}
+
+/**
+ * Panel for loading libraries
+ * There is a [AboutActivityBase.getLibraries] hook that can be overridden
+ * to customize the libraries listed
+ */
+open class AboutPanelLibs : AboutPanelRecycler() {
+
+ override fun onInflatingPage(activity: AboutActivityBase, recycler: RecyclerView, position: Int) {
+ super.onInflatingPage(activity, recycler, position)
+ recycler.withMarginDecoration(16, KAU_BOTTOM)
+ LibraryIItem.bindEvents(adapter)
+ }
+
+ override fun loadItems(activity: AboutActivityBase, position: Int) {
+ doAsync {
+ with(activity) {
+ items = getLibraries(if (rClass == null) Libs(activity) else Libs(this, Libs.toStringArray(rClass.fields)))
+ .map { LibraryIItem(it) }
+ if (pageStatus[position] == 1)
+ uiThread { addItems(activity, position) }
+ }
+ }
+ }
+
+ override fun addItemsImpl(activity: AboutActivityBase, position: Int) {
+ with(activity.configs) {
+ adapter.add(HeaderIItem(text = libPageTitle, textRes = libPageTitleRes))
+ .add(items)
+ }
+ }
+}
+
+open class AboutPanelFaqs : AboutPanelRecycler() {
+
+ override fun onInflatingPage(activity: AboutActivityBase, recycler: RecyclerView, position: Int) {
+ super.onInflatingPage(activity, recycler, position)
+ FaqIItem.bindEvents(adapter)
+ }
+
+ override fun loadItems(activity: AboutActivityBase, position: Int) {
+ with(activity) {
+ kauParseFaq(configs.faqXmlRes, configs.faqParseNewLine) {
+ items = it.map { FaqIItem(it) }
+ if (pageStatus[position] == 1)
+ addItems(activity, position)
+ }
+ }
+ }
+
+ override fun addItemsImpl(activity: AboutActivityBase, position: Int) {
+ with(activity.configs) {
+ adapter.add(HeaderIItem(text = faqPageTitle, textRes = faqPageTitleRes))
+ .add(items)
+ }
+ }
+
+} \ No newline at end of file
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt b/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt
new file mode 100644
index 0000000..32573bc
--- /dev/null
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt
@@ -0,0 +1,33 @@
+package ca.allanwang.kau.about
+
+import android.content.Context
+import android.content.res.Configuration
+import android.util.AttributeSet
+import android.widget.LinearLayout
+import android.widget.TextView
+import ca.allanwang.kau.ui.views.CollapsibleView
+import ca.allanwang.kau.ui.views.CollapsibleViewDelegate
+
+/**
+ * Created by Allan Wang on 2017-08-02.
+ *
+ */
+class CollapsibleTextView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : TextView(context, attrs, defStyleAttr), CollapsibleView by CollapsibleViewDelegate() {
+
+ init {
+ initCollapsible(this)
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration?) {
+ resetCollapsibleAnimation()
+ super.onConfigurationChanged(newConfig)
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ val result = getCollapsibleDimension()
+ setMeasuredDimension(result.first, result.second)
+ }
+} \ No newline at end of file
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt
index 1ba5815..3f764d3 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt
@@ -4,6 +4,7 @@ import android.support.v7.widget.RecyclerView
import android.view.View
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
+import ca.allanwang.kau.iitems.KauIItem
import ca.allanwang.kau.ui.views.CutoutView
import ca.allanwang.kau.utils.bindView
import com.mikepenz.fastadapter.items.AbstractItem
@@ -13,12 +14,9 @@ import com.mikepenz.fastadapter.items.AbstractItem
*
* Just a cutout item with some defaults in [R.layout.kau_iitem_cutout]
*/
-class CutoutIItem(val config: CutoutView.() -> Unit = {}
-) : AbstractItem<CutoutIItem, CutoutIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() {
-
- override fun getType(): Int = R.id.kau_item_cutout
-
- override fun getLayoutRes(): Int = R.layout.kau_iitem_cutout
+class CutoutIItem(val config: CutoutView.() -> Unit = {}) : KauIItem<CutoutIItem, CutoutIItem.ViewHolder>(
+ R.layout.kau_iitem_cutout, {ViewHolder(it)}, R.id.kau_item_cutout
+), ThemableIItem by ThemableIItemDelegate() {
override fun isSelectable(): Boolean = false
@@ -38,8 +36,6 @@ class CutoutIItem(val config: CutoutView.() -> Unit = {}
}
}
- override fun getViewHolder(v: View): ViewHolder = ViewHolder(v)
-
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
val cutout: CutoutView by bindView(R.id.kau_cutout)
}
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt
new file mode 100644
index 0000000..5e00447
--- /dev/null
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt
@@ -0,0 +1,86 @@
+package ca.allanwang.kau.about
+
+import android.support.v7.widget.RecyclerView
+import android.text.method.LinkMovementMethod
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import ca.allanwang.kau.adapters.ThemableIItem
+import ca.allanwang.kau.adapters.ThemableIItemDelegate
+import ca.allanwang.kau.iitems.KauIItem
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.dpToPx
+import ca.allanwang.kau.utils.parentViewGroup
+import ca.allanwang.kau.utils.setPaddingLeft
+import ca.allanwang.kau.xml.FaqItem
+import com.mikepenz.fastadapter.FastAdapter
+import com.mikepenz.fastadapter.IItem
+import com.mikepenz.fastadapter.listeners.ClickEventHook
+
+/**
+ * Created by Allan Wang on 2017-08-02.
+ */
+class FaqIItem(val content: FaqItem) : KauIItem<LibraryIItem, FaqIItem.ViewHolder>(
+ R.layout.kau_iitem_faq, { ViewHolder(it) }, R.id.kau_item_faq
+), ThemableIItem by ThemableIItemDelegate() {
+
+ companion object {
+
+
+ @JvmStatic fun bindEvents(fastAdapter: FastAdapter<IItem<*, *>>) {
+ fastAdapter.withSelectable(false)
+ .withEventHook(object : ClickEventHook<IItem<*, *>>() {
+
+ override fun onBind(viewHolder: RecyclerView.ViewHolder): View?
+ = (viewHolder as? ViewHolder)?.questionContainer
+
+ override fun onClick(v: View, position: Int, adapter: FastAdapter<IItem<*, *>>, item: IItem<*, *>) {
+ if (item !is FaqIItem) return
+ item.isExpanded = !item.isExpanded
+ v.parentViewGroup.findViewById<CollapsibleTextView>(R.id.faq_item_answer).setExpanded(item.isExpanded)
+ }
+
+ })
+ }
+ }
+
+ private var isExpanded = false
+
+ override fun bindView(holder: ViewHolder, payloads: MutableList<Any>?) {
+ super.bindView(holder, payloads)
+ with(holder) {
+ number.text = "${content.number}."
+ question.text = content.question
+ answer.setExpanded(isExpanded, false)
+ if (accentColor != null) answer.setLinkTextColor(accentColor!!)
+ answer.text = content.answer
+ answer.post { answer.setPaddingLeft(16.dpToPx + number.width) }
+ bindTextColor(number, question)
+ bindTextColorSecondary(answer)
+ bindDividerColor(answer)
+ bindBackgroundRipple(questionContainer)
+ }
+ }
+
+ override fun unbindView(holder: ViewHolder) {
+ super.unbindView(holder)
+ with(holder) {
+ number.text = null
+ question.text = null
+ answer.text = null
+ }
+ }
+
+ class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
+ val container: ViewGroup by bindView(R.id.faq_item)
+ val questionContainer: ViewGroup by bindView(R.id.faq_item_question_container)
+ val number: TextView by bindView(R.id.faq_item_number)
+ val question: TextView by bindView(R.id.faq_item_question)
+ val answer: CollapsibleTextView by bindView(R.id.faq_item_answer)
+
+ init {
+ answer.movementMethod = LinkMovementMethod.getInstance()
+ }
+ }
+
+} \ No newline at end of file
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt
index 518cd54..e50460e 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt
@@ -8,6 +8,7 @@ import android.view.View
import android.widget.TextView
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
+import ca.allanwang.kau.iitems.KauIItem
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.gone
import ca.allanwang.kau.utils.startLink
@@ -15,33 +16,30 @@ import ca.allanwang.kau.utils.visible
import com.mikepenz.aboutlibraries.entity.Library
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.IItem
-import com.mikepenz.fastadapter.items.AbstractItem
/**
* Created by Allan Wang on 2017-06-27.
*/
-class LibraryIItem(val lib: Library
-) : AbstractItem<LibraryIItem, LibraryIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() {
+class LibraryIItem(val lib: Library) : KauIItem<LibraryIItem, LibraryIItem.ViewHolder>(
+ R.layout.kau_iitem_library, { ViewHolder(it) }, R.id.kau_item_library
+), ThemableIItem by ThemableIItemDelegate() {
companion object {
- @JvmStatic fun bindClickEvents(fastAdapter: FastAdapter<IItem<*, *>>) {
- fastAdapter.withOnClickListener { v, _, item, _ ->
- if (item !is LibraryIItem) false
- else {
- val c = v.context
- with(item.lib) {
- c.startLink(libraryWebsite, repositoryLink, authorWebsite)
+ @JvmStatic fun bindEvents(fastAdapter: FastAdapter<IItem<*, *>>) {
+ fastAdapter.withSelectable(false)
+ .withOnClickListener { v, _, item, _ ->
+ if (item !is LibraryIItem) false
+ else {
+ val c = v.context
+ with(item.lib) {
+ c.startLink(libraryWebsite, repositoryLink, authorWebsite)
+ }
+ true
+ }
}
- true
- }
- }
}
}
- override fun getType(): Int = R.id.kau_item_library
-
- override fun getLayoutRes(): Int = R.layout.kau_iitem_library
-
override fun isSelectable(): Boolean = false
override fun bindView(holder: ViewHolder, payloads: MutableList<Any>?) {
@@ -83,8 +81,6 @@ class LibraryIItem(val lib: Library
}
}
- override fun getViewHolder(v: View): ViewHolder = ViewHolder(v)
-
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
val card: CardView by bindView(R.id.lib_item_card)
val name: TextView by bindView(R.id.lib_item_name)
diff --git a/about/src/main/res/layout/kau_iitem_faq.xml b/about/src/main/res/layout/kau_iitem_faq.xml
new file mode 100644
index 0000000..4a0f7fc
--- /dev/null
+++ b/about/src/main/res/layout/kau_iitem_faq.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/faq_item"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/faq_item_question_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="@dimen/kau_padding_normal">
+
+ <TextView
+ android:id="@+id/faq_item_number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingEnd="@dimen/kau_padding_small"
+ android:paddingStart="0dp" />
+
+ <TextView
+ android:id="@+id/faq_item_question"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <ca.allanwang.kau.about.CollapsibleTextView
+ android:id="@+id/faq_item_answer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="@dimen/kau_padding_normal" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/about/src/main/res/values/strings.xml b/about/src/main/res/values/strings.xml
index 509b56c..164c0c8 100644
--- a/about/src/main/res/values/strings.xml
+++ b/about/src/main/res/values/strings.xml
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="kau_about_libraries_intro">This app would not be possible without the following great libraries.</string>
+ <string name="kau_about_faq_intro">FAQ</string>
</resources> \ No newline at end of file
diff --git a/about/src/main/res/values/strings_about.xml b/about/src/main/res/values/strings_about.xml
index 8f10d31..8c3dc59 100644
--- a/about/src/main/res/values/strings_about.xml
+++ b/about/src/main/res/values/strings_about.xml
@@ -1,5 +1,5 @@
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="library_kau_libraryVersion">3.0</string>
+ <string name="library_kau_libraryVersion">3.2.3</string>
<string name="define_kau"/>
<string name="library_kau_author">Allan Wang</string>
<string name="library_kau_authorWebsite">https://www.allanwang.ca/dev/</string>