A Framework that simplify developing MVVM Architecture and Material Design in Android with Kotlin language including useful Extensions and Sample Application. This Framework has some tools for Retrofit and OKHttp and Coroutine for calling REST API requests.
Dynamic Localization and Day/Night Theme & Meow Custom Widgets are another features.
We suggest you to install Meow-Sample.apk to be familiar with Meow Framework
.
We are developing this framework in open source community without financial planning but the maintenance & preparing updates at periodic times is Time-consuming. If you like this project and you want to give us peace of mind, you can support us by clicking this button :
implementation("com.etebarian:meow-framework-mvvm:0.10.2")
After adding library, some of most useful libraries (such as Androidx AppCompat
, Coroutine
, Glide
, Kodein
, Kotlinx Serialization
, Material Components
, Moshi
, Navigation Components
, Retrofit
) will be added in your app. So you would'nt need to add this libraries manually.
List of dependencies can be found in meow.AppConfig.kt in Dependencies
Object.
Check out build.gradle.kts in Sample module to avoid any issues that related to setup & adding Framework.
We recommend that use Kotlin DSL Gradle
instead of Groovy
. That is not Buggy ๐.
Enable androidx in
gradle.properties
.android.useAndroidX=true android.enableJetifier=trueRemember that you'll need to enable Java 8 & DataBinding & Kotlin Kapt in your app module
build.gradle
.
-
- Initialization : How to have a
MeowApp
. - Meow Controller ๐ : Trust this CAT.
- MVVM Architecture : Get to know this architecture.
- Accessing Views with DataBinding : Forget
findViewById()
.
- Initialization : How to have a
-
๐ถ REST API : Retrofit + OKHttp + Coroutine + Moshi
- Create Api that extends
MeowApi
: A new way to connect server. - Common API Flow/Patterns : Some predefined patterns for REST APIs.
- Sample
Index
Api : A Sample for fillingRecyclerView
from JSON Data.
- Create Api that extends
We assume that you know MVVM architecture, but if you have some problems in understanding its, this Articles can help you.
Create your application class which extends MeowApp
and set it in AndroidManifest.xml
. Dependency Injection in MVVM architecture is necessary, so we use Kodein-DI
Framework.
You'll need to define appModule
for View Models. Update application class like below :
class App : MeowApp() {
// Create a kodein module.
val appModule = Module("App Module", false) {
// Provide object of SomeOfClass(such as View Models) in Kodein with bind() function.
// bind() from singleton { SomeOfClass(instance()) }
}
// Source is `KodeinAware` interface.
override val kodein = Kodein.lazy {
// Import org.kodein.di.Kodein.*
bind() from singleton { kodein.direct }
bind() from singleton { this@App }
import(androidXModule(this@App))
import(meowModule) // Important
import(appModule)
}
}
This Framework has two Highlighted Features :
- Dynamic Day/Night Theme to switch from
LIGHT
toDARK
mode. - Dynamic Localization to change language , currency formatting , date formatting of app at Realtime.
to use above features, you'll need to define your MeowController
.
MeowController
is a class that controls some features in app such as above.
If you want to use avoidException
in your app, this class can controls Exception Handlers with onException
property.
Update your application class like this :
class App : MeowApp() {
// Layout Direction would be set automatically by Android System.
// (Example: "en": LayoutDirection.LTR "fa": LayoutDirection.RTL).
// Our Primary Sample app's language is English.
override fun getLanguage(context: Context?) = "en" // or any language such as ("fa","fr","ar",etc.)
// Our Sample app's theme is set by Android System Light/Dark (Day/Night) mode.
override fun getTheme(context: Context?) =
if (context.isNightModeFromSettings()) MeowController.Theme.NIGHT else MeowController.Theme.DAY
override fun onCreate() {
super.onCreate()
bindMeow { // Import it from meow package.
it.isDebugMode = BuildConfig.DEBUG
// Set other properties here.
it.onException = { // Only non-fatal error
// Log to Fabric or any other Crash Management System. Just use `avoidException` instead of `try{}catch{}`
}
}
}
}
You can update language and theme from UI Thread by using MeowController
global instance.
import meow.controller
controller.updateLanguage(meowActivity, string)
controller.updateTheme(meowActivity, theme)
The Sample Application has above features. try to install Meow-Sample.apk .
MVVM is Model-View-ViewModel that we define it in Android App as Data Model - View (Activity, Fragment, DialogFragment, BottomSheetDialogFragment) - MeowViewModel.
Follow below steps to have an activity with MVVM Architecture.
class MainViewModel(app: App): MeowViewModel(app)
val appModule = Module("App Module", false) {
bindAutoTag<MainViewModel>() with provider {
MainViewModel(kodein.direct.instance())
}
}
bindAutoTag()
was imported frommeow.ktx.*
package.
<layout>
<data>
<variable
name="viewModel"
type="MainViewModel" />
</data>
<LinearLayout /> <!-- or another View -->
</layout>
โโโMainActivity
is a sample activity that needs Kodein Dependency Injection and ViewDataBinding and View Model. See this example :
class MainActivity : MeowActivity<ActivityMainBinding>() {
// ActivityMainBinding is generated by Androidx Lifecycle DataBinding Utils.
private val viewModel: MainViewModel by instanceViewModel()
override fun layoutId() = R.layout.activity_main
override fun initViewModel() {// Set View Model in binding.
binding.viewModel = viewModel
}
}
You can access views like this code :
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Meow.Toolbar" />
class MainActivity : MeowActivity<ActivityMainBinding>() {
override fun layoutId() = R.layout.activity_main
override fun onCreate(savedInstanceState: Bundle?) {
// ...
binding.toolbar.title = "custom_title" // Use binding variable
}
}
Now you have an Activity with MVVM architecture. In above sample, you can replace MeowActivity
with MeowFragment
to have MVVM Fragment.
Meow Framework provides some tools to call Server REST API actions from Android App with Retrofit
. Creating client connections will be with OKHttp
. Moshi
helps us to serialize json responses. We replaced RxJava
with Coroutine
for multi thread handling.
class AppApi(
var app: App,
baseUrl : String = "http://api-url.any/api/v1/"
): MeowApi(baseUrl)
We'll show you how to call a request to server and get response from it. Then Data has been shown in UI by parsing Data. Some of actions that is related to REST API can be have a flow/pattern. We define this patterns as :
Index
: Response with simple request from server can be parsed as List of Data Model.Detail
: Response with simple request from server can be parsed as a Data Model.Form
: Response with advanced request (send a form) from server can be parsed as a Data Model.
For example, server gives this JSON response when we call /api/v1/persons
with GET method :
[
{
"id":1,
"username":"oneHamidreza",
"alias":"Hamidreza Etebarian"
},
{
"id":2,
"username":"samdh82",
"alias":"Ali Modares"
}
]
Create a data class for JSON response which uses Moshi @Json
annotation.
@JsonClass(generateAdapter = true)
data class Person(
@Json(name = "id") var id: Int = 0,
@Json(name = "username") var username: String? = null,
@Json(name = "alias") var alias: String? = null) {
// RecyclerView List Adapter requires DiffCallBack.
class DiffCallback : DiffUtil.ItemCallback<Person>() {
override fun areItemsTheSame(oldItem: Person, newItem: Person) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Person, newItem: Person) = oldItem == newItem
}
}
Define an interface containing Rest API actions. Meow Framework uses Coroutine
library to calling Rest API actions, so you must write suspend
prefix for functions.
interface PersonApi {
@GET("persons") // Don't need to write absolute path. OKHTTP appends this string at end of your baseUrl API.
suspend fun getPersonIndex(): List<Person>
}
class PersonIndexViewModel(override var app: App) : MeowViewModel(app) {
// Define LiveData variables. use `SingleLiveData` to observe only when changed.
var eventLiveData = SingleLiveData<MeowEvent<*>>()
var listLiveData = SingleLiveData<List<Person>>()
var customLiveData = SingleLiveData<String>()
fun callApi() {
safeCallApi(
liveData = eventLiveData,
apiAction = { AppApi(app).createServiceByAdapter<PersonApi>().getPersonIndex() }
) { _, it ->
// If connection was Success and Retrofit can parse json data as list of models, this line will be run.
// Otherwise MeowEvent.Api.Error will be posted into eventLiveData.
// You can observe it manually or use MeowFlow.
listLiveData.postValue(it)
}
}
}
Create activity_sample_index.xml
which has RecyclerView
to showing items as List.
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="PersonIndexViewModel" />
<!-- Remember that viewModel type must be with package -->
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
style="@style/Meow.RecyclerView.Linear"
meow_items="@{viewModel.listLiveData}" />
<meow.widget.MeowProgressBar
android:id="@+id/progressbar"
style="@style/Meow.ProgressBar.Medium.Primary" />
</FrameLayout>
</layout>
Use MeowFlow
to handle events from ViewModel automatically.
class SampleIndexActivity : MeowActivity<ActivitySampleIndexBinding>() {
//...
private val viewModel by instance<PersonIndexViewModel>()
override fun layoutId() = R.layout.activity_sample_index
override fun initViewModel() {
binding.viewModel = viewModel
callApiAndObserve()
}
private fun callApiAndObserve() {
MeowFlow.GetDataApi<Person>(this) { // You must pass the type of API response. For Example : `Person`.
viewModel.callApi()
}.apply {
errorHandlerType = MeowFlow.ErrorHandlerType.TOAST // Error handling will be with toast().
progressBarInterface = binding.progressbar
}.observeForIndex(viewModel.eventLiveData, viewModel.listLiveData)
// Optional - call safeObserve function for observe changes of liveData safely.
viewModel.customLiveData.safeObserve(this) {
// Access the value of liveData with it parameter.
}
}
}
MeowFlow
is a helper class that observes eventLiveData
and it handles errors from API automatically. You can set error handling with errorHandlerType
. Supported types : TOAST
, SNACKBAR
, EMPTY_STATE
.
For example, when errorHandlerType
is Toast
errors has been shown in toast form. See strings_error.xml to edit error messages.
item_person.xml
describes the layout of each row of list and you can set properties with DataBinding
structure. Define layout like this :
<layout>
<data>
<variable
name="model"
type="Person" />
</data>
<LinearLayout>
<TextView android:text="@{model.alias}" />
</LinearLayout>
</layout>
We suggest you to use MeowAdapter
. Let's take a look at this sample :
class PersonAdapter : MeowAdapter<Model, ViewHolder>(Person.DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemPersonBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MeowViewHolder(binding.root) { position, model ->
binding.let {
it.setVariable(BR.model, model)
it.executePendingBindings()
}
}
}
}
Finally bind adapter to RecyclerView
.
class PersonIndexActivity : MeowActivity<ActivitySampleIndexBinding>(){
override fun onCreate(savedInstanceState: Bundle?) {
//...
binding.recyclerView.adapter = PersonAdapter()
}
}
Now you have a activity that connect to REST API and parse the response (if the response code is HttpCode.OK (200)) and it shows items into a RecyclerView
as a list.
Above sample can be used for other types of REST API patterns/flows (such as Detail
,Form
). for more details see API Package in Sample
module.
We have developed some Kotlin Extensions that can be help us in building Android Apps. Just import meow.ktx
package which include the following :
- ๐งฉ Androidx Extensions
- ๐ต Currency Extensions
- ๐ Date Extensions
- ๐ File Extensions
- ๐ JSON Extensions
- ๐ Kodein Extensions
- ๐ Kotlin Extensions
- ๐ Log Extensions
- ๐งฎ Math Extensions
- ๐ถ Network Extensions
- ๐ฆ Permission Extensions
- ๐ฌ Shared Preferences Extensions
- ๐ Snackbar Extensions
- ๐งฌ String Extensions
- ๐ System Extensions
- ๐ Toast Extensions
- โ Validate Extensions
Update App Theme in styles.xml
with DayNight
Material Theme. More details are at Official Material Design Site.
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Original AppCompat attributes. -->
<!-- Define colors in colors.xml -->
<item name="colorPrimary">YOUR_PRIMARY_COLOR</item>
<item name="colorSecondary">YOUR_SECONDARY_COLOR</item>
<item name="android:colorBackground">@color/meow_background</item>
<!-- New MaterialComponents attributes. -->
<item name="colorPrimaryVariant">YOUR_PRIMARY_VARIANT_COLOR</item>
<item name="colorSecondaryVariant">YOUR_SECONDARY_VARIANT_COLOR</item>
<item name="colorOnPrimary">YOUR_ON_PRIMARY_COLOR</item>
<item name="colorOnSecondary">YOUR_ON_SECONDARY_COLOR</item>
<item name="colorSurface">@color/meow_surface</item>
<item name="colorOnSurface">@color/meow_on_surface</item>
<item name="colorOnBackground">@color/meow_on_background</item>
<item name="colorError">@color/meow_error</item>
<item name="colorOnError">@color/meow_on_error</item>
<item name="scrimBackground">@color/mtrl_scrim_color</item>
</style>
Just do same as styles_text_appearances.xml.
You must apply styles in
AppTheme
.<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar" > <item name="textAppearanceHeadline1">@style/App.TextAppearance.Headline1</item> <item name="textAppearanceHeadline2">@style/App.TextAppearance.Headline2</item> <item name="textAppearanceHeadline3">@style/App.TextAppearance.Headline3</item> <item name="textAppearanceHeadline4">@style/App.TextAppearance.Headline4</item> <item name="textAppearanceHeadline5">@style/App.TextAppearance.Headline5</item> <item name="textAppearanceHeadline6">@style/App.TextAppearance.Headline6</item> <item name="textAppearanceSubtitle1">@style/App.TextAppearance.Subtitle1</item> <item name="textAppearanceSubtitle2">@style/App.TextAppearance.Subtitle2</item> <item name="textAppearanceBody1">@style/App.TextAppearance.Body1</item> <item name="textAppearanceBody2">@style/App.TextAppearance.Body2</item> <item name="textAppearanceCaption">@style/App.TextAppearance.Caption</item> <item name="textAppearanceButton">@style/App.TextAppearance.Button</item> <item name="textAppearanceOverline">@style/App.TextAppearance.Overline</item> </style>
You can show Alert Dialog with alert()
function in MeowActivity/MeowFragment
.
fun testAlert() {
alert(R.string.alert_title,R.string.alert_message)
.setPositiveButton(R.string.ok) { d, _ ->
toastL(R.string.alerts_warn_ok_clicked)
d.dismiss()
}
.setNegativeButton(R.string.cancel) { d, _ ->
toastL(R.string.alerts_warn_cancel_clicked)
d.dismiss()
}.show()
}
A Dialog with MeowLoadingView
to showing progress bar with text into Dialog.
fun testLoadingAlertDialog() {
loadingAlert(R.string.loading_title_custom).show()
}
Learn more about it at AlertsFragment.kt.
There are some customized styles that is related to Material Button
.
Style | Usage |
---|---|
Meow.Button |
Regular Button with primary background color |
Meow.Button.Outlined |
Outlined Button with transparent background color and stroke_color.xml outline color |
Meow.Button.Flat |
Flat Button with transparent background color |
Meow.Button.Unelevated |
Regular Button with primary background color with 0dp elevation |
Meow.Button.IconOnly |
A Meow Button that shows has not text |
Use it like this in XML Layout :
<LinearLayout>
<Button
style="@style/Meow.Button"
android:text="SomeRegularButton" />
<Button
style="@style/Meow.Button"
android:textColor="?colorOnSecondaryVariant"
android:text="SomeCustomizedButton"
app:backgroundTint="?colorSecondaryVariant" />
</LinearLayout>
Learn more about it at Material Card Component and fragment_cards.xml.
There are some customized styles that is related to Material CardView
.
Style | Usage |
---|---|
Meow.CardView |
Regular Card with surface background color |
Meow.CardView.Outlined |
Outlined Card with surface background color and stroke_color.xml outline color |
Use it like this in XML Layout :
<com.google.android.material.card.MaterialCardView
style="@style/Meow.CardView"
app:contentPadding="16dp" >
<!-- Place your views here -->
</com.google.android.material.card.MaterialCardView>
Learn more about it at Material Card Component and fragment_cards.xml.
There are some customized styles that is related to Material CheckBox
.
Style | Usage |
---|---|
Meow.Checkbox |
Checkbox with accent_color button tint |
Meow.Checkbox.Primary |
Checkbox with primary button tint |
Meow.Checkbox.Secondary |
Checkbox with secondary button tint |
Meow.Checkbox.OnPrimary |
Checkbox with onPrimary button tint & textColor |
Meow.Checkbox.OnSecondary |
Checkbox with onSecondary button tint & textColor |
Use it like this in XML Layout :
<com.google.android.material.checkbox.MaterialCheckBox
style="@style/Meow.Checkbox"
android:text="@string/checkbox_text" />
Learn more about it at Material Checkbox Component and fragment_checkboxes.xml.
Use it like this in XML Layout :
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
style="@style/Meow.RecyclerView.Linear"
app:meow_items="@{viewModel.listLiveData}" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
style="@style/Meow.FloatingActionButton"
android:onClick="@{viewModel::onClickedFab}"
app:icon="@drawable/ic_add"
app:layout_anchor="@id/recyclerView"
app:layout_anchorGravity="bottom|center_horizontal" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Learn more about it at Material Floating Action Button Component and fragment_fab_simple.xml.
A FAB that supports android:text
property.
Use it like this in XML Layout :
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
style="@style/Meow.FloatingActionButton.Extended"
android:onClick="@{viewModel::onClickedFab}"
android:text="@string/fab_extended_text"
app:icon="@drawable/ic_add"
app:layout_anchor="@id/recyclerView"
app:layout_anchorGravity="bottom|center_horizontal" />
Learn more about it at Material Extended Floating Action Button Component and fragment_fab_simple.xml.
There are some customized styles that is related to Material Radio Group
.
Style | Usage |
---|---|
Meow.RadioGroup.Horizontal |
RadioGroup with Horizontal Radio Buttons |
Meow.RadioGroup.Vertical |
RadioGroup with Vertical Radio Buttons |
There are some customized styles that is related to Material Radio Button
.
Style | Usage |
---|---|
Meow.RadioButton.Vertical |
Vertical RadioButton with accent_color button tint |
Meow.RadioButton.Horizontal |
Horizontal RadioButton with accent_color button tint |
Meow.RadioButton.Vertical.Primary |
Vertical RadioButton with primary button tint |
Meow.RadioButton.Horizontal.Primary |
Horizontal RadioButton with primary button tint |
Meow.RadioButton.Vertical.Secondary |
Vertical RadioButton with secondary button tint |
Meow.RadioButton.Horizontal.Secondary |
Horizontal RadioButton with secondary button tint |
Meow.RadioButton.Vertical.OnPrimary |
Vertical RadioButton with onPrimary button tint & textColor |
Meow.RadioButton.Horizontal.OnPrimary |
Horizontal RadioButton with onPrimary button tint & textColor |
Meow.RadioButton.Vertical.OnSecondary |
Vertical RadioButton with onSecondary button tint & textColor |
Meow.RadioButton.Horizontal.OnSecondary |
Horizontal RadioButton with onSecondary button tint & textColor |
Use it like this in XML Layout :
<RadioGroup style="@style/Meow.RadioGroup.Vertical">
<com.google.android.material.radiobutton.MaterialRadioButton
style="@style/Meow.RadioButton.Vertical.Primary"
android:text="@string/radio_buttons_option_a" />
<com.google.android.material.radiobutton.MaterialRadioButton
style="@style/Meow.RadioButton.Vertical.Primary"
android:text="@string/radio_buttons_option_b" />
</RadioGroup>
Learn more about it at Material Radio Button Component and fragment_radio_buttons.xml.
You can show Snack Bars with snackL()
or snackS()
functions in MeowActivity/MeowFragment
.
fun testSnackbars(){
// Shows Snack Bars with LENGTH_SHORT.
snackS(R.string.snackbars_message)
// Shows Snack Bars with LENGTH_LONG.
snackL(R.string.snackbars_message)
// Shows Snack Bars with LENGTH_INDEFINITE.
snackI(R.string.snackbars_message)
// Shows Snack Bars with LENGTH_LONG with action button.
snackL(
message = R.string.snackbars_message,
resActionText = R.string.snackbars_action,
// Optional - if you want to set custom textAppearances to message and action, set this attributes.
messageTextAppearanceId = R.style.textAppearance_Snack_Message,
actionTextAppearanceId = R.style.textAppearance_Snack_Action
) {
// Callback for action button click
}
}
Learn more about it at SnackBarsFragment.
There are some customized styles that is related to Material Switch
.
Style | Usage |
---|---|
Meow.Switch |
Switch with accent_color button tint |
Meow.Switch.Primary |
Switch with primary button tint |
Meow.Switch.Secondary |
Switch with secondary button tint |
Meow.Switch.OnPrimary |
Switch with onPrimary button tint & textColor |
Meow.Switch.OnSecondary |
Switch with onSecondary button tint & textColor |
Use it like this in XML Layout :
<com.google.android.material.switchmaterial.SwitchMaterial
style="@style/Meow.Switch"
android:text="@string/switch_text" />
Learn more about it at Material Switch Component and fragment_switches.xml.
If you want to show contents into a ViewPager, we recommend to use ViewPager2
. TabLayout
is the indicator of ViewPager state. Follow below steps to have a View with Swipe Gesture.
<layout>
<data />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
style="@style/Meow.TabLayout.Surface" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
style="@style/Meow.ViewPager" />
</LinearLayout>
</layout>
class MyPagerAdapter(
fragmentManager: FragmentManager,
lifecycle: Lifecycle) : MeowPagerAdapter(fragmentManager, lifecycle) {
// Replace this with the array of Fragments that you want to show into ViewPager.
private val fragmentArray = Array<Fragment>(3) { ChildFragment.newInstance(it) }
override fun getFragments() = fragmentArray
}
fun onCreate(savedInstanceState: Bundle?) {
// ...
binding.apply {
binding.viewPager.adapter = MyPagerAdapter(childFragmentManager, lifecycle)
TabLayoutMediator(tabLayout, viewpager) { tab, position ->
tab.text = "Tab Title #" + (position + 1) // Set Tab titles here.
}.attach()
// Optional - If you want to show Material Badge on TabLayout.
tabLayout.getTabAt(0)?.orCreateBadge?.apply {
isVisible = true
number = 10
}
}
}
Now you have ViewPager2
+ TabLayout
in an Activity/Fragment.
There are some customized styles that is related to Material TabLayout
.
Style | Usage |
---|---|
Meow.TabLayout.Surface |
TabLayout with surface background color |
Meow.TabLayout.Primary |
TabLayout with primary background color |
Meow.TabLayout.Secondary |
TabLayout with primary background color |
Meow.TabLayout.PrimarySurface |
TabLayout with primary background color in DAY mode and surface background color in NIGHT Mode |
Learn more about it at Material TabLayout Component.
Use it like this in XML Layout :
<TextView
style="@style/Meow.TextView"
android:text="@string/some_text"
android:textAppearance="?textAppearanceBody1"
android:textColor="@color/on_background_high" />
Learn more about it at fragment_textviews.xml.
Colors for texts based on Material Colors which contains EMPHASIS_HIGH
, EMPHASIS_MEDIUM
, DISABLED
states.
Color | Value |
---|---|
@color/on_background_high |
onBackground color with %87 transparency |
@color/on_background_medium |
onBackground color with %60 transparency |
@color/on_background_disabled |
onBackground color with %38 transparency |
@color/on_surface_high |
onSurface color with %87 transparency |
@color/on_surface_medium |
onSurface color with %60 transparency |
@color/on_surface_disabled |
onSurface color with %38 transparency |
@color/on_primary_high |
onPrimary color with %87 transparency |
@color/on_primary_medium |
onPrimary color with %60 transparency |
@color/on_primary_disabled |
onPrimary color with %38 transparency |
@color/on_secondary_high |
onSecondary color with %87 transparency |
@color/on_secondary_medium |
onSecondary color with %60 transparency |
@color/on_secondary_disabled |
onSecondary color with %38 transparency |
Use it like this in XML Layout :
<layout>
<data/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Meow.Toolbar.Surface" />
</com.google.android.material.appbar.AppBarLayout>
<!-- Main Layout -->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
There are some customized styles that is related to Material Toolbar
.
Style | Usage |
---|---|
Meow.Toolbar.Surface |
Toolbar with surface background color |
Meow.Toolbar.PrimarySurface |
Toolbar with primary background color in DAY mode and surface background color in NIGHT Mode |
Meow.Toolbar.Primary |
Toolbar with primary background color |
Meow.Toolbar.Secondary |
Toolbar with secondary background color |
Learn more about it at Material Top App Bars Component.
Meow CircleImageView Attributes:
Attributes | Descriptions |
---|---|
meow_strokeColor |
The stroke color of image |
meow_strokeWidth |
The stroke width of image |
Use it like this in XML Layout :
<meow.widget.MeowCircleImageView
android:layout_width="56dp"
android:layout_height="56dp"
app:meow_strokeColor="@color/white"
app:meow_strokeWidth="2dp"
app:srcCompat="@drawable/avatar" />
Learn more about it at fragment_imageviews.xml.
There are some styles that is related to Dash View
.
Style | Usage |
---|---|
Meow.Dash.Horizontal |
DashView with Horizontal orientation |
Meow.Dash.Horizontal.Primary |
DashView with Horizontal orientation and primary color |
Meow.Dash.Horizontal.PrimaryVariant |
DashView with Horizontal orientation and PrimaryVariant color |
Meow.Dash.Horizontal.PrimarySurface |
DashView with Horizontal orientation and PrimarySurface color |
Meow.Dash.Horizontal.Secondary |
DashView with Horizontal orientation and secondary color |
Meow.Dash.Horizontal.SecondaryVariant |
DashView with Horizontal orientation and SecondaryVariant color |
Meow.Dash.Horizontal.OnPrimary |
DashView with Horizontal orientation and OnPrimary color |
Meow.Dash.Horizontal.OnSecondary |
DashView with Horizontal orientation and OnSecondary color |
Meow.Dash.Horizontal.OnSurface |
DashView with Horizontal orientation and OnSurface color |
Meow.Dash.Vertical |
DashView with Vertical orientation |
Meow.Dash.Vertical.Primary |
DashView with Vertical orientation and primary color |
Meow.Dash.Vertical.PrimaryVariant |
DashView with Vertical orientation and PrimaryVariant color |
Meow.Dash.Vertical.PrimarySurface |
DashView with Vertical orientation and PrimarySurface color |
Meow.Dash.Vertical.Secondary |
DashView with Vertical orientation and secondary color |
Meow.Dash.Vertical.SecondaryVariant |
DashView with Vertical orientation and SecondaryVariant color |
Meow.Dash.Vertical.OnPrimary |
DashView with Vertical orientation and OnPrimary color |
Meow.Dash.Vertical.OnSecondary |
DashView with Vertical orientation and OnSecondary color |
Meow.Dash.Vertical.OnSurface |
DashView with Vertical orientation and OnSurface color |
Meow Dash Attributes:
Attributes | Descriptions |
---|---|
meow_dash_gap |
Dash Gap |
meow_dash_length |
Dash length |
meow_dash_thickness |
Dash thickness |
meow_dash_color |
Dash color |
Use it like this in XML Layout :
<meow.widget.MeowDashView
app:meow_dash_gap="4dp"
app:meow_dash_length="8dp"
app:meow_dash_thickness="2dp" />
Learn more about it at fragment_dash.xml.
There are some styles that is related to Divider
.
Style | Usage |
---|---|
Meow.Divider.Horizontal |
Divider with Horizontal orientation |
Meow.Divider.Vertical |
Divider with Vertical orientation |
Meow.Divider.Horizontal.OnPrimary |
Divider with Horizontal orientation and primary divider background type |
Meow.Divider.Horizontal.OnSecondary |
Divider with Horizontal orientation and secondary divider background type |
Meow.Divider.Horizontal.OnSurface |
Divider with Horizontal orientation and surface divider background type |
Meow.Divider.Vertical.OnPrimary |
Divider with Vertical orientation and primary divider background type |
Meow.Divider.Vertical.OnSecondary |
Divider with Vertical orientation and secondary divider background type |
Meow.Divider.Vertical.OnSurface |
Divider with Vertical orientation and surface divider background type |
Meow Divider Attributes:
Attributes | Descriptions |
---|---|
meow_orientation |
Orientation: vertical or horizontal |
meow_background_type |
Types: background ,surface ,secondary ,primary |
Use it like this in XML Layout :
You just need use style.๐
<meow.widget.MeowDivider style="@style/Meow.Divider.Horizontal" />
Learn more about it at fragment_dividers.xml.
There are some styles that is related to Empty State
.
Style | Usage |
---|---|
Meow.EmptyState |
EmptyState default style with icon size and icon tint |
Meow.EmptyState.OnBackground |
EmptyState with title and description OnBackground color |
Meow.EmptyState.OnPrimary |
EmptyState with title and description OnPrimary color |
Meow.EmptyState.OnSecondary |
EmptyState with title and description OnSecondary colore |
Meow.EmptyState.OnSurface |
EmptyState with title and description OnSurface color |
Meow Empty state Attributes:
Attributes | Descriptions |
---|---|
meow_icon |
Icon resource |
meow_iconSize |
Icon size |
meow_iconTint |
Icon tint color |
meow_title |
Title text |
meow_titleTextColor |
Title text color |
meow_desc |
Description text |
meow_descTextColor |
Description text color |
meow_primaryActionText |
Button text |
Use it like this in XML Layout :
<meow.widget.MeowEmptyState
android:id="@+id/emptyState"
style="@style/Meow.EmptyState.OnBackground" />
Not Completed yet!.
There are some styles that is related to Hint Button
.
Style | Usage |
---|---|
Meow.HintButton |
HintButton default style with icon color |
Meow HintButton Attributes:
Attributes | Descriptions |
---|---|
meow_hint |
Hint text |
meow_hintColor |
Hint text color |
meow_hintTextAppearance |
Hint textAppearance |
meow_title |
Title text |
meow_titleColor |
Title text color |
meow_titleTextAppearance |
Title textAppearance |
meow_icon |
Icon resource |
meow_iconColor |
Icon color |
Use it like this in XML Layout :
<meow.widget.MeowHintButton
style="@style/Meow.HintButton"
app:meow_hint="@string/date"
app:meow_icon="@drawable/ic_date"
app:meow_title="@string/date_num" />
Learn more about it at fragment_form.xml.
There are some styles that is related to PinView
.
Style | Usage |
---|---|
Meow.PinView.Filled |
PinView Filled box style |
Meow.PinView.Outlined |
PinView Outlined box style |
Meow PinView Attributes:
Attributes | Descriptions |
---|---|
meow_hint |
Hint text |
meow_hintColor |
Hint text color |
meow_hintTextAppearance |
Hint textAppearance |
meow_count |
Length of pin (box count) |
meow_textColor |
Boxes text color |
meow_textAppearance |
Boxes textAppearance |
meow_icon |
Icon resource |
meow_iconTint |
Icon color |
meow_showBack |
Show clear boxes text |
meow_errorTextAppearance |
Error textAppearance |
meow_boxStyle |
Styles: outlined or filled |
Use it like this in XML Layout :
<meow.widget.MeowPinView
android:id="@+id/pv"
style="@style/Meow.PinView.Filled"
app:meow_hint="@string/enter_code"
app:meow_icon="@drawable/ic_dialpad" />
Learn more about it at fragment_form.xml.
There are some styles that is related to ProgressBar
.
Style | Usage |
---|---|
Meow.ProgressBar.Small |
Small ProgressBar |
Meow.ProgressBar.Small.Primary |
Small ProgressBar with primary color |
Meow.ProgressBar.Small.PrimaryVariant |
Small ProgressBar with PrimaryVariant color |
Meow.ProgressBar.Small.PrimarySurface |
Small ProgressBar with PrimarySurface color |
Meow.ProgressBar.Small.Secondary |
Small ProgressBar with secondary color |
Meow.ProgressBar.Small.SecondaryVariant |
Small ProgressBar with SecondaryVariant color |
Meow.ProgressBar.Small.OnPrimary |
Small ProgressBar with OnPrimary color |
Meow.ProgressBar.Small.OnSecondary |
Small ProgressBar with OnSecondary color |
Meow.ProgressBar.Small.OnSurface |
Small ProgressBar with OnSurface color |
Meow.ProgressBar.Medium |
Medium ProgressBar |
Meow.ProgressBar.Medium.Primary |
Medium ProgressBar with primary color |
Meow.ProgressBar.Medium.PrimaryVariant |
Medium ProgressBar with PrimaryVariant color |
Meow.ProgressBar.Medium.PrimarySurface |
Medium ProgressBar with PrimarySurface color |
Meow.ProgressBar.Medium.Secondary |
Medium ProgressBar with secondary color |
Meow.ProgressBar.Medium.SecondaryVariant |
Medium ProgressBar with SecondaryVariant color |
Meow.ProgressBar.Medium.OnPrimary |
Medium ProgressBar with OnPrimary color |
Meow.ProgressBar.Medium.OnSecondary |
Medium ProgressBar with OnSecondary color |
Meow.ProgressBar.Medium.OnSurface |
Medium ProgressBar with OnSurface color |
Meow.ProgressBar.Large |
Large ProgressBar |
Meow.ProgressBar.Large.Primary |
Large ProgressBar with primary color |
Meow.ProgressBar.Large.PrimaryVariant |
Large ProgressBar with PrimaryVariant color |
Meow.ProgressBar.Large.PrimarySurface |
Large ProgressBar with PrimarySurface color |
Meow.ProgressBar.Large.Secondary |
Large ProgressBar with secondary color |
Meow.ProgressBar.Large.SecondaryVariant |
Large ProgressBar with SecondaryVariant color |
Meow.ProgressBar.Large.OnPrimary |
Large ProgressBar with OnPrimary color |
Meow.ProgressBar.Large.OnSecondary |
Large ProgressBar with OnSecondary color |
Meow.ProgressBar.Large.OnSurface |
Large ProgressBar with OnSurface color |
Meow ProgressBar Attributes:
Attributes | Descriptions |
---|---|
meow_showOnInit |
Specify that the progress can be show on Initialization |
Use it like this in XML Layout :
<meow.widget.MeowProgressBar
style="@style/Meow.ProgressBar.Small.Primary"
app:meow_showOnInit="true" />
Learn more about it at fragment_progress_bars.xml.
There are some styles that is related to RatingBar
.
Style | Usage |
---|---|
Meow.RatingBar |
RatingBar with default style |
Meow.RatingBar.Indicator |
RatingBar with enabled Indicator style (just show and not clickable) |
Meow RatingBar Attributes:
Attributes | Descriptions |
---|---|
meow_numStars |
The number of stars |
meow_minimumStars |
The minimum selected stars |
meow_rating |
Show while when use it |
meow_starPadding |
Stars padding |
meow_drawableEmpty |
Stars drawable when is empty |
meow_drawableFilled |
Stars drawable when is filled |
meow_isIndicator |
Specify that it is indicator or not |
meow_scrollable |
Specify that it is scrollable or not |
meow_clickable |
Specify that it is clickable or not |
meow_clearRatingEnabled |
Specify that clearRating is enabled or not |
meow_starWidth |
Stars Width |
meow_starHeight |
Stars Height |
meow_stepSize |
Step Size |
Use it like this in XML Layout :
<meow.widget.MeowRatingBar
style="@style/Meow.RatingBar"
app:meow_drawableEmpty="@drawable/ic_star"
app:meow_drawableFilled="@drawable/ic_star_fill"
app:meow_numStars="5"
app:meow_stepSize="0.5" />
Learn more about it at fragment_rating_bars.xml.
With this widget, you no longer need to check the form fields (like editTexts and spinners) one by one.
Use it like this in XML Layout :
<meow.widget.MeowFormView
android:id="@+id/fv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:resetForm="true">
<!-- You can add MeowTextField,MeowSpinner,Button and other views in this layout -->
</meow.widget.MeowFormView>
You can call validate()
function to validate all widgets which are in MeowFormView
as children :
binding.fv.validate {
// When MeowFormView validate all widgets with their validate type, this line runs.
}
Learn more about it at fragment_form.xml.
There are some styles that is related to Spinner
.
Style | Usage |
---|---|
Meow.Spinner.Outlined |
Spinner with outlined style |
Meow.Spinner.Outlined.Dense |
Spinner with outlined dense style |
Meow.Spinner.Filled |
Spinner with Filled style |
Meow.Spinner.Filled.Dense |
Spinner with Filled dense style |
If you want to use Validation Feature, you should add
MeowSpinner
toFormView
Layout.
Attributes | Descriptions |
---|---|
meow_validateType |
Types: empty ,optional |
meow_errorEmpty |
Error empty Text (when spinner was empty you can show your customize error) |
Use it like this in XML Layout :
<meow.widget.MeowSpinner
style="@style/Meow.Spinner.Outlined"
android:hint="@string/select"
app:meow_validateType="empty" />
And for add Item in MeowSpinner
:
Supports : title , description and icon
binding.spinner
.addItem(R.string.item1, R.string.description1, R.drawable.ic_error)
.addItem(R.string.item2, R.string.description2, R.drawable.ic_error)
.addItem(R.string.item3, imageViewResId = R.drawable.ic_error)
.addItem(R.string.item4, imageViewResId = R.drawable.ic_error)
.addItem(R.string.item5, R.string.description3)
.addItem(R.string.item6, R.string.description4)
.addItem(R.string.item7)
.addItem(R.string.item8)
.build()
Learn more about it at Material Exposed Dropdown Menu Component and fragment_form.xml.
There are some styles that is related to TextField
.
Style | Usage |
---|---|
Meow.TextField.Outlined |
TextField with outlined style |
Meow.TextField.Outlined.Dense |
TextField with outlined dense style |
Meow.TextField.Filled |
TextField with Filled style |
Meow.TextField.Filled.Dense |
TextField with Filled dense style |
Meow TextField Attributes:
For use validation Feature you should add
MeowTextField
toFormView
Layout.If the error text is blank, the default message will be displayed.
Attributes | Descriptions |
---|---|
meow_validateType |
Types: empty ,mobile ,mobileLegacy ,email ,optional |
meow_errorEmpty |
Error empty Text (when textfield was empty you can show your customize error) |
meow_errorMobile |
Error invalid mobile number |
meow_errorMobileLegacy |
Error invalid mobile legacy (persian) number |
meow_errorEmail |
Error invalid email |
meow_textSize |
TextField text size |
meow_inputType |
Default android TextInputLayout input type |
Use it like this in XML Layout :
<meow.widget.MeowTextField
style="@style/Meow.TextField.Filled"
android:hint="@string/email"
app:errorEnabled="true"
app:meow_inputType="textEmailAddress"
app:meow_validateType="email"
app:startIconDrawable="@drawable/ic_android" />
Learn more about it at Material TextField Component and fragment_form.xml.
Just include rules of proguard-rules.pro at your application Proguard config file.
If you want to contribute to this project, just send an email to oneHamidreza@gmail.com with Meow-Framework-Contributing
subject.
Copyright 2020 Hamidreza Etebarian
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.