Android – Architecture – How to build multiple pages having similar UI structures/ logic features?

Build screens having Toolbar & Back button & popup dialog, show/hide soft keyboard

Build an abstract Activity/ Fragment class

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
abstract class BaseFragment : Fragment() {
private var actionBarTitle = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onResume() {
super.onResume()
setupToolbar()
}
open fun toFront() {}
abstract fun loadText()
open fun showBackIcon(): Boolean = true
open fun getBackIcon(): Int = R.drawable.back
open fun showKeyboard(view: View) {
val inputMethodManager = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
}
open fun hideKeyboard(view: View) {
val inputMethodManager = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
open fun showAlertDialog(messageId: Int) {
val alertText = getTranslation(messageId)
val builder = AlertDialog.Builder(this.requireContext())
builder.setMessage(alertText)
val dialog: AlertDialog = builder.create()
dialog.show()
}
private fun setupToolbar() {
toolbar?.let {
(activity as SampleActivity).setSupportActionBar(it)
val supportActionBar = (activity as SampleActivity).supportActionBar
activity?.title = actionBarTitle
supportActionBar?.setDisplayHomeAsUpEnabled(showBackIcon())
supportActionBar?.setHomeAsUpIndicator(getBackIcon())
}
}
}
abstract class BaseFragment : Fragment() { private var actionBarTitle = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onResume() { super.onResume() setupToolbar() } open fun toFront() {} abstract fun loadText() open fun showBackIcon(): Boolean = true open fun getBackIcon(): Int = R.drawable.back open fun showKeyboard(view: View) { val inputMethodManager = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY) } open fun hideKeyboard(view: View) { val inputMethodManager = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) } open fun showAlertDialog(messageId: Int) { val alertText = getTranslation(messageId) val builder = AlertDialog.Builder(this.requireContext()) builder.setMessage(alertText) val dialog: AlertDialog = builder.create() dialog.show() } private fun setupToolbar() { toolbar?.let { (activity as SampleActivity).setSupportActionBar(it) val supportActionBar = (activity as SampleActivity).supportActionBar activity?.title = actionBarTitle supportActionBar?.setDisplayHomeAsUpEnabled(showBackIcon()) supportActionBar?.setHomeAsUpIndicator(getBackIcon()) } } }
abstract class BaseFragment : Fragment() {

    private var actionBarTitle = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onResume() {
        super.onResume()
        setupToolbar()
    }

    open fun toFront() {}

    abstract fun loadText()

    open fun showBackIcon(): Boolean = true

    open fun getBackIcon(): Int = R.drawable.back

    open fun showKeyboard(view: View) {
        val inputMethodManager = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
    }

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

    open fun showAlertDialog(messageId: Int) {
        val alertText = getTranslation(messageId)

        val builder = AlertDialog.Builder(this.requireContext())

        builder.setMessage(alertText)

        val dialog: AlertDialog = builder.create()

        dialog.show()
    }

    private fun setupToolbar() {
        toolbar?.let {
            (activity as SampleActivity).setSupportActionBar(it)

            val supportActionBar = (activity as SampleActivity).supportActionBar
            activity?.title = actionBarTitle
            supportActionBar?.setDisplayHomeAsUpEnabled(showBackIcon())
            supportActionBar?.setHomeAsUpIndicator(getBackIcon())
        }
    }
}

Build screen implementing this base abstract Activity/ Fragment

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// XML layout file having Toolbar
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fillViewport="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/mainLayoutPage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/lightGray"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:titleTextColor="@color/white" />
...
</LinearLayout>
</ScrollView>
// XML layout file having Toolbar <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:fillViewport="true" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/mainLayoutPage" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/lightGray" android:orientation="vertical"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" app:titleTextColor="@color/white" /> ... </LinearLayout> </ScrollView>
// XML layout file having Toolbar
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/mainLayoutPage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/lightGray"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            app:titleTextColor="@color/white" />
        ...
    </LinearLayout>
</ScrollView>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Fragment class
class PageFragment : BaseFragment(), PageContract.View {
private val presenter: PageContract.Presenter by inject { parametersOf(this) }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
inflater.inflate(R.layout.fragment_page, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun loadText() {
elementViewOne?.text = "ABCDEF"
elementViewTwo?.text = "ASADED"
}
override fun enableSomeStuff() {
...
showKeyboard(someViewElement)
}
override fun disableSomeStuff() {
....
hideKeyboard(textPlateNumber)
}
// Fragment class class PageFragment : BaseFragment(), PageContract.View { private val presenter: PageContract.Presenter by inject { parametersOf(this) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_page, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) } override fun loadText() { elementViewOne?.text = "ABCDEF" elementViewTwo?.text = "ASADED" } override fun enableSomeStuff() { ... showKeyboard(someViewElement) } override fun disableSomeStuff() { .... hideKeyboard(textPlateNumber) }
// Fragment class
class PageFragment : BaseFragment(), PageContract.View {

    private val presenter: PageContract.Presenter by inject { parametersOf(this) }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater.inflate(R.layout.fragment_page, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }

    override fun loadText() {
        elementViewOne?.text = "ABCDEF"
        elementViewTwo?.text = "ASADED"
    }

    override fun enableSomeStuff() {
        ...
        showKeyboard(someViewElement)
    }

    override fun disableSomeStuff() {
        ....
        hideKeyboard(textPlateNumber)
    }

Build tutorial screens having same UI structure: on image, one header title, one description

Build a base abstract fragment

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:scaleType="centerInside"
tools:src="@drawable/activated_illustration"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
</LinearLayout>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="30dp"
android:textAlignment="center"
android:textSize="24sp"
tools:text="" />
<TextView
android:id="@+id/detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="30dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="30dp"
android:gravity="center_horizontal"
android:text=""
android:textAlignment="center"
android:textSize="18sp" />
</LinearLayout>
</ScrollView>
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="300dp" android:orientation="vertical"> <ImageView android:id="@+id/image" android:scaleType="centerInside" tools:src="@drawable/activated_illustration" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" /> </LinearLayout> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginStart="30dp" android:layout_marginTop="30dp" android:layout_marginEnd="30dp" android:textAlignment="center" android:textSize="24sp" tools:text="" /> <TextView android:id="@+id/detail" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginStart="30dp" android:layout_marginTop="20dp" android:layout_marginEnd="30dp" android:gravity="center_horizontal" android:text="" android:textAlignment="center" android:textSize="18sp" /> </LinearLayout> </ScrollView>
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/image"
                android:scaleType="centerInside"
                tools:src="@drawable/activated_illustration"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center" />
        </LinearLayout>

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginStart="30dp"
            android:layout_marginTop="30dp"
            android:layout_marginEnd="30dp"
            android:textAlignment="center"
            android:textSize="24sp"
            tools:text="" />

        <TextView
            android:id="@+id/detail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginStart="30dp"
            android:layout_marginTop="20dp"
            android:layout_marginEnd="30dp"
            android:gravity="center_horizontal"
            android:text=""
            android:textAlignment="center"
            android:textSize="18sp" />
    </LinearLayout>
</ScrollView>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
abstract class TutorialBaseFragment : BaseFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_tutorial, container, false)
}
abstract fun loadImage()
override fun onResume() {
super.onResume()
loadImage()
}
}
abstract class TutorialBaseFragment : BaseFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_tutorial, container, false) } abstract fun loadImage() override fun onResume() { super.onResume() loadImage() } }
abstract class TutorialBaseFragment : BaseFragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_tutorial, container, false)
    }

    abstract fun loadImage()

    override fun onResume() {
        super.onResume()
        loadImage()
    }

}

Build specific screen fragment implementing this base fragment

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class TutorialPageOneFragment : TutorialBaseFragment() {
override fun loadText() {
title?.text = "title One"
detail?.text = "detail One"
}
override fun loadImage() {
image.setImageResource(R.drawable.imageOne)
}
}
class TutorialPageOneFragment : TutorialBaseFragment() { override fun loadText() { title?.text = "title One" detail?.text = "detail One" } override fun loadImage() { image.setImageResource(R.drawable.imageOne) } }
class TutorialPageOneFragment : TutorialBaseFragment() {

    override fun loadText() {
        title?.text = "title One"
        detail?.text = "detail One"
    }

    override fun loadImage() {
        image.setImageResource(R.drawable.imageOne)
    }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class TutorialPageTwoFragment : TutorialBaseFragment() {
override fun loadText() {
title?.text = "title Two"
detail?.text = "detail Two"
}
override fun loadImage() {
image.setImageResource(R.drawable.imageTwo)
}
}
class TutorialPageTwoFragment : TutorialBaseFragment() { override fun loadText() { title?.text = "title Two" detail?.text = "detail Two" } override fun loadImage() { image.setImageResource(R.drawable.imageTwo) } }
class TutorialPageTwoFragment : TutorialBaseFragment() {

    override fun loadText() {
        title?.text = "title Two"
        detail?.text = "detail Two"
    }

    override fun loadImage() {
        image.setImageResource(R.drawable.imageTwo)
    }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class TutorialPageThreeFragment : TutorialBaseFragment() {
override fun loadText() {
title?.text = "title Three"
detail?.text = "detail Three"
}
override fun loadImage() {
image.setImageResource(R.drawable.imageThree)
}
}
class TutorialPageThreeFragment : TutorialBaseFragment() { override fun loadText() { title?.text = "title Three" detail?.text = "detail Three" } override fun loadImage() { image.setImageResource(R.drawable.imageThree) } }
class TutorialPageThreeFragment : TutorialBaseFragment() {

    override fun loadText() {
        title?.text = "title Three"
        detail?.text = "detail Three"
    }

    override fun loadImage() {
        image.setImageResource(R.drawable.imageThree)
    }
}

Be the first to comment

Leave a Reply

Your email address will not be published.


*