- Adapter
- [TabPagerAdapter]
- Base
- Common
- [SafeClickListener]
- SingleLiveData
- Dialog
- Extension
- Custom UI
- Utils
- Other
- [RecyclerViewEndlessScrollListener]
- AppPrefs
dependencies {
implementation 'io.github.imanfz:android-utils:{latest version}'
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
...
}
or if you have custom BaseActivity, you can extends it:
class BaseActivity<B : ViewBinding> : BaseActivity<B>() {
...
}
class SampleSheet : BaseBottomSheetDialog<FragmentSampleSheetBinding>() {
...
}
class SampleFragment : BaseFragment<FragmentSampleBinding>() {
...
}
or if you have custom BaseFragment, you can extends it:
class BaseFragment<B : ViewBinding> : BaseFragment<B>() {
...
}
for handle bug live data in fragment after on backstack
val dataState = SingleLiveData<String>()
val image = url or uri.toString()
ImageViewerDialog.newInstance(image).show(supportFragmentManager, tag)
class MainActivity : BaseActivity<ActivityMainBinding>() {
...
binding.apply {
btnLoading.setSafeOnClickListener {
showLoading()
lifecycle.coroutineScope.apply {
launch {
delay(3000)
hideLoading()
}
}
}
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
// keyboard
hidekeyboard()
showKeyboard()
// SnackBar
longSnack("Hello World")
shortSnack("Hello World")
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
private val listPermission = listOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
// Toast
longToast("Hello World")
shortToast("Hello World")
if (hasPermission(Manifest.permission.CAMERA)) {
logi("GRANTED")
}
if(hasPermission(listPermission.toTypedArray())) {
logi("GRANTED")
} else {
requestPermission()
}
startActivity<HomeActivity>()
// or
startActivity<HomeActivity>(Bundle().apply{
putString("A", "tes")
})
startActivity<HomeActivity>()
// or
startActivityAndClearTask<HomeActivity>(Bundle().apply{
putString("A", "tes")
})
startActivityClearTop<HomeActivity>()
// or
startActivityClearTop<HomeActivity>(Bundle().apply{
putString("A", "tes")
})
showBasicDialog(
"Title",
"Message",
okClicked = { // nullable
logi("OK")
},
cancelClicked = { // nullable
logi("Cancel")
}
)
}
}
update language
open class BaseActivity : AppCompatActivity() {
override fun attachBaseContext(newBase: Context) {
newBase.apply {
val prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
var lang = prefs.getString(AppPreference.KEY_LANGUAGE, "en") ?: "en"
super.attachBaseContext(updateBaseContextLocale(lang))
}
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
val number = binding.etNumber.getString()
}
}
class HomeFragment : BaseFragment<FragmentHomeBinding>() {
private val listPermission = listOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
override fun onViewCreated(savedInstanceState: Bundle) {
super.onViewCreated()
...
// SnackBar
longSnack("Hello World")
shortSnack("Hello World")
// Toast
longToast("Hello World")
shortToast("Hello World")
// for finished parent activity
finish()
copyTextToClipboard(binding.etNumber.getString(), "Text Copied")
if (hasPermission(Manifest.permission.CAMERA)) {
logi("GRANTED")
}
if(hasPermission(listPermission.toTypedArray())) {
logi("GRANTED")
} else {
requestPermission()
}
startActivity<HomeActivity>()
// or
startActivity<HomeActivity>(Bundle().apply{
putString("A", "tes")
})
startActivity<HomeActivity>()
// or
startActivityAndClearTask<HomeActivity>(Bundle().apply{
putString("A", "tes")
})
startActivityClearTop<HomeActivity>()
// or
startActivityClearTop<HomeActivity>(Bundle().apply{
putString("A", "tes")
})
showDialog(
"Title",
"Message",
okClicked = { // nullable
logi("OK")
},
cancelClicked = { // nullable
logi("Cancel")
}
)
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
val needDp = 8.toDp()
val needPx = 8.toPx()
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
// basic
binding.ivAvatar.loadImage("url")
// or
val uri = ...
binding.ivAvatar.loadImage(uri)
// or
binding.ivAvatar.loadImage(R.drawable.ic_avatar)
// circle
binding.ivAvatar.loadCircleImage("url")
// or
val uri = ...
binding.ivAvatar.loadCircleImage(uri)
// or
binding.ivAvatar.loadCircleImage(R.drawable.ic_avatar)
// rounded (default radius = 10, can modify)
binding.ivAvatar.loadRoundedImage("url", 20)
// or
val uri = ...
binding.ivAvatar.loadRoundedImage(uri, 15)
// or
binding.ivAvatar.loadRoundedImage(R.drawable.ic_avatar, 25)
// ShapeableImageView
binding.shapableIv.setRadius(10)
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
// TAG auto generate with class T.TAG
// example use get HomeFragment TAG
HomeFragment().TAG
logv("Hello World")
logi("Hello World")
logw("Hello World")
logd("Hello World")
loge("Hello World")
}
}
findNavController().safeNavigate(action)
findNavController().safeNavigate(R.id.navigateto)
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
binding.rvMain.apply {
setup() // default is LinearLayourManager
// or
setup(GridLayoutManager(this, 4))
addVerticalItemDecoration() // default
// or
addVerticalItemDecoration(ContexCompact.getDrawable(this, R.drawable.rect_blue)) // with drawable nullable
addDividerVerticalItemExLast(ContexCompact.getDrawable(this, R.drawable.rect_blue)) // with drawable nullable
addDividerVerticalItemExHeader(ContexCompact.getDrawable(this, R.drawable.rect_blue)) // with drawable nullable
addHorizontalItemDecoration()
addHorizontalSpaceItem(space = 8)
addGridSpaceItem(
spaceCount: 4,
rowSpace: 8f,
columnSpacing: 24f
)
}
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
"11/11/2022".toDate("dd/MM/yyyy")
"Iman Faizal".apply {
logi(getFirstName()) // output: Iman
logi(getLastName()) // output: Faizal
// get initial can set limitation for your need initial name, example getInitial(limit = 1) -> result I
logi(getInitials()) // output: IF
logi(getStartAndEndOfSubstring("Fai")) // output (5, 7)
}
"afas37h38f".getNumeber() // output: 3738
}
}
fromHtmlText(text: String)
setColorOfSubstring(substring: String, color: Int)
startDrawable(drawableRes: Int)
startDrawable(drawable: Drawable?)
endDrawable(drawableRes: Int)
endDrawable(drawable: Drawable?)
AutoCompleteTextView.setupDropdownUI()
- ViewHolder
inner class CharactersViewHolder(binding: RowCharacterBinding): BindingViewHolder<RowCharacterBinding>(binding) { fun bind(item: Character) { .... binding.tvName.text = item.name .... binding.root.setOnClickListener { .... } } }
- Adapter
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return CharactersViewHolder(parent.toBinding()) }
- BaseActivity
- BaseFragment
- BaseBottomSheetDialog
- BaseDialogFragment
class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate()
...
binding.apply {
imageView.gone() // hide
imageView.isGone() // true or false
imageView.visible() // visibile
imageView.isVisible() // true or false
imageView.invisible() // invisibile
imageView.isInvisible() // true or false
imageView.enabled()
imageView.disabled()
root.snackBarWithAction(
"Message",
"Action Label",
onClicked = {
logi("OK click")
}
)
}
}
}
class MainActivity : BaseActivity<ActivityMainBinding>() {
private lateinit var appUpdateUtils: AppUpdateUtils
...
override fun onCreate(savedInstanceState: Bundle?) {
...
appUpdateUtils = AppUpdateUtils(this)
}
@Deprecated("Deprecated in Java")
@Suppress("DEPRECATION")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
appUpdateUtils.onActivityResult(requestCode, resultCode)
super.onActivityResult(requestCode, resultCode, data)
}
}
in layout
<com.imanfz.utility.ui.ReadMoreTextView
android:id="@+id/readMoreTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:readMoreText="Show" // default Read More
app:readMoreTextColor="@color/colorPrimary" // default readmore_color
app:readMoreMaxLine="2" // default 4
android:text="testsfsf sfks\nsfsfsf\nsfjfsjsfj\njsfjs oke bos"
in layout
<com.imanfz.utility.ui.LoadingButton
android:id="@+id/loading_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Loading Button"
android:textColor="#ffffff"
app:lb_buttonColor="@color/bluePrimaryDark"
app:lb_loaderColor="@color/redPrimary"
app:lb_loaderWidth="2dp"
app:lb_loaderMargin="8dp"
app:lb_isLoading="false"
app:lb_cornerRadius="8dp"
app:lb_isCircular="false"
app:lb_isShadowEnable="false"
app:lb_shadowColor="@color/yellowPrimary"
app:lb_shadowHeight="2dp"
app:lb_isStrokeEnable="true"
app:lb_strokeWidth="2dp"
app:lb_strokeColor="@color/redPrimary" />
in activity/fragment
loadingButton.apply {
setSafeOnClickListener {
showLoading()
delayOnLifecycle {
hideLoading()
}
}
}
getCurrentDateTime() // date
getCurrentDateTimeMils() // long
showDatePicker(context: Context) { date -> // string return
...
}
getUUID() // UUID
getDeviceModel()
getDeviceName()
getDeviceAPILevel()
getDeviceOSCode()
getDeviceOSName()
getDeviceTimeZone()
getDeviceLanguage()
setLightTheme()
setDarkTheme()
mandatory, your model class extend the BaseModel. The detail base model is:
interface BaseModel {
fun contains(someValue: String): Boolean = false
fun isItemSameWith(value: BaseModel): Boolean = false
fun isContentSameWith(value: BaseModel): Boolean = false
}
and how to use it
@Parcelize
data class Example(
...
...
): Parcelable, BaseModel
ItemDiffCallback<Example>()
convertDpToPixel(dp: Float, context: Context?): Float
convertPixelsToDp(px: Float, context: Context?): Float
isConnectionOn(context: Context): Boolean
isInternetAvailable(): Boolean
NetworkStatusUtils(context).observe(this, {
when(it) {
NetworkStatus.Available -> shortToast("Network Connection Established")
NetworkStatus.Unavailable -> shortToast("No Internet")
NetworkStatus.Lost -> shortToast("Reconnecting")
}
})
isDeviceRooted(): Boolean
reverse(duration: Long = 2000L): Shimmer
thinStraightTransparent(): Shimmer
sweep(
direction: Int = Shimmer.Direction.TOP_TO_BOTTOM,
tilt: Float = 0f
): Shimmer
spotlight(
alpha: Float = 0f,
duration: Long = 2000L,
dropOff: Float = 0.1f,
intensity: Float = 0.35f,
shape: Int = Shimmer.Shape.RADIAL
): Shimmer
// extension
show()
hide()
isValidInput(text: String, textInputLayout: TextInputLayout): Boolean
isValidInputLength(text: String, textInputLayout: TextInputLayout): Boolean
isValidEmail(emailText: String, textInputLayout: TextInputLayout): Boolean
isValidPhone(phone: String, textInputLayout: TextInputLayout): Boolean
isValidPhoneOrEmail(text: String, textInputLayout: TextInputLayout): Boolean
isValidPassword(password: String, textInputLayout: TextInputLayout): Boolean
isValidStrongPassword(password: String, textInputLayout: TextInputLayout): Boolean
enum class PasswordValidation {
LOWERCASE, UPPERCASE, DIGIT, CHARACTER
}
isNewValidPassword(password: String): List<PasswordValidation>
isMatchPassword(password: String, confirmPassword: String, textInputLayout: TextInputLayout): Boolean
DepthPageTransformer()
ZoomOutPageTransformer()
putIsLogin(value: Boolean)
isLogin(): Boolean
putFirstTimeLaunch(value: Boolean)
isFirstTimeLaunch(): Boolean
isFirstLogin(): Boolean
putIsFirstLogin(value: Boolean)
putString(key: String, text: String)
getString(key: String): String
putInt(key: String, value: Int)
getInt(key: String): Int
clear()
// model
put(UserModel(), USER_KEY)
get<UserModel>(USER_KEY) // nullable
// list model
putList(listUserModel, LIST_KEY)
geListt<UserModel>(LIST_KEY)
putInitialNameAvatar(bitmap: Bitmap)
getInitialNameAvatar(): Bitmap?