vkatz-lib

Additional

Language
Kotlin
Version
N/A
Created
Mar 8, 2015
Updated
Jul 11, 2018
Owner
Viachaslau Katsuba (vkatz)
Contributor
Viachaslau Katsuba (vkatz)
1
Activity
Badge
Generate
Download
Source code

Advertisement

Katzilla & Katzext

Libs to speedup & simplify your android apps development

Usage

Implementation samples might be found in the samples/ folder.

Separate info about each lib see below

Including In Your Project

Add follow for your dependencies in the build.gradle

implementation 'io.github.vkatz:katzext:1.0.3'
implementation 'io.github.vkatz:katzilla:1.0.3'

Libs dependencies info:

Be aware - lib use newest androidX versions of libs

Versions:

ext.appKotlinVersion = '1.2.50'
ext.appKotlinCorutines = '0.22.5'
ext.appAndroidXVersion = '1.0.0-alpha3'
ext.appConstraintVersion = '1.1.2'

katzilla:

dependencies {
    api "androidx.appcompat:appcompat:$appAndroidXVersion"
    api "androidx.transition:transition:$appAndroidXVersion"
    api "org.jetbrains.kotlin:kotlin-stdlib:$appKotlinVersion"
}

katzext:

dependencies {
    api "androidx.appcompat:appcompat:$appAndroidXVersion"
    api "androidx.recyclerview:recyclerview:$appAndroidXVersion"
    api "androidx.constraintlayout:constraintlayout:$appConstraintVersion"
    api "org.jetbrains.kotlin:kotlin-stdlib:$appKotlinVersion"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$appKotlinCorutines"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$appKotlinCorutines"
}

Developed By

License

Copyright 2018 Viachaslau Katsubo

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Katzilla

This lib used to crate Single activity navigation with help of Fragments

This impl using MVVM model of screens, each screen is just a Fragment with bunch of improvements

KatzillaFragment<Model> provide default transition animations and permission helpers, see sources to more info, there is all simple

It also provide parent & model properties to control data & flow. Model might store/restore any data & Parent allow to perform navigation across app by navigation functions

parent provide go and back methods as far as full back stack access - so u are free to modify it

Minimal implementation:

//extend from KatzillaActivity
class MainUI : KatzillaActivity() {

    //override method
    override fun initContent(backStack: FragmentBackStack, savedInstanceState: Bundle?) {
        setContentView(R.layout.main)
        //bind to supportFragmentManager
        //                                     navigation root
        //                                             |
        backStack.bind(supportFragmentManager, R.id.screen_layout, MainScreen::class)
        //                                                              |
        //        default screen (will be used in case resotr old one is imposible || it is first start)
    }
}

Next is to make screen

class MainScreenModel : FragmentScreen.ScreenModel() {
    var counter = AppLiveData(0)
}

class MainScreen : KatzillaFragment<MainScreenModel>() {
    private var backTimeouted = false

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, model: MainScreenModel, savedInstanceState: Bundle?): View? =
            inflater.inflate(R.layout.screen_main)

    override fun onViewCreated(view: View, model: MainScreenModel, savedInstanceState: Bundle?) {
        super.onViewCreated(view, model, savedInstanceState)

        ...
        dataPass.setOnClickListener {
            //navigate with predefined model
            parent?.go(DataPassScreen::class, DataPassScreen.Model(model.counter.value, { model.counter.value = it }))
        }

        spinners.setOnClickListener {
            //simple navigation
            parent?.go(SpinnerScreen::class)
        }
        ...

    }
}

Katzext

Helper lib that provide a bunch of enhanced views and some amount of useful custom views as far as utility classes

Adapters

Pack of useful adapters:

  • HeaderFooterRecyclerViewAdapter
  • MultiTypeRecyclerViewAdapter
  • SimpleExtendSpinnerAdapter
  • SimpleExtendSpinnerArrayAdapter
  • SimpleRecyclerViewAdapter
  • SimpleViewPagerAdapter

More details in the AdaptersScreen

Simple example:

   val adapter = when (index) {
   // usual recycler without direct creation of VH
       0 -> SimpleRecyclerViewAdapter(listOf(1, 2, 3),
                                      { this.toLong() },
                                      R.layout.spinner_item,
                                      { itemView.asTextView().text = it.toString() })
   // usual recycler with VH
       1 -> SimpleRecyclerViewAdapter(listOf(3, 4, 5),
                                      { this.toLong() },
                                      { parent ->
                                          SimpleViewHolder(R.layout.spinner_item, parent, { itemView.asTextView().text = it.toString() })
                                      })
   // adapter for multiple types - just register handlers and it's done
       2 -> MultiTypeRecyclerViewAdapter(listOf("a", 1, "c", 2), { hashCode().toLong() },
                                         ViewTypeHandler<Any>({ it is String }, ::SpinnerItemViewHolder),
                                         ViewTypeHandler(
                                                 { it is Int },
                                                 {
                                                     SimpleViewHolder<Any>(R.layout.spinner_item, it,
                                                                           {
                                                                               itemView.asTextView().text = it.toString()
                                                                               itemView.setBackgroundColor(Color.BLUE)
                                                                           })
                                                 })
                                        )
   // multi type adapter where u can add 1 header and 1 footer (u can hide it via visibility properties) (if u need more - use default MultiTypeRecyclerViewAdapter)
       3 -> HeaderFooterRecyclerViewAdapter(Array(50, { i -> i }).toList(), null,
                                            R.layout.spinner_item,
                                            { itemView.asTextView().text = "Header" },
                                            R.layout.spinner_item,
                                            { itemView.asTextView().text = "Footer" },
                                            ViewTypeHandler({ true },
                                                            R.layout.spinner_item,
                                                            { itemView.asTextView().text = it.toString() })
                                           ).apply { headerVisible = true; footerVisible = true }

   // pagination - just use PaginationList as data source and call list.loadPAge on footer show (or impl your own logic)
       4 -> {
           val list = PaginationList<String>(7, { from, count, callback ->
               asyncUI(this) {
                   delay(1000)
                   val cnt = minOf(count, 100 - from)
                   callback(Array(cnt, { i -> "Item #${i + from}" }).toList())
               }
           })
           val adapter = HeaderFooterRecyclerViewAdapter(list, null, null,
                                                         { SimpleViewHolder(ProgressBar(it.context), { list.loadPage() }) },
                                                         ViewTypeHandler({ true },
                                                                         R.layout.spinner_item,
                                                                         { itemView.asTextView().text = it })
                                                        )
           list.setOnPageLoadedListener {
               if (adapter.data == list) {
                   if (!list.hasMorePages) {
                       adapter.footerVisible = false
                   }
                   adapter.notifyDataSetChanged()
               } else {
                   list.setOnPageLoadedListener(null)
               }
           }
           adapter
       }
       else -> null
   }
   recycler.adapter = adapter

Utils

Most examples might be found in the UtilsScreen

AsyncHelper - helper for asyn operations using corutines, also suppor lifecycle (async operation will be canceled on screen close)

 asyncUI {
       val t1 = async { 1 }.await()   //Int? - ? due to task might be canceled
       val t2 = async { 1 }.await()!! //Int
       val t3 = AsyncHelper(null, newSingleThreadContext("WorkThread"), { 1 }).start().await()
 }

Delegates - SharedPreferences and Bundle delegates

ExtUtils - various useful functions

LiveDataHelper.kt - android lifecycle original LiveData is too low to use, so here is improvements

  • AppLiveData - accept initial value, provide null safe ops for kotlin & allow to use lambdas within alot of useful observers
  • ExtLiveData - additionally provide access control (via token, to prevent unwanted edit) & loadability with/without interruption

PaginationList - ArrayList + async data loading, useful for adapters, see example at AdaptersScreen #pagination(4)

XmlParser - pool xml parser with easy code

  val foods = ArrayList<FoodItem>()
  XmlParser.parse(context!!.resources.openRawResource(R.raw.test)) {
      item("menu") {
          item("food") { params ->
              val item = FoodItem(params["id"]?.toInt() ?: 0, "", "")
              itemValue("name", { item.name = it ?: "" })
              itemValue("price", { item.price = it ?: "" })
              foods.add(item)
          }
      }
  }
  xml.text = "ParsedXml:\n$foods".replace("),", ")\n")

Widgets

List of views:

Extend elements have a bunch of buffs

List of items:

  • ExtendCheckBox
  • ExtendConstraintLayout
  • ExtendEditText
  • ExtendFrameLayout
  • ExtendImageView
  • ExtendLinearLayout
  • ExtendProgressBar
  • ExtendRadioButton
  • ExtendRelativeLayout
  • ExtendTextView

New widgets:

  • FlowLayout
  • ExtendSpinner
  • SlideMenuLayout
  • ViewPagerIndicator
Core buffs:
  1. app:compoundDrawableWidth and app:compoundDrawableHeight -> specify compound drawable size(w, h or both)

  1. app:extendBackground1 and app:extendBackground2 -> combine 2 bg into one as layers (useful when u have color + selector)
  2. app:extendEnabled and app:extendActivated -> set relative view state from xml
ExtendEditText

app:extendInputMask/setMask(String) allow to provide input mask ("000 000 0000") - where '0' will be input digit, all other chars will stay

addAfterTextChangedListener setAfterTextChangedListener functions and onSelectionChangedListener listener

ExtendImageView

app:touchZoom allow to enable pinchZoom(default false), app:maxZoom and app:minZoom to config it

New widgets

FlowLayout

Allow to place items one by one, in case there is no space in line - item placed at next line. Allow to set horizontal gaps and vertical per line align

ExtendSpinner

Completely new spinner that allow to handle - "no selection" and "custom selected" items ps: in case u are using TextView+[height=wrap-content] as list istem - add also line count !! (otherwise u will face ListView measure bug, someday i will fix it)

SlideMenuLayout

Allow to create expandable menu from any direction, multiple per layout

Take look at the examples:

  • slide_menu_1.xml
  • slide_menu_2.xml
  • slide_menu_3.xml
  • slide_menu_4.xml

Examples:

ViewPagerIndicator

Simple indicators for ViewPager - just setup adapter and bind to ViewPager