📄Core Directory

The core directory contains code and abstract classes that are extended by other activities in the Matar Android app.


Core Directory

--core(directory)
       --base(directory)
         --ActBase.kt(file)(ActBase is an abstract class serving as blueprints for other classes)
         --BaseActivity.kt(file)()
         --FragBase.kt(file)
       --DataResult.kt(file)
       --ResultWrapper.kt(file)

core/base/ActBase.kt

package com.matar.app.core.base

import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.akexorcist.localizationactivity.ui.LocalizationActivity
import com.matar.app.ui.features.firebase.AnalyticsViewModel
import com.matar.app.ui.features.firebase.FirebaseViewModel
import com.matar.app.ui.util.PreferenceManager

abstract class ActBase<actBinding : ViewBinding> : LocalizationActivity() {

    lateinit var binding: actBinding

    protected val analyticsViewModel: AnalyticsViewModel by viewModels()
    protected val firebaseViewModel: FirebaseViewModel by viewModels()

    lateinit var preferenceManager: PreferenceManager

    override fun onCreate(savedInstanceState: Bundle?) {
        preferenceManager = PreferenceManager(this)
        super.onCreate(savedInstanceState)
        binding = setViewBinding()
        setContentView(binding.root)
        bindObjects()
        bindListeners()
        bindMethods()
    }

    abstract fun setViewBinding(): actBinding
    abstract fun bindObjects()
    abstract fun bindListeners()
    abstract fun bindMethods()

    fun openFragment(fragment: Fragment, fragmentName: String, fragmentContainerId: Int) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(fragmentContainerId, fragment, fragmentName)
        transaction.disallowAddToBackStack()
        transaction.commit()

    }

}

Describing Code :

This class is meant to be extended by other activities in your Android app. Here's a breakdown of what this class does:

  1. Imports: It imports necessary packages and classes that are used in the class.

  2. Class Declaration: It declares a generic class ActBase that extends LocalizationActivity. The generic type actBinding is expected to be a ViewBinding class specific to the child activity that extends this base class.

  3. Properties:

    • binding: This property is used to hold the instance of the view binding for the child activity.

    • analyticsViewModel

    • preferenceManager

  4. onCreate() Method: This method is an Android lifecycle method that gets called when the activity is created. In this method:

    • An instance of the activity's content view is set to the root view of the binding.

  5. Abstract Methods:

    • setViewBinding()

      : This abstract method is meant to be implemented by child activities to provide the appropriate view binding for that activity.

    • bindObjects()

  6. openFragment() Method: This method is used to replace a fragment within the activity's fragment container. It takes three parameters:

    • fragment: The fragment to be displayed.

    • **fragmentName **: A tag or name for the fragment.

    • **fragmentContainerId **: The ID of the container where the fragment should be displayed. It replaces the current fragment with the specified fragment using a transaction.


core/base/BaseActivity.kt

package com.matar.app.core.base

import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.Patterns
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.akexorcist.localizationactivity.ui.LocalizationActivity
import com.matar.app.R
import com.matar.app.ui.dialog.AlertDialogs
import com.matar.app.ui.features.firebase.AnalyticsViewModel
import com.matar.app.ui.features.firebase.FirebaseViewModel
import com.matar.app.ui.util.PreferenceManager

abstract class BaseActivity : LocalizationActivity() {
    var dialog: AlertDialogs? = null
    var bind: ViewDataBinding? = null
    lateinit var preferencesManager: PreferenceManager

    protected val analyticsViewModel: AnalyticsViewModel by viewModels()
    protected val firebaseViewModel: FirebaseViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bind = DataBindingUtil.setContentView(this, getLayout())
        onViewReady(bind)
        preferencesManager = PreferenceManager(applicationContext)
        dialog = AlertDialogs(this)
    }


    fun showDialog() {
        dialog?.show()
    }

    fun hideDialog() {
        if (dialog != null) {
            dialog?.dismiss()
        }
    }

    protected abstract fun onViewReady(bind: ViewDataBinding?)
    abstract fun getLayout(): Int

    fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }


    fun isValidEmail(target: CharSequence?): Boolean {
        return if (target == null) {
            false
        } else {
            Patterns.EMAIL_ADDRESS.matcher(target).matches()
        }
    }

    fun openFragment(fragment: Fragment, fragmentName: String) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.fragmentContainer, fragment, fragmentName)
        transaction.disallowAddToBackStack()
        transaction.commit()

    }

    fun Context.hideKeyboard(view: View) {
        val inputMethodManager =
            getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
    }
}

Describing Code:

An abstract base class named BaseActivity in an Android application serve as a foundation for other activities in your app. Let's break down what this class does:

  1. Inheritance: BaseActivity inherits from another class named LocalizationActivity.

  2. Properties:

    • dialog

    • bind

    • preferencesManager

    • analyticsViewModel

    • firebaseViewModel

  3. onCreate Method: This is an override of the onCreate method from the Android Activity class. It sets up the activity by:

    • Setting the content view using data binding.

    • Calling

    • Initializing the

    • Creating an instance of

  4. showDialog and hideDialog Methods: These methods allow you to show and hide dialog boxes, respectively. They use the dialog property.

  5. onViewReady and getLayout Methods: These are abstract methods that you must implement in subclasses. onViewReady is called in onCreate after setting up the view, and getLayout should return the layout resource ID for the activity layout.

  6. showToast Method: A utility method for displaying toast messages.

  7. isValidEmail Method: A utility method for checking if a given string is a valid email address using a regular expression.

  8. openFragment Method: This method allows you to replace the fragment in the activity's layout with a new one. It uses the FragmentManager to perform the transaction.

  9. hideKeyboard Extension Function: An extension function for hiding the soft keyboard. It takes a View as an argument and uses the InputMethodManager to hide the keyboard.

Subclasses of BaseActivity can implement the onViewReady and getLayout methods to customize their behavior. Also, analytics and Firebase functionality can be integrated for tracking user interactions into the app.


core/base/Fragbase.kt

package com.matar.app.core.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.viewbinding.ViewBinding
import com.matar.app.ui.features.firebase.AnalyticsViewModel
import com.matar.app.ui.features.firebase.FirebaseViewModel

abstract class FragBase<actBinding : ViewBinding> : Fragment() {

    protected val analyticsViewModel: AnalyticsViewModel by viewModels()
    protected val firebaseViewModel: FirebaseViewModel by viewModels()

    lateinit var binding: actBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = setViewBinding()
        bindObjects()
        bindListener()
        bindMethod()
        return binding.root
    }

    abstract fun setViewBinding(): actBinding
    abstract fun bindObjects()
    abstract fun bindListener()
    abstract fun bindMethod()
}

Describing Code:

  1. FragBase is an abstract class that extends Fragment, making it a base class for other fragments in your Android app.

  2. The class is parameterized with actBinding, which is expected to be a subtype of ViewBinding. This allows you to use view binding to interact with your fragment's layout.

  3. Inside the class, two view models are declared and initialized using viewModels(). These view models are analyticsViewModel and firebaseViewModel, which are presumably used for handling analytics and Firebase-related functionality in your app.

  4. A lateinit property binding of type actBinding is declared. This property will be used to store the view binding instance for the fragment's layout.

  5. The onCreateView function is overridden. This function is called when the fragment is created and is responsible for inflating the fragment's layout, binding views, and returning the root view.

  6. Inside onCreateView, setViewBinding() is called to initialize the binding property with the appropriate view binding instance for the fragment.

  7. The bindObjects(), bindListener(), and bindMethod() functions are called within onCreateView. These are abstract functions that must be implemented by subclasses of FragBase. They are meant for initializing objects, setting up listeners, and binding methods related to the fragment's functionality.

FragBase can provide** ** implementations for setViewBinding(), bindObjects(), bindListener(), and bindMethod(), which allows you to customize the behavior and layout of your fragment.


core/DataResult.kt

package com.matar.app.core

sealed class DataResult<out T> {
    data class Success<out T>(val value: T): DataResult<T>()
    data class Error(val exception: Exception) : DataResult<Nothing>()
}

fun <T, V> DataResult<T>.toResultWrapper(mapper: (T) -> V) = when (this) {
    is DataResult.Error -> ResultWrapper.Error(exception)
    is DataResult.Success -> ResultWrapper.Success(mapper(value))
}

core/ResultWrapper.kt

package com.matar.app.core

sealed class ResultWrapper<out T> {

    data class Success<out T>(val value: T) : ResultWrapper<T>()

    data class Error(val throwable: Throwable? = null) : ResultWrapper<Nothing>()

    object None : ResultWrapper<Nothing>()

    object Loading : ResultWrapper<Nothing>()

    @Throws(Exception::class)
    fun takeValueOrThrow(): T {
        return when (this) {
            is Success -> value
            is Error -> throw throwable ?: Throwable()
            else -> throw Throwable("Unknown the result type $this")
        }
    }
}

Last updated