diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 3c7772a..7643783 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,22 +1,6 @@ - - diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 0b8c8e2..99f581a 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -15,7 +15,6 @@ - diff --git a/.idea/misc.xml b/.idea/misc.xml index ef61796..ae9f4f1 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,13 @@ + + + diff --git a/README.md b/README.md index 2bcb65f..81b3b1e 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,15 @@ * Commons utils and extention * Support MVVM pattern with BaseViewModel * Network Configuration -* WebViewActivity used/ call this directly to show webview +* WebViewActivity used/ call this directly to show webview * BaseActivity and BaseFragment ## How to use + +### Add to Project + Gradle + ``` allprojects { repositories { @@ -23,7 +27,9 @@ dependencies { implementation 'com.github.mncinnovation:mnc-android-code-standard-core:0.1.3' } ``` + or Maven + ``` @@ -39,6 +45,213 @@ or Maven ``` +### Implementation + +1. BaseActivity + +```kotlin +class MainActivity : BaseActivity() { + private lateinit var binding: ActivityMainBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + showToolbarBack(false) + showToolbarTitle(false) + } +} +``` + +2. BaseViewModel + +- Handle Result from com.mncgroup.core.network.Result (To Handle result from any data model) +- Common live event, like _isLoading, showErrorDialog, navigateToLogin and more. + +```kotlin +class LoginViewModel constructor( + private val authRepository: AuthRepository, + userRepository: UserRepository +) : BaseViewModel() { + + val userData: LiveData> = userRepository.getUserLiveData() + + @OptIn(DelicateCoroutinesApi::class) + fun authLogin(email: String, password: String) { + _isLoading.value = true + GlobalScope.launch(Dispatchers.Main) { + val result = authRepository.requestLogin(LoginRequest(email, password)) + result.handle { + //handle result ok + _isLoading.value = false + } + } + } +} +``` + +3. WebViewActivity, an activity class to show webview. You can use ``WebViewActivity`` + directly from your project. + +```kotlin + val headers: MutableMap = mutableMapOf() + headers["token"] = "5454wvybw9y9" + startActivity( + Intent(this@MainActivity, WebViewActivity::class.java) + .apply { + putExtra(EXTRA_TITLE, "Webview") + putExtra(EXTRA_HEADERS, headers.toMap() as Serializable) + data = Uri.parse("https://cloud.google.com/speech-to-text/docs/libraries") + } + ) +``` + +4. Load Image + +Easy load image by accessing ImageView extensions. + ![image view extension](docs/image/imageViewExtension.jpg) + +```kotlin + ivImage.load("https://img.shields.io/github/v/release/mncinnovation/mnc-android-code-standard-core.svg?label=latest") +``` + +5. Snackbar + +```kotlin + btnShowSnackbar.setOnClickListener { + showSnackbar(it, "Ini snackbar") { + Toast.makeText(this@MainActivity, "closed snackbar", Toast.LENGTH_SHORT).show() + } +} +``` + +6. Intens + +There is an Intents object that contain functions that return Intent + ![Intents](docs/image/intents.jpg) + +```kotlin + btnOpenLocationSetting.setOnClickListener { + startActivity(Intents.createOpenLocationSettings()) +} +``` + +7. AppCompatAlert + +Show appCompatAlert or with action, or with input action. + ![showAppCompatAlert Options](docs/image/showAppCompatAlertOption.jpg) + +```kotlin + btnShowAppCompatAlertAction.setOnClickListener { + showAppCompatAlert("This is a message") { + Toast.makeText(this@MainActivity, "Test", Toast.LENGTH_SHORT).show() + } +} +``` + +8. Date Picker +```kotlin + btnShowDatePicker.setOnClickListener { + showDatePickerAction(null, null) { day, month, year -> + Toast.makeText( + this@MainActivity, "selected date is " + day + + " / " + month + + " / " + year, Toast.LENGTH_SHORT + ).show() + }.show() +} +``` + +9. Permissions + +Check any permissions and request permissions. + +```kotlin + private fun checkPermissionOrOpenCamera() { + when (checkPermissionsAll( + listOf( + Manifest.permission.CAMERA, + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) + )) { + PermissionResult.Granted -> openFileChooser() + PermissionResult.DialogNeeded, PermissionResult.NeedRequest -> { + requestPermissions( + RC_CAMERA, + Manifest.permission.CAMERA, + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) + } + } +} + +``` + +10. Internet Util + +This is an object to help app check internet connection. +First need to init in application class. +```kotlin +class AppNameApplication : Application() { + override fun onCreate() { + super.onCreate() + //init internet util + InternetUtil.init(this) + } +} +``` + +And to use it call ``runIfConnectedOrResultException`` and place call of function API at the body like this sample. + +```kotlin + +interface AuthRepository { + suspend fun requestLogin(request: LoginRequest): Result +} + +class AuthRepositoryImpl(private val authApi: AuthApi, private val userRepository: UserRepository) : + AuthRepository { + @OptIn(ExperimentalCoroutinesApi::class) + override suspend fun requestLogin(request: LoginRequest): Result { + return runIfConnectedOrResultException { + authApi.loginUser(request).awaitResult() { + userRepository.updateUser(this.user) + this + } + } + } +} +``` + +11. View Extensions + +Common functions for view configurations. +- ``View.hideKeyboard()`` and ``View.showKeyboard()`` +- ``View.toBitmap()`` +- ``Boolean?.toVisibleOrGone()`` +- ``Boolean?.toVisibleOrInvisible()`` +- ``Context.dip(value: Int)`` + +12. Arguments + +Start an Activity for given class T and allow to work on intent with "run" lambda function +- `` T.withSerializable(vararg arguments: Pair)`` +- `` T.withParcelable(vararg arguments: Pair): T`` + Retrieve property from intent +- `` AppCompatActivity.argument(key: String) : T`` +- `` AppCompatActivity.argument(key: String, defaultValue: T? = null) : T`` +- `` AppCompatActivity.argumentNotNull(key: String, defaultValue: T) : T`` +- `` Fragment.argument(key: String) : T`` +- `` Fragment.argument(key: String, defaultValue: T? = null) : T`` +- `` Fragment.argumentNotNull(key: String, defaultValue: T) : T`` +13. ConfigUtils + +Configuration for resources locale +- ``Context.updateResourcesLocale(locale: Locale): Context`` +- ``Context.updateResourcesLocaleLegacy(locale: Locale): Context`` +- ``Context.updateBaseContextLocale(locale: Locale): Context`` +- ``Context.updateResourcesLocale(body: Configuration.() -> Unit): Context`` +- ``Context.updateBaseContextLocaleWithoutChange(locale: Locale): Context`` + ## License ``` diff --git a/app/build.gradle b/app/build.gradle index a343774..4de1a29 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -108,6 +108,7 @@ dependencies { implementation project(':core') implementation "io.insert-koin:koin-android:$koin_version" implementation "androidx.appcompat:appcompat:$appcompat_version" + implementation "com.google.android.material:material:$material_version" testImplementation "junit:junit:$junit_version" androidTestImplementation "androidx.test.ext:junit:$androidx_junit" diff --git a/app/src/main/java/com/mncgroup/mnccore/ui/MainActivity.kt b/app/src/main/java/com/mncgroup/mnccore/ui/MainActivity.kt index 2be4de3..f9c1bb3 100644 --- a/app/src/main/java/com/mncgroup/mnccore/ui/MainActivity.kt +++ b/app/src/main/java/com/mncgroup/mnccore/ui/MainActivity.kt @@ -1,22 +1,32 @@ package com.mncgroup.mnccore.ui -import android.app.Activity +import android.content.Intent +import android.net.Uri import android.os.Bundle import android.widget.Toast +import com.mncgroup.core.ui.BaseActivity +import com.mncgroup.core.ui.EXTRA_HEADERS +import com.mncgroup.core.ui.EXTRA_TITLE +import com.mncgroup.core.ui.WebViewActivity import com.mncgroup.core.util.ext.* +import com.mncgroup.core.util.load import com.mncgroup.mnccore.databinding.ActivityMainBinding +import java.io.Serializable -class MainActivity : Activity() { +class MainActivity : BaseActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - with(binding){ + with(binding) { + ivImage.load("https://img.shields.io/github/v/release/mncinnovation/mnc-android-code-standard-core.svg?label=latest") + btnShowSnackbar.setOnClickListener { - showSnackbar(it,"Ini snackbar"){ + showSnackbar(it, "Ini snackbar") { Toast.makeText(this@MainActivity, "closed snackbar", Toast.LENGTH_SHORT).show() } } @@ -27,25 +37,43 @@ class MainActivity : Activity() { startActivity(Intents.createOpenLocationSettings()) } btnShowAppCompatAlertAction.setOnClickListener { - showAppCompatAlert("This is a message"){ + showAppCompatAlert("This is a message. Will open web view") { Toast.makeText(this@MainActivity, "Test", Toast.LENGTH_SHORT).show() + val headers: MutableMap = mutableMapOf() + headers["token"] = "5454wvybw9y9" + startActivity( + Intent(this@MainActivity, WebViewActivity::class.java) + .apply { + putExtra(EXTRA_TITLE, "Webview") + putExtra(EXTRA_HEADERS, headers.toMap() as Serializable) + data = + Uri.parse("https://cloud.google.com/speech-to-text/docs/libraries") + } + ) } } btnShowInputName.setOnClickListener { - showAppCompatAlertInputAction("Please to Input Fullname","Input","Kirim","Kembali","Fullname",true) { input -> - Toast.makeText(this@MainActivity, "Namanya adalah : $input", Toast.LENGTH_SHORT).show() + showAppCompatAlertInputAction( + "Please to Input Fullname", + "Input", + "Kirim", + "Kembali", + "Fullname", + true + ) { input -> + Toast.makeText(this@MainActivity, "Namanya adalah : $input", Toast.LENGTH_SHORT) + .show() } } btnShowDatePicker.setOnClickListener { - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - showDatePickerAction(null,null) { day, month, year -> - Toast.makeText(this@MainActivity, "selected date is " + day + + showDatePickerAction(null, null) { day, month, year -> + Toast.makeText( + this@MainActivity, "selected date is " + day + " / " + month + - " / " + year, Toast.LENGTH_SHORT).show() - }.show() - } + " / " + year, Toast.LENGTH_SHORT + ).show() + }.show() } } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e70778f..b9b92b4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,97 +1,110 @@ - + android:background="@color/white" + android:orientation="vertical"> - -