Skip to content

Commit

Permalink
Merge pull request #3 from rahul-gill/main
Browse files Browse the repository at this point in the history
Initial setup: gradle, lint, styles, preview app
  • Loading branch information
rahul-gill committed Aug 20, 2022
2 parents 5632878 + 44dd959 commit f5ee292
Show file tree
Hide file tree
Showing 67 changed files with 2,102 additions and 245 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 19 additions & 11 deletions app/build.gradle
Expand Up @@ -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
Expand All @@ -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'
}
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mifos.mobile.ui">
package="org.mifos.mobile.ui.app">

<application
android:allowBackup="true"
Expand Down
11 changes: 0 additions & 11 deletions app/src/main/java/org/mifos/mobile/ui/MainActivity.kt

This file was deleted.

48 changes: 48 additions & 0 deletions app/src/main/java/org/mifos/mobile/ui/app/MainActivity.kt
@@ -0,0 +1,48 @@
package org.mifos.mobile.ui.app

import android.app.UiModeManager
import android.content.Context
import android.os.Build.VERSION
import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import org.mifos.mobile.ui.app.R
import org.mifos.mobile.ui.app.databinding.ActivityMainBinding
import org.mifos.mobile.ui.getThemeAttributeColor
import org.mifos.mobile.ui.setStatusBarColor

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(LayoutInflater.from(this))
setContentView(binding.root)

binding.bottomNav.setupWithNavController(findNavController(R.id.navHostFragment))

setStatusBarColor(getThemeAttributeColor(com.google.android.material.R.attr.colorSurface))
}

override fun onSupportNavigateUp() =
findNavController(R.id.navHostFragment).navigateUp() || super.onSupportNavigateUp()

private fun findNavController(navHostId: Int): NavController {
val navHostFragment = supportFragmentManager.findFragmentById(navHostId) as NavHostFragment
return navHostFragment.navController
}
}


fun Context.switchNightMode() {
val uiManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
if (VERSION.SDK_INT <= 22) {
uiManager.enableCarMode(0)
}
if (uiManager.nightMode == UiModeManager.MODE_NIGHT_NO) {
uiManager.nightMode = UiModeManager.MODE_NIGHT_YES
} else {
uiManager.nightMode = UiModeManager.MODE_NIGHT_NO
}
}
51 changes: 51 additions & 0 deletions app/src/main/java/org/mifos/mobile/ui/app/MainScreenFragment.kt
@@ -0,0 +1,51 @@
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.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import org.mifos.mobile.ui.app.R
import org.mifos.mobile.ui.app.databinding.FragmentMainScreenBinding
import org.mifos.mobile.ui.app.databinding.SampleCardBinding
import org.mifos.mobile.ui.app.util.GenericRecyclerViewAdapter

class MainScreenFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = FragmentMainScreenBinding.inflate(inflater, container, false)

binding.topAppBar.setOnMenuItemClickListener {
if(it.itemId == R.id.editTheme)
requireContext().switchNightMode()
true
}

binding.bottomSheetRecyclerView.adapter = GenericRecyclerViewAdapter(
items = List(30){ it },
bindingCreator = { parent -> 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
}
}
32 changes: 32 additions & 0 deletions 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
}
}
61 changes: 61 additions & 0 deletions 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
}

}
@@ -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<T: Any, VBType: ViewBinding>(
items: List<T>,
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<T, GenericRecyclerViewAdapter.GenericViewHolder>(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<T> diffCallBackBy(comparator: (oldItem: T, newItem: T) -> Boolean) = object : DiffUtil.ItemCallback<T>() {
override fun areItemsTheSame(oldItem: T, newItem: T)
= comparator(oldItem, newItem)

@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: T, newItem: T)
= (oldItem == newItem)

}
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M21,18v1c0,1.1 -0.9,2 -2,2L5,21c-1.11,0 -2,-0.9 -2,-2L3,5c0,-1.1 0.89,-2 2,-2h14c1.1,0 2,0.9 2,2v1h-9c-1.11,0 -2,0.9 -2,2v8c0,1.1 0.89,2 2,2h9zM12,16h10L22,8L12,8v8zM16,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z"/>
</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_baseline_account_circle_24.xml
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,6c1.93,0 3.5,1.57 3.5,3.5S13.93,13 12,13s-3.5,-1.57 -3.5,-3.5S10.07,6 12,6zM12,20c-2.03,0 -4.43,-0.82 -6.14,-2.88C7.55,15.8 9.68,15 12,15s4.45,0.8 6.14,2.12C16.43,19.18 14.03,20 12,20z"/>
</vector>

0 comments on commit f5ee292

Please sign in to comment.