Created
January 18, 2020 05:57
-
-
Save nawanirakshit/11713f26e2e93d68d14d6b15058297a2 to your computer and use it in GitHub Desktop.
Base/Core class for Android Developement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout xmlns:tools="http://schemas.android.com/tools" | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:bind="http://schemas.android.com/apk/res-auto"> | |
<data> | |
<variable | |
name="viewModel" | |
type="package_name.DashboardViewModel" /> | |
</data> | |
<androidx.recyclerview.widget.RecyclerView | |
android:id="@+id/recycler_dashboard" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
app:adapter="@{viewModel.adapter}" | |
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> | |
</layout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created By: Rakshit Nawani | |
* Date: January 18 2020 | |
* | |
* BaseRecyclerViewAdapter can be used as a base class for all the Recycler View's Adapter, it contains all the basic functions needed by the user, like | |
* 1. Add Item | |
* 2. Update Item | |
* 3. Add List | |
* 4. Remove Item | |
* and many more according to needs. | |
* | |
*/ | |
abstract class BaseRecyclerViewAdapter<BD : ViewDataBinding, T>( | |
@LayoutRes private var layoutId: Int, var mList: ArrayList<T> = ArrayList() | |
) : | |
RecyclerView.Adapter<BaseRecyclerViewAdapter<BD, T>.BaseRecyclerViewHolder>() { | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecyclerViewHolder = | |
BaseRecyclerViewHolder( | |
DataBindingUtil.inflate( | |
LayoutInflater.from(parent.context), | |
layoutId, | |
parent, | |
false | |
) | |
) | |
private var baseRecyclerViewItemListener: BaseRecyclerViewItemListener? = null | |
fun addItem(t: T, position: Int? = null) { | |
when (position) { | |
null -> mList.add(t) | |
else -> mList.add(position, t) | |
} | |
notifyItemInserted(position ?: mList.size - 1) | |
baseRecyclerViewItemListener?.addItem(position ?: mList.size - 1) | |
} | |
open fun addItemAtBeginning(t: T) { | |
mList.add(0, t) | |
notifyItemInserted(0) | |
} | |
open fun getItem(position: Int): T = mList[position] | |
fun findItem(predicate: (T) -> Boolean): T? = mList.find(predicate) | |
fun itemPosition(t: T): Int = mList.indexOf(t) | |
open fun removeItem(position: Int) { | |
if (position < 0) return | |
mList.removeAt(position) | |
notifyItemRemoved(position) | |
baseRecyclerViewItemListener?.removeItem(position) | |
} | |
fun updateItem(position: Int, t: T) { | |
mList[position] = t | |
notifyItemChanged(position) | |
baseRecyclerViewItemListener?.changeItem(position) | |
} | |
fun addItems(t: List<T>) { | |
mList.addAll(t) | |
notifyDataSetChanged() | |
baseRecyclerViewItemListener?.addAllItems() | |
} | |
override fun getItemCount(): Int = mList.size | |
fun getAllItems(): ArrayList<T> = mList | |
open fun clear() { | |
mList.clear() | |
notifyDataSetChanged() | |
} | |
operator fun contains(item: T): Boolean = mList.contains(item) | |
fun getPositionForItem(item: T) = when { | |
mList.size > 0 -> mList.indexOf(item) | |
else -> -1 | |
} | |
fun moveItems(fromPosition: Int, toPosition: Int): Boolean { | |
if (fromPosition < toPosition) { | |
for (i in fromPosition until toPosition) { | |
Collections.swap(mList, i, i + 1) | |
} | |
} else { | |
for (i in fromPosition downTo toPosition + 1) { | |
Collections.swap(mList, i, i - 1) | |
} | |
} | |
notifyItemMoved(fromPosition, toPosition) | |
return true | |
} | |
inner class BaseRecyclerViewHolder(var binding: BD) : RecyclerView.ViewHolder(binding.root) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created By: Rakshit Nawani | |
* Date: January 18 2020 | |
* | |
* Binding Activity can be used as a base class for all the activity, it contains all the basic functions needed by the user, like | |
* 1. Printing log | |
* 2. Displaying Toast | |
* 3. Show/Hide Loading | |
* and many more according to needs. | |
* | |
* In an Activity extend it with BindingActivity<Data Binding Class of that class> | |
* After extending Activity we need to override methods which is getLayoutResId, implement it like below | |
* | |
* @LayoutRes | |
* override fun getLayoutResId() = R.layout.your_layout_name_here | |
* | |
* | |
*/ | |
abstract class BindingActivity<T : ViewDataBinding> : AppCompatActivity() { | |
@LayoutRes | |
abstract fun getLayoutResId(): Int | |
private var loadingDialog: AlertDialog? = null | |
protected lateinit var binding: T private set | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
//Printling the Class name in logs | |
printLog(javaClass.simpleName) | |
binding = DataBindingUtil.setContentView(this, getLayoutResId()) | |
} | |
private var toast: Toast? = null | |
/** | |
* showToast with message | |
* @view: for custom toast provide view perform inflater and other task at your end | |
* @gravity: provide gravity | |
*/ | |
fun showToast( | |
message: String?, | |
view: View? = null, | |
duration: Int = Toast.LENGTH_LONG, | |
gravity: Int = Gravity.BOTTOM or Gravity.CENTER_VERTICAL, @DimenRes x: Int = 0, @DimenRes y: Int = 0, | |
cancelPrevious: Boolean = false | |
) { | |
if (cancelPrevious) toast?.cancel() | |
// set custom view | |
when { | |
view != null -> { | |
toast = Toast(context) | |
toast?.view = view | |
} | |
else -> toast = Toast.makeText(context, message, duration) | |
} | |
// set duration | |
toast?.duration = duration | |
// set position | |
var marginY = 0 | |
var marginX = 0 | |
if (y != 0) marginY = resources.getDimensionPixelSize(y) | |
if (x != 0) marginX = resources.getDimensionPixelSize(x) | |
if (marginX > 0 || marginY > 0) toast?.setGravity(gravity, marginX, marginY) | |
// show toast | |
toast?.show() | |
} | |
/** | |
* For Displaying the loading when an API is hit | |
*/ | |
fun showLoading(context: Context) { | |
try { | |
if (loadingDialog == null) { | |
val factory: LayoutInflater = LayoutInflater.from(context) | |
val deleteDialogView: View = factory.inflate(R.layout.loading_screen, null) | |
loadingDialog = | |
AlertDialog.Builder(context, R.style.AppCompatAlertDialogStyle).create() | |
loadingDialog!!.setView(deleteDialogView) | |
loadingDialog!!.setCanceledOnTouchOutside(false) | |
loadingDialog!!.setCancelable(false) | |
hideKeyboard() | |
} | |
loadingDialog!!.show() | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
} | |
/** | |
* For hiding the loading | |
*/ | |
open fun hideLoading() { | |
try { | |
loadingDialog?.dismiss() | |
hideKeyboard() | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
} | |
/** | |
* For Hiding the keyboard | |
*/ | |
open fun hideKeyboard() { | |
val view = this.currentFocus | |
if (view != null) { | |
val imm = | |
(getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager) | |
imm.hideSoftInputFromWindow(view.windowToken, 0) | |
} | |
} | |
/** | |
* function to check if internet connection is active or not. | |
* | |
* @return true if connected to internet else false | |
*/ | |
open fun isConnectedToInternet(): Boolean { | |
val cm = | |
(getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager) | |
val activeNetwork = cm.activeNetworkInfo | |
return activeNetwork != null | |
} | |
open fun printLog(message: String) { | |
Log.d(getString(R.string.app_name), message) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created By: Rakshit Nawani | |
* Date: January 18 2020 | |
* | |
* BindingFragment can be used as a base class for all the Fragments, it contains all the basic functions needed by the user | |
* which will be connected with the BindingActivity | |
* | |
* In a Fragment extend it with BindingFragment<Data Binding Class of that class> | |
* After extending Fragment we need to override methods which is getLayoutResId, implement it like below | |
* | |
* @LayoutRes | |
* override fun getLayoutResId() = R.layout.your_layout_name_here | |
*/ | |
abstract class BindingFragment<T : ViewDataBinding> : Fragment() { | |
@LayoutRes | |
abstract fun getLayoutResId(): Int | |
private var loadingDialog: AlertDialog? = null | |
protected lateinit var binding: T private set | |
override fun onCreateView( | |
inflater: LayoutInflater, | |
container: ViewGroup?, | |
savedInstanceState: Bundle? | |
): View? { | |
(activity as BindingActivity<*>).printLog(javaClass.simpleName) | |
setHasOptionsMenu(true) | |
return DataBindingUtil.inflate<T>(inflater, getLayoutResId(), container, false) | |
.apply { binding = this }.root | |
} | |
private var toast: Toast? = null | |
/** | |
* showToast with message | |
* @view: for custom toast provide view perform inflater and other task at your end | |
* @gravity: provide gravity | |
*/ | |
open fun showToast( | |
message: String?, | |
view: View? = null, | |
duration: Int = Toast.LENGTH_LONG, | |
gravity: Int = Gravity.BOTTOM or Gravity.CENTER_VERTICAL, @DimenRes x: Int = 0, @DimenRes y: Int = 0, | |
cancelPrevious: Boolean = false | |
) { | |
(activity as BindingActivity<*>).showToast( | |
message = message, | |
view = view, | |
duration = duration, | |
gravity = gravity, | |
cancelPrevious = cancelPrevious | |
) | |
} | |
/** | |
* For Displaying the loader | |
*/ | |
fun showLoading(context: Context) { | |
try { | |
(activity as BindingActivity<*>).hideLoading() | |
(activity as BindingActivity<*>).showLoading(context) | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
} | |
/** | |
* For hiding the loading | |
*/ | |
fun hideLoading() { | |
(activity as BindingActivity<*>).hideLoading() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto"> | |
<data> | |
<variable | |
name="data" | |
type="String" /> | |
</data> | |
<TextView | |
android:text="@{data}" | |
android:id="@+id/tv_hospital_name" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:textColor="@color/divider_dark" /> | |
</layout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created By: Rakshit Nawani | |
* Date: January 18 2020 | |
* | |
* Sample Activity, displays how to use the Base Classes | |
* | |
*/ | |
class DashboardActivity : BindingActivity<ActivityDashboardBinding>() { | |
@LayoutRes | |
override fun getLayoutResId() = R.layout.activity_dashboard | |
lateinit var viewModel: DashboardViewModel | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
//Attaching View Model | |
viewModel = DashboardViewModel() | |
binding.viewModel = viewModel | |
binding.lifecycleOwner = this | |
//Adding click Listeners for the adapter's item | |
viewModel.adapter.listener = object : DashboardAdapter.DataListListener { | |
override fun itemClick(data: String) { | |
//Calling a function from Base Class | |
printlog(data) | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created By: Rakshit Nawani | |
* Date: January 18 2020 | |
* | |
* Recycler View's Adapter class extending BaseRecyclerViewAdapter<Data_Binding_Class, Model_Type> | |
* | |
*/ | |
class DashboardAdapter: BaseRecyclerViewAdapter<DashboardListItemBinding, String>(R.layout.dashboard_list_item) { | |
override fun onBindViewHolder(holder: BaseRecyclerViewHolder, position: Int) { | |
holder.binding.data = getItem(position) | |
holder.binding.root.setOnClickListener { | |
listener?.itemClick(getItem(holder.adapterPosition)) | |
} | |
} | |
var listener: DataListListener? = null | |
interface DataListListener { | |
fun itemClick(data: String) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created By: Rakshit Nawani | |
* Date: January 18 2020 | |
* | |
* View Model class for DashboardActivity.kt extending BaseViewModel a core class | |
* | |
* Displaying how to Add a recycler View Adapter in a View model | |
*/ | |
class DashboardViewModel: BaseViewModel() { | |
val adapter = DashboardAdapter() | |
init{ | |
// Add data in your Adapter | |
val list = arrayListOf<String>() | |
list.add("A") | |
list.add("B") | |
list.add("C") | |
list.add("D") | |
list.add("E") | |
adapter.addItems(list) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment