diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..5fb62c5 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index d7bfda1..56be5ec 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -11,10 +11,10 @@ - diff --git a/.idea/misc.xml b/.idea/misc.xml index 2a4d5b5..f0873a2 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,29 @@ + + + diff --git a/app/build.gradle b/app/build.gradle index 65579f4..f1244ea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ android { compileSdk 32 defaultConfig { - applicationId "org.mifos.mobile.ui" + applicationId "org.mifos.mobile.ui.app" minSdk 22 targetSdk 32 versionCode 1 @@ -23,22 +23,30 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' + } + buildFeatures{ + viewBinding = true + } + + lintOptions{ + abortOnError false } } dependencies { + implementation libraries.androidx_core + implementation libraries.app_compat + implementation libraries.material + implementation libraries.constraint_layout + implementation libraries.navigation_component + + testImplementation libraries.junit + androidTestImplementation libraries.android_tests - implementation 'androidx.core:core-ktx:1.7.0' - implementation 'androidx.appcompat:appcompat:1.4.1' - implementation 'com.google.android.material:material:1.5.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation project(path: ':uihouse') - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a4614e7..f14cfaa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="org.mifos.mobile.ui.app"> SampleCardBinding.inflate(LayoutInflater.from(parent.context), parent, false) }, + itemOnClick = { + val dialog = MaterialAlertDialogBuilder(requireContext()) + .setTitle("Sample Dialog") + .setIcon(R.drawable.ic_launcher_foreground) + .setMessage("This is some random long dialog message. Just to show you how it looks") + .setPositiveButton("OK"){ dialogInterface, _ -> dialogInterface.dismiss() } + .setNegativeButton("Cancel"){ dialogInterface, _ -> dialogInterface.dismiss() } + .show() + }, + itemOnLongClick = lambda@{ + val snackBar = Snackbar.make(binding.root, "Item Long Clicked position $it", Snackbar.LENGTH_SHORT) + snackBar.setAction("OK"){ snackBar.dismiss() } + snackBar.show() + return@lambda true + } + ) + + return binding.root + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/app/SecondFragment.kt b/app/src/main/java/org/mifos/mobile/ui/app/SecondFragment.kt new file mode 100644 index 0000000..0df8459 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/ui/app/SecondFragment.kt @@ -0,0 +1,32 @@ +package org.mifos.mobile.ui.app + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.android.material.textfield.MaterialAutoCompleteTextView +import org.mifos.mobile.ui.app.R +import org.mifos.mobile.ui.app.databinding.FragmentSecondBinding + +class SecondFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val binding = FragmentSecondBinding.inflate(inflater, container, false) + + binding.topAppBar.setOnMenuItemClickListener { + if(it.itemId == R.id.editTheme) + requireContext().switchNightMode() + true + } + + (binding.dropDown.editText as? MaterialAutoCompleteTextView)?.setSimpleItems( + arrayOf("Item 1", "Item 2", "Item 3", "Item 4") + ) + + return binding.root + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/app/ThirdFragment.kt b/app/src/main/java/org/mifos/mobile/ui/app/ThirdFragment.kt new file mode 100644 index 0000000..d9cb077 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/ui/app/ThirdFragment.kt @@ -0,0 +1,61 @@ +package org.mifos.mobile.ui.app + +import android.app.DatePickerDialog +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.DatePicker +import android.widget.Toast +import androidx.fragment.app.Fragment +import com.google.android.material.datepicker.CalendarConstraints +import com.google.android.material.datepicker.DateValidatorPointForward +import com.google.android.material.datepicker.MaterialDatePicker +import org.mifos.mobile.ui.app.databinding.FragmentThirdBinding +import java.time.LocalDate +import java.time.Year +import java.util.* + +class ThirdFragment : Fragment() { + + var previouslySelectedDate: Long? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val binding = FragmentThirdBinding.inflate(inflater, container, false) + + binding.apply { + profileImage.setOnImageChangeButtonListener{ + Toast.makeText(requireContext(), "Image change button clicked", Toast.LENGTH_SHORT).show() + } + + dateDialogTrigger.setOnClickListener { + val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")) + calendar.timeInMillis = MaterialDatePicker.todayInUtcMilliseconds() + val startConst = calendar.timeInMillis + calendar[Calendar.DAY_OF_MONTH] = calendar[Calendar.DAY_OF_MONTH] + 10 + val endConst = calendar.timeInMillis + + val constraints: CalendarConstraints = CalendarConstraints.Builder() + .setOpenAt(previouslySelectedDate ?: MaterialDatePicker.todayInUtcMilliseconds()) + .setValidator(DateValidatorPointForward.now()) + .build() + + val dialog = MaterialDatePicker + .Builder + .datePicker() + .setCalendarConstraints(constraints) + .setTitleText("Select payment date") + .setSelection(previouslySelectedDate ?: MaterialDatePicker.todayInUtcMilliseconds()) + .build() + dialog.addOnPositiveButtonClickListener { previouslySelectedDate = it } + dialog.show(parentFragmentManager, "DATE_PICKER") + } + } + + return binding.root + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/app/util/GenericRecyclerViewAdapter.kt b/app/src/main/java/org/mifos/mobile/ui/app/util/GenericRecyclerViewAdapter.kt new file mode 100644 index 0000000..4c14865 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/ui/app/util/GenericRecyclerViewAdapter.kt @@ -0,0 +1,51 @@ +package org.mifos.mobile.ui.app.util + +import android.annotation.SuppressLint +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import androidx.viewbinding.ViewBinding + + +class GenericRecyclerViewAdapter( + items: List, + itemComparator:(oldItem: T, newItem: T) -> Boolean = { a,b -> a == b}, + private val bindingCreator: (parent: ViewGroup) -> VBType, + private val bindItemWithHolder: (item: T, binding: VBType) -> Unit = {_,_ ->}, + private val itemOnClick: (item: T) -> Unit = {}, + private val itemOnLongClick: (item: T) -> Boolean = {false} +) : ListAdapter(diffCallBackBy(itemComparator)) { + + init { + submitList(items) + } + + class GenericViewHolder(val binding: ViewBinding) : RecyclerView.ViewHolder(binding.root) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder { + val binding = bindingCreator(parent) + val viewHolder = GenericViewHolder(binding) + binding.root.setOnClickListener { itemOnClick(getItem(viewHolder.adapterPosition)) } + binding.root.setOnLongClickListener { itemOnLongClick(getItem(viewHolder.adapterPosition)) } + return viewHolder + } + + + @Suppress("UNCHECKED_CAST") + override fun onBindViewHolder(viewHolder: GenericViewHolder, position: Int) + = bindItemWithHolder(getItem(position) as T, viewHolder.binding as VBType) + + +} + + +fun diffCallBackBy(comparator: (oldItem: T, newItem: T) -> Boolean) = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: T, newItem: T) + = comparator(oldItem, newItem) + + @SuppressLint("DiffUtilEquals") + override fun areContentsTheSame(oldItem: T, newItem: T) + = (oldItem == newItem) + +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_baseline_account_balance_wallet_24.xml b/app/src/main/res/drawable/ic_baseline_account_balance_wallet_24.xml new file mode 100644 index 0000000..ebed1ce --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_account_balance_wallet_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_account_circle_24.xml b/app/src/main/res/drawable/ic_baseline_account_circle_24.xml new file mode 100644 index 0000000..93ce250 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_account_circle_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_dark_mode_24.xml b/app/src/main/res/drawable/ic_baseline_dark_mode_24.xml new file mode 100644 index 0000000..3b52248 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_dark_mode_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_home_24.xml b/app/src/main/res/drawable/ic_baseline_home_24.xml new file mode 100644 index 0000000..5a870f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_home_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..bb45125 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -5,166 +5,6 @@ android:viewportWidth="108" android:viewportHeight="108"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/sample_user_image.xml b/app/src/main/res/drawable/sample_user_image.xml new file mode 100644 index 0000000..6ead84f --- /dev/null +++ b/app/src/main/res/drawable/sample_user_image.xml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fc2444..566e040 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,13 +6,23 @@ android:layout_height="match_parent" tools:context=".MainActivity"> - + + + app:menu="@menu/bottom_nav_destinations"/> \ No newline at end of file diff --git a/app/src/main/res/layout/drawer_header.xml b/app/src/main/res/layout/drawer_header.xml new file mode 100644 index 0000000..590408d --- /dev/null +++ b/app/src/main/res/layout/drawer_header.xml @@ -0,0 +1,36 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main_screen.xml b/app/src/main/res/layout/fragment_main_screen.xml new file mode 100644 index 0000000..439d650 --- /dev/null +++ b/app/src/main/res/layout/fragment_main_screen.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_second.xml b/app/src/main/res/layout/fragment_second.xml new file mode 100644 index 0000000..e47e82d --- /dev/null +++ b/app/src/main/res/layout/fragment_second.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + +