Skip to content

Commit

Permalink
* create class by type: ClassHelper.kt
Browse files Browse the repository at this point in the history
* change ui on state change by decideOnState: PagingDataAdapterHelper.kt
* clear ConcatAdapterHelper.kt
* commit fragments more easily: FragmentHelper.kt
* more extensions: EdittextHelper.kt, InputValidator.kt, IterableHelper.kt, LiveEventBusHelper.kt, NumberHelper.kt, ScrollViewHelper.kt, StringHelper.kt, ViewModelHelper.kt
* update versions
  • Loading branch information
am3n committed Apr 19, 2022
1 parent c60f84f commit 8560b7c
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 13 deletions.
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ buildscript {
ext.material_version = '1.5.0'
ext.hilt_version = '2.28-alpha'

ext.kotlin_version = '1.6.10'
ext.kotlinx_coroutines = '1.6.0-native-mt'
ext.kotlin_version = '1.6.20'
ext.kotlinx_coroutines = '1.6.1-native-mt'

}

plugins {
id 'com.android.application' version '7.1.2' apply false
id 'com.android.library' version '7.1.2' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
id 'com.android.application' version '7.1.3' apply false
id 'com.android.library' version '7.1.3' apply false
id 'org.jetbrains.kotlin.android' version '1.6.20' apply false
}

task clean(type: Delete) {
Expand Down
9 changes: 8 additions & 1 deletion needtool/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ dependencies {
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinx_coroutines"
api 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'



/** paging */
api 'androidx.paging:paging-runtime-ktx:3.1.1'


/** retrofit */
api "com.squareup.retrofit2:retrofit:2.9.0"
api "com.squareup.retrofit2:converter-gson:2.9.0"
Expand All @@ -65,4 +69,7 @@ dependencies {
api 'com.github.am3n:AndroidDeviceNames:2.0.3'


/** eventbus */
api 'io.github.jeremyliao:live-event-bus-x:1.8.0'

}
6 changes: 6 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/ClassHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ir.am3n.needtool


inline fun <reified T> createClass(): T {
return T::class.java.newInstance()
}
12 changes: 12 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/ConcatAdapterHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ir.am3n.needtool

import androidx.recyclerview.widget.ConcatAdapter


fun ConcatAdapter.clear() {
while (adapters.size > 0) {
removeAdapter(adapters[0])
notifyItemRemoved(0)
}
}

10 changes: 9 additions & 1 deletion needtool/src/main/java/ir/am3n/needtool/EdittextHelper.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ir.am3n.needtool

import android.content.Context
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText

interface EdittextOnDone {
Expand All @@ -27,4 +29,10 @@ fun EditText.onDone(edittextOnDone: () -> Boolean) {
}
return@setOnEditorActionListener false
}
}
}


fun EditText.showSoftKeyboard() {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?)
?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}
97 changes: 96 additions & 1 deletion needtool/src/main/java/ir/am3n/needtool/FragmentHelper.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package ir.am3n.needtool

import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.IdRes
import androidx.annotation.NonNull
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope

abstract class BackPressHandler : Fragment() {
var created: Long = System.currentTimeMillis()
Expand Down Expand Up @@ -58,3 +64,92 @@ fun View.onBackPressed(callback: () -> Unit) {
return@setOnKeyListener false
}
}


val Fragment.vlo: LifecycleOwner get() = viewLifecycleOwner
val Fragment.vloScope: LifecycleCoroutineScope get() = vlo.lifecycleScope


val Fragment.sfm: FragmentManager get() = requireActivity().sfm
val FragmentActivity.sfm: FragmentManager get() = supportFragmentManager
val Fragment.cfm: FragmentManager get() = childFragmentManager


val Fragment.TAG: String get() = javaClass.name


fun FragmentTransaction.replaceAndStack(@IdRes containerViewId: Int, @NonNull fragment: Fragment): FragmentTransaction {
replace(containerViewId, fragment, fragment.TAG)
addToBackStack(fragment.TAG)
return this
}

fun FragmentTransaction.addAndStack(@IdRes containerViewId: Int, @NonNull fragment: Fragment): FragmentTransaction {
add(containerViewId, fragment, fragment.TAG)
addToBackStack(fragment.TAG)
return this
}

fun FragmentManager.popBackStackInclusive(tag: String) {
popBackStack(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}

fun FragmentManager.popBackStackInclusive(clazz: Class<out Fragment>) {
popBackStackInclusive(clazz.newInstance().TAG)
}

fun AppCompatActivity.addAndHideFragment(containerId: Int, fragment: Fragment, addToBackStack: Boolean) {
val ft = supportFragmentManager.beginTransaction()
ft.add(containerId, fragment, fragment.TAG)
ft.hide(fragment)
if (addToBackStack) {
ft.addToBackStack(fragment.TAG)
}
ft.commit()
}

fun AppCompatActivity.showOrAddFragment(containerId: Int, fragment: Fragment, addToBackStack: Boolean) {
if (supportFragmentManager.findFragmentByTag(fragment.TAG) != null) {
showFragment(fragment)
} else {
addFragment(containerId, fragment, addToBackStack)
}
}

fun AppCompatActivity.showFragment(fragment: Fragment) {
val ft = supportFragmentManager.beginTransaction()
ft.show(fragment)
ft.commit()
}

fun AppCompatActivity.hideFragment(fragment: Fragment) {
val ft = supportFragmentManager.beginTransaction()
ft.hide(fragment)
ft.commit()
}

fun AppCompatActivity.addFragment(containerId: Int, fragment: Fragment, addToBackStack: Boolean) {
val fragmentTransaction = supportFragmentManager.beginTransaction()
performAddFragment(containerId, fragmentTransaction, fragment, addToBackStack)
}

private fun performAddFragment(containerId: Int, ft: FragmentTransaction, fragment: Fragment, addToBackStack: Boolean) {
ft.add(containerId, fragment, fragment.TAG)
if (addToBackStack) {
ft.addToBackStack(fragment.TAG)
}
ft.commit()
}

fun AppCompatActivity.replaceFragment(containerId: Int, fragment: Fragment, addToBackStack: Boolean) {
val fragmentTransaction = supportFragmentManager.beginTransaction()
performReplaceFragment(containerId, fragmentTransaction, fragment, addToBackStack)
}

private fun performReplaceFragment(containerId: Int, ft: FragmentTransaction, fragment: Fragment, addToBackStack: Boolean) {
ft.replace(containerId, fragment, fragment.TAG)
if (addToBackStack) {
ft.addToBackStack(fragment.TAG)
}
ft.commit()
}
4 changes: 2 additions & 2 deletions needtool/src/main/java/ir/am3n/needtool/InputValidator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package ir.am3n.needtool
import java.util.regex.Pattern


fun String.validEmail(): Boolean {
fun String?.isValidEmail(): Boolean {
val expression = "^[\\w.-]+@([\\w\\-]+\\.)+[A-Z]{2,8}$"
val pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE)
val matcher = pattern.matcher(this)
val matcher = pattern.matcher(this ?: "")
return matcher.matches()
}

7 changes: 6 additions & 1 deletion needtool/src/main/java/ir/am3n/needtool/IterableHelper.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ir.am3n.needtool

import androidx.core.util.Predicate
import java.io.BufferedReader


Expand All @@ -12,6 +11,12 @@ fun Iterable<String?>.filterNotEmpty(): MutableList<String> {
}


fun <T> Iterable<T>.firstOrNullIndexed(predicate: (T) -> Boolean): IndexedValue<T>? {
withIndex().forEach { if (predicate(it.value)) return it }
return null
}


val BufferedReader.lines: Iterator<String?> get() = object : Iterator<String?> {
var line: String? = this@lines.readLine()
override fun next(): String? {
Expand Down
13 changes: 13 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/LiveEventBusHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ir.am3n.needtool

import com.jeremyliao.liveeventbus.LiveEventBus
import com.jeremyliao.liveeventbus.core.Observable


fun postLiveEventBus(key: String, value: Any? = null) {
LiveEventBus.get<Any>(key).post(value)
}

fun getLiveEventBus(key: String): Observable<Any> {
return LiveEventBus.get(key, Any::class.java)
}
18 changes: 18 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/NumberHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,21 @@ val String.toPersian: String get() {
persianNumStr = persianNumStr.replace(",".toRegex(), "٬")
return persianNumStr
}


fun Int?.ifNullOrZero(defaultValue: Int): Int {
return if (this == null || this == 0) defaultValue else this
}

fun Long?.ifNullOrZero(defaultValue: Long): Long {
return if (this == null || this == 0L) defaultValue else this
}

fun Float?.ifNullOrZero(defaultValue: Float): Float {
return if (this == null || this == 0f) defaultValue else this
}

fun Double?.ifNullOrZero(defaultValue: Double): Double {
return if (this == null || this == 0.0) defaultValue else this
}

29 changes: 29 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/PagingDataAdapterHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ir.am3n.needtool

import androidx.paging.LoadState
import androidx.paging.PagingDataAdapter

fun PagingDataAdapter<*, *>.decideOnState(
showLoadStates: (showLoading: Boolean, showEmpty: Boolean, showError: Boolean) -> Unit
) {

addLoadStateListener { loadState ->

val errorState = loadState.source.append as? LoadState.Error
?: loadState.source.prepend as? LoadState.Error
?: loadState.source.refresh as? LoadState.Error
?: loadState.append as? LoadState.Error
?: loadState.prepend as? LoadState.Error
?: loadState.refresh as? LoadState.Error

val loading = loadState.refresh is LoadState.Loading && itemCount == 0

val empty = loadState.source.append is LoadState.NotLoading && loadState.source.append.endOfPaginationReached && itemCount == 0

val error = errorState != null && itemCount == 0

showLoadStates(loading, empty, error)

}

}
12 changes: 12 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/ScrollViewHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ir.am3n.needtool

import android.view.View
import android.widget.ScrollView


fun ScrollView.focusOn(view: View) {
val vTop = view.top
val vBottom = view.bottom
val sHeight = bottom
smoothScrollTo((vTop + vBottom - sHeight) / 2, 0)
}
21 changes: 19 additions & 2 deletions needtool/src/main/java/ir/am3n/needtool/StringHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,27 @@ package ir.am3n.needtool
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.Editable
import androidx.core.content.ContextCompat
import java.math.BigDecimal
import java.math.BigInteger


const val loremIpsumShort = "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است."


val Editable?.len: Int get() = this?.length ?: -1
val String?.len: Int get() = this?.length ?: -1

fun String?.ifBlank(defaultValue: String? = null): String? {
return if (this?.isBlank() == true) defaultValue else this
}

fun String?.ifNullOrBlank(defaultValue: String): String {
return if (isNullOrBlank()) defaultValue else this
}


val String.url2Host get() = replace(Regex(".*//"), "").replace(Regex("/.*"), "").replace("www.", "")

fun String.firstCap() = replaceFirstChar { it.uppercase() }
Expand Down Expand Up @@ -76,9 +93,9 @@ fun change2by2(str: String): ByteArray {
}


val String.intOr0: Int get() = toIntOrNull() ?: 0
val String?.intOr0: Int get() = this?.toIntOrNull() ?: 0

val String.intOr0Str: String get() = intOr0.toString()
val String?.intOr0AsString: String get() = intOr0.toString()



Expand Down
20 changes: 20 additions & 0 deletions needtool/src/main/java/ir/am3n/needtool/ViewModelHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ir.am3n.needtool

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.launch
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext


val ViewModel.scope: CoroutineScope get() = viewModelScope

fun ViewModel.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
) {
scope.launch(context, start, block)
}

0 comments on commit 8560b7c

Please sign in to comment.