Kent is a set of extension functions to build dynamic Android layouts. The purpose of this library is to make UI code clean, easy to read and as simple as possible without introducing extra logic. Simple UI code with Kent Layouts:
verticalLayout {
lparams(matchParent, matchParent)
textView {
text = "Hello, World!"
}
}
There is no magic here, only two extension functions that turns noisy code to simple DSL syntax without XML.
Usually, XML is used to build Android UI. Major disadvantages of XML:
- XML is parsed on the device wasting battery and CPU time, and view inflations affects the cold start time
- You can't insert code logic inside XML
- XML is not null-safe which leads to NPEs.
- You repeat
android
andapp
almost in every line - XML is static, you can't dynamically add / remove views according to app logic, for example:
if isLoggedIn: addOwnerPhoto() else addLoginButton()
and many more reasons
The main goal is to supersede Anko Layouts (since it is deprecated) with support for AndroidX and excluding all other gigantic util code.
Add these dependencies to your app level build.gradle:
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "com.google.android.material:material:1.2.1"
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation 'com.kent.layouts:layouts:1.0.1'
You can build your UI dynamically in a conventional way, but even in Kotlin, it would be longer:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val parent = LinearLayout(this)
parent.orientation = LinearLayout.VERTICAL
parent.layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
val btn = Button(this)
btn.layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
btn.text = "Click me!"
btn.setOnClickListener {
Toast.makeText(this, "Hello, World!", Toast.LENGTH_SHORT).show()
}
parent.addView(btn)
setContentView(parent)
}
While with the DSL syntax of Kent Layouts, the same UI code of the same activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
lparams(matchParent, matchParent)
button {
text = "Click me!"
setOnClickListener {
toast("Hello, World!")
}
}
}
}
All you need is Context
, this will simply create TextView
inside FrameLayout
using context
:
return ViewHolder(parent.context.frameLayout {
layoutParams = ViewGroup.LayoutParams(matchParent, dip(56))
padding = dip(16)
setRippleEffect()
textView {
layoutParams = FrameLayout.LayoutParams(wrapContent, wrapContent)
text = "Hello, Kent!"
}
})
Most of the standard Android views and view groups have their extensions so that you don't need to waste time writing extensions, here is the complete list:
ViewGroups
* AppBarLayout
* BottomAppBar
* CollapsingToolbarLayout
* ConstraintLayout
* CoordinatorLayout
* DrawerLayout
* FrameLayout
* GridLayout
* LinearLayout
* RelativeLayout
Views
* Buttons
* Button
* MaterialButton
* FloatingActionButton
* CardView & MaterialCardView
* CheckBox & MaterialCheckBox
* Chip and ChipGroup
* DatePicker
* ImageView
* NavigationView & BottomNavigationView
* Progress: CircularProgress and LinearProgress
* RadioButton, MaterialRadioButton, RadioGroup
* RatingBar
* RecyclerView
* ScrollView & NestedScrollView
* SeekBar
* Switch & MaterialSwitch
* Tabs: TabItem & TabLayout
* TextView
* EditText & TextInputEditText & TextInputLayout
* View
* ViewPager & ViewPager2
Using Kotlin extension functions, we can convert this conventional code:
val btn = Button(this)
btn.layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
btn.text = "Click me!"
parent.addView(btn)
into DSL syntax as an extension function of ViewGroup
:
inline fun ViewGroup.button(init: AppCompatButton.() -> Unit = {}): AppCompatButton {
val a = AppCompatButton(context).apply(init)
addView(a)
return a
}
And the result is more beatiful, concise and easy to understand code:
button {
layoutParams = LinearLayout.LayoutParams(wrapContent, wrapContent)
text = "Click me!"
}
Create extension function of ViewGroup for your custom view, example for SwipeRefreshLayout
:
inline fun ViewGroup.swipeRefresh(init: SwipeRefreshLayout.() -> Unit = {}): SwipeRefreshLayout {
val a = SwipeRefreshLayout(context).apply(init)
addView(a)
return a
}
See more examples in samples
An open source app entirely written using Kent Layouts: Flashcards Maker