Add Drawer navigation. Convert to multiple fragments shown with app drawer.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-01-05 17:58:20 +01:00
parent 39b092c7c5
commit ec765b5fec
36 changed files with 468 additions and 242 deletions

View File

@@ -11,10 +11,15 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<service <activity
android:name=".SettingsService" android:name=".DrawerActivity"
android:enabled="true" android:exported="false"
android:exported="true"></service> android:label="@string/title_activity_drawer"
android:theme="@style/AppTheme.NoActionBar">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity <activity
android:name=".SettingsActivity" android:name=".SettingsActivity"
@@ -25,11 +30,6 @@
android:value="" /> android:value="" />
</activity> </activity>
<service
android:name=".Tichu"
android:enabled="true"
android:exported="true" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"

View File

@@ -1,137 +1,52 @@
package me.zobrist.tichucounter package me.zobrist.tichucounter
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import com.google.android.material.navigation.NavigationView
import androidx.activity.viewModels import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.drawerlayout.widget.DrawerLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers import me.zobrist.tichucounter.databinding.ActivityDrawerBinding
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import me.zobrist.tichucounter.data.Round
import me.zobrist.tichucounter.databinding.ActivityMainBinding
import me.zobrist.tichucounter.domain.Tichu
import me.zobrist.tichucounter.domain.getAbsoluteDifference
import me.zobrist.tichucounter.fragments.KeyboardViewModel
import me.zobrist.tichucounter.repository.GameRepository
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : BaseActivity() { class MainActivity : BaseActivity() {
private var currentRound: Round = Round(0, 0, null, null) private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDrawerBinding
private val keyboardViewModel: KeyboardViewModel by viewModels()
@Inject
lateinit var tichu: Tichu
@Inject
lateinit var gameRepository: GameRepository
private var ignoreNextUpdate: Boolean = false
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
binding = ActivityDrawerBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
setSupportActionBar(binding.toolbar) val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_drawer)
setSupportActionBar(binding.appBarDrawer.toolbar)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_counter, R.id.nav_history, R.id.nav_settings
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
GlobalScope.launch(Dispatchers.IO) {
val game = gameRepository.getActiveGame()
if (game == null) {
gameRepository.newGame()
}
}
keyboardViewModel.scoreA.observe(this) { value ->
val oldValue = currentRound.scoreA
currentRound.scoreA = value
if (ignoreNextUpdate) {
ignoreNextUpdate = false
} else {
if (currentRound.scoreA?.let { oldValue?.getAbsoluteDifference(it) } != 100) {
ignoreNextUpdate = true
currentRound.scoreB = tichu.calculateOtherScore(value)
keyboardViewModel.setScoreB(currentRound.scoreB)
}
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
}
}
keyboardViewModel.scoreB.observe(this) { value ->
val tichu = Tichu()
val oldValue = currentRound.scoreB
currentRound.scoreB = value
if (ignoreNextUpdate) {
ignoreNextUpdate = false
} else {
if (currentRound.scoreB?.let { oldValue?.getAbsoluteDifference(it) } != 100) {
ignoreNextUpdate = true
currentRound.scoreA = tichu.calculateOtherScore(value)
keyboardViewModel.setScoreA(currentRound.scoreA)
}
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
}
}
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onSupportNavigateUp(): Boolean {
// Inflate the menu; this adds items to the action bar if it is present. val navController = findNavController(R.id.nav_host_fragment_content_drawer)
menuInflater.inflate(R.menu.menu_main, menu) return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
//menu.findItem(R.id.action_screenOn).isChecked =
// this.getSharedPreferences("Settings", MODE_PRIVATE).getBoolean("Screen_On", false)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_clear -> {
val builder = AlertDialog.Builder(this)
builder.setMessage(getString(R.string.confirmClear)).setTitle(R.string.clear)
.setCancelable(false).setPositiveButton(getString(R.string.yes)) { dialog, _ ->
dialog.dismiss()
GlobalScope.launch(Dispatchers.IO) {
gameRepository.newGame()
}
}.setNegativeButton(getString(R.string.no)) { dialog, _ ->
dialog.cancel()
}
builder.create().show()
true
}
R.id.action_undo -> {
GlobalScope.launch(Dispatchers.IO) {
val history = gameRepository.getActiveRoundHistory()
if (history.isNotEmpty()) {
gameRepository.removeRoundFromHistory(history.last())
}
}
true
}
R.id.settings -> {
val i = Intent(this, SettingsActivity::class.java)
startActivity(i)
true
}
else -> super.onOptionsItemSelected(item)
}
} }
} }

View File

@@ -1,68 +0,0 @@
package me.zobrist.tichucounter
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.MenuItem
import androidx.preference.ListPreference
import androidx.preference.PreferenceFragmentCompat
import me.zobrist.tichucounter.databinding.SettingsActivityBinding
class SettingsActivity : BaseActivity() {
private lateinit var binding: SettingsActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = SettingsActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.replace(R.id.settings, SettingsFragment())
.commit()
}
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
supportActionBar?.title = resources.getString(R.string.settings)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
val i = Intent(this, MainActivity::class.java)
navigateUpTo(i)
true
}
else -> super.onOptionsItemSelected(item)
}
}
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
val index = when (getCurrentLocale()) {
"de" -> 1
"en" -> 0
else -> 0
}
findPreference<ListPreference>("language")?.setValueIndex(index)
}
private fun getCurrentLocale(): String? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
resources.configuration.locales.get(0).language
} else {
resources.configuration.locale.language
}
}
}
}

View File

@@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import dagger.hilt.android.AndroidEntryPoint
abstract class FragmentBase<VB : ViewBinding> : Fragment() { abstract class FragmentBase<VB : ViewBinding> : Fragment() {

View File

@@ -5,8 +5,10 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint
import me.zobrist.tichucounter.databinding.FragmentHistoryListBinding import me.zobrist.tichucounter.databinding.FragmentHistoryListBinding
@AndroidEntryPoint
class HistoryList : FragmentBase<FragmentHistoryListBinding>() { class HistoryList : FragmentBase<FragmentHistoryListBinding>() {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHistoryListBinding override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHistoryListBinding

View File

@@ -9,8 +9,10 @@ import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.EditText import android.widget.EditText
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint
import me.zobrist.tichucounter.databinding.FragmentKeyboardBinding import me.zobrist.tichucounter.databinding.FragmentKeyboardBinding
@AndroidEntryPoint
class Keyboard : FragmentBase<FragmentKeyboardBinding>() { class Keyboard : FragmentBase<FragmentKeyboardBinding>() {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentKeyboardBinding override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentKeyboardBinding

View File

@@ -10,7 +10,7 @@ import me.zobrist.tichucounter.repository.GameRepository
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class KeyboardViewModel @Inject constructor(val gameRepository: GameRepository) : ViewModel() { class KeyboardViewModel @Inject constructor(private val gameRepository: GameRepository) : ViewModel() {
private val _scoreA: MutableLiveData<Int?> = MutableLiveData() private val _scoreA: MutableLiveData<Int?> = MutableLiveData()
private val _scoreB: MutableLiveData<Int?> = MutableLiveData() private val _scoreB: MutableLiveData<Int?> = MutableLiveData()
private val _enableSubmitButton: MutableLiveData<Boolean> = MutableLiveData() private val _enableSubmitButton: MutableLiveData<Boolean> = MutableLiveData()

View File

@@ -6,8 +6,10 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.widget.doAfterTextChanged import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint
import me.zobrist.tichucounter.databinding.FragmentTeamNamesBinding import me.zobrist.tichucounter.databinding.FragmentTeamNamesBinding
@AndroidEntryPoint
class TeamNames : FragmentBase<FragmentTeamNamesBinding>() { class TeamNames : FragmentBase<FragmentTeamNamesBinding>() {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentTeamNamesBinding override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentTeamNamesBinding

View File

@@ -5,8 +5,10 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint
import me.zobrist.tichucounter.databinding.FragmentTeamScoresBinding import me.zobrist.tichucounter.databinding.FragmentTeamScoresBinding
@AndroidEntryPoint
class TeamScores : FragmentBase<FragmentTeamScoresBinding>() { class TeamScores : FragmentBase<FragmentTeamScoresBinding>() {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentTeamScoresBinding override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentTeamScoresBinding

View File

@@ -0,0 +1,119 @@
package me.zobrist.tichucounter.ui.counter
import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import me.zobrist.tichucounter.R
import me.zobrist.tichucounter.data.Round
import me.zobrist.tichucounter.databinding.FragmentCounterBinding
import me.zobrist.tichucounter.domain.Tichu
import me.zobrist.tichucounter.domain.getAbsoluteDifference
import me.zobrist.tichucounter.fragments.FragmentBase
import me.zobrist.tichucounter.fragments.KeyboardViewModel
import me.zobrist.tichucounter.repository.GameRepository
import javax.inject.Inject
@AndroidEntryPoint
class CounterFragment : FragmentBase<FragmentCounterBinding>(), MenuProvider {
@Inject lateinit var gameRepository: GameRepository
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentCounterBinding
get() = FragmentCounterBinding::inflate
private var currentRound: Round = Round(0, 0, null, null)
private var ignoreNextUpdate: Boolean = false
private val keyboardViewModel: KeyboardViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(
this, viewLifecycleOwner, Lifecycle.State.RESUMED
)
keyboardViewModel.scoreA.observe(viewLifecycleOwner) { value ->
val tichu = Tichu()
val oldValue = currentRound.scoreA
currentRound.scoreA = value
if (ignoreNextUpdate) {
ignoreNextUpdate = false
} else {
if (currentRound.scoreA?.let { oldValue?.getAbsoluteDifference(it) } != 100) {
ignoreNextUpdate = true
currentRound.scoreB = tichu.calculateOtherScore(value)
keyboardViewModel.setScoreB(currentRound.scoreB)
}
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
}
}
keyboardViewModel.scoreB.observe(viewLifecycleOwner) { value ->
val tichu = Tichu()
val oldValue = currentRound.scoreB
currentRound.scoreB = value
if (ignoreNextUpdate) {
ignoreNextUpdate = false
} else {
if (currentRound.scoreB?.let { oldValue?.getAbsoluteDifference(it) } != 100) {
ignoreNextUpdate = true
currentRound.scoreA = tichu.calculateOtherScore(value)
keyboardViewModel.setScoreA(currentRound.scoreA)
}
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
}
}
}
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu_counter, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_clear -> {
val builder = context?.let { AlertDialog.Builder(it) }
if(builder != null)
{
builder.setMessage(getString(R.string.confirmClear)).setTitle(R.string.clear)
.setCancelable(false).setPositiveButton(getString(R.string.yes)) { dialog, _ ->
dialog.dismiss()
viewLifecycleOwner.lifecycleScope.launch {
gameRepository.newGame()
}
}.setNegativeButton(getString(R.string.no)) { dialog, _ ->
dialog.cancel()
}
builder.create().show()
}
true
}
R.id.action_undo -> {
viewLifecycleOwner.lifecycleScope.launch {
val history = gameRepository.getActiveRoundHistory()
if (history.isNotEmpty()) {
gameRepository.removeRoundFromHistory(history.last())
}
}
true
}
else -> false
}
}
}

View File

@@ -0,0 +1,30 @@
package me.zobrist.tichucounter.ui.settings
import android.os.Build
import android.os.Bundle
import androidx.preference.ListPreference
import androidx.preference.PreferenceFragmentCompat
import me.zobrist.tichucounter.R
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
val index = when (getCurrentLocale()) {
"de" -> 1
"en" -> 0
else -> 0
}
findPreference<ListPreference>("language")?.setValueIndex(index)
}
private fun getCurrentLocale(): String? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
resources.configuration.locales.get(0).language
} else {
@Suppress("DEPRECATION")
resources.configuration.locale.language
}
}
}

View File

@@ -0,0 +1,38 @@
package me.zobrist.tichucounter.ui.slideshow
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import me.zobrist.tichucounter.databinding.FragmentSlideshowBinding
class SlideshowFragment : Fragment() {
private var _binding: FragmentSlideshowBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val slideshowViewModel =
ViewModelProvider(this).get(SlideshowViewModel::class.java)
_binding = FragmentSlideshowBinding.inflate(inflater, container, false)
val root: View = binding.root
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,13 @@
package me.zobrist.tichucounter.ui.slideshow
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SlideshowViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is slideshow Fragment"
}
val text: LiveData<String> = _text
}

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0" />
<path
android:fillColor="#FF000000"
android:pathData="M9,2L7.17,4H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2H9zm3,15c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M22,16V4c0,-1.1 -0.9,-2 -2,-2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zm-11,-4l2.03,2.71L16,11l4,5H8l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2H4V6H2z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6zm16,-4H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zm-8,12.5v-9l6,4.5 -6,4.5z" />
</vector>

View File

@@ -0,0 +1,9 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:centerColor="#009688"
android:endColor="#00695C"
android:startColor="#4DB6AC"
android:type="linear" />
</shape>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
android:id="@+id/app_bar_drawer"
layout="@layout/app_bar_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_drawer"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".DrawerActivity">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -20,8 +20,6 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<include <include layout="@layout/content_drawer" />
android:id="@+id/contentMain"
layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_drawer">
<fragment
android:id="@+id/nav_host_fragment_content_drawer"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/nav_header_desc"
android:paddingTop="@dimen/nav_header_vertical_spacing"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/nav_header_title"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nav_header_subtitle" />
</LinearLayout>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/settings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_counter"
android:icon="@drawable/ic_menu_camera"
android:title="@string/menu_counter" />
<item
android:id="@+id/nav_history"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/menu_history" />
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_menu_slideshow"
android:title="@string/menu_settings" />
</group>
</menu>

View File

@@ -15,10 +15,4 @@
android:orderInCategory="10" android:orderInCategory="10"
android:title="@string/clear" android:title="@string/clear"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/settings"
android:checkable="false"
android:orderInCategory="10"
android:title="@string/settings"
app:showAsAction="never" />
</menu> </menu>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/nav_counter">
<fragment
android:id="@+id/nav_counter"
android:name="me.zobrist.tichucounter.ui.counter.CounterFragment"
android:label="@string/menu_counter"
tools:layout="@layout/fragment_counter" />
<fragment
android:id="@+id/nav_history"
android:name="me.zobrist.tichucounter.ui.settings.SettingsFragment"
android:label="@string/menu_history"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/nav_settings"
android:name="me.zobrist.tichucounter.ui.settings.SettingsFragment"
android:label="@string/menu_settings"/>
</navigation>

View File

@@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">200dp</dimen>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

View File

@@ -0,0 +1,8 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="nav_header_vertical_spacing">8dp</dimen>
<dimen name="nav_header_height">176dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources>

View File

@@ -0,0 +1,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item name="ic_menu_camera" type="drawable">@android:drawable/ic_menu_camera</item>
<item name="ic_menu_gallery" type="drawable">@android:drawable/ic_menu_gallery</item>
<item name="ic_menu_slideshow" type="drawable">@android:drawable/ic_menu_slideshow</item>
<item name="ic_menu_manage" type="drawable">@android:drawable/ic_menu_manage</item>
<item name="ic_menu_share" type="drawable">@android:drawable/ic_menu_share</item>
<item name="ic_menu_send" type="drawable">@android:drawable/ic_menu_send</item>
</resources>

View File

@@ -21,4 +21,15 @@
<string name="dark">Dark</string> <string name="dark">Dark</string>
<string name="display">Display</string> <string name="display">Display</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="title_activity_drawer">DrawerActivity</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="nav_header_title">Tichu Counter</string>
<string name="nav_header_subtitle">app@zobrist.me</string>
<string name="nav_header_desc">Navigation header</string>
<string name="action_settings">Settings</string>
<string name="menu_counter">Counter</string>
<string name="menu_history">History</string>
<string name="menu_settings">Settings</string>
</resources> </resources>

View File

@@ -8,13 +8,4 @@
</style> </style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">true</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources> </resources>

View File

@@ -0,0 +1,11 @@
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>