Added app language support (I think); fragments rely on Bundles instead of constructor parameters to get data, mitigating a source of crashes

This commit is contained in:
denizk0461
2023-04-30 22:47:59 +02:00
parent 7243df0f06
commit 079e66ad50
23 changed files with 619 additions and 472 deletions
+8 -1
View File
@@ -13,7 +13,8 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.StudIPTimetable"
tools:targetApi="31">
tools:targetApi="33"
android:localeConfig="@xml/locales_config">
<activity
android:name=".activity.MainActivity"
@@ -31,6 +32,12 @@
android:exported="false"
android:theme="@style/Theme.StudIPTimetable">
</activity>
<activity
android:name=".activity.ImageActivity"
android:exported="false"
android:theme="@style/Theme.StudIPTimetable">
</activity>
</application>
</manifest>
@@ -1,12 +1,12 @@
package com.denizk0461.studip.activity
import android.annotation.SuppressLint
import android.app.Activity
import android.os.Bundle
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.denizk0461.studip.R
import com.denizk0461.studip.data.showErrorSnackBar
@@ -19,7 +19,7 @@ import java.net.URLDecoder
* Activity for allowing the user to log in to access and fetch their schedule from their Stud.IP
* profile. Launched through a button in the app's settings.
*/
class FetcherActivity : Activity() {
class FetcherActivity : AppCompatActivity() {
// View binding
private lateinit var binding: ActivityFetcherBinding
@@ -0,0 +1,32 @@
package com.denizk0461.studip.activity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import com.denizk0461.studip.R
import com.denizk0461.studip.databinding.ActivityImageBinding
/**
* Activity used solely to display a single image. Not a critical part of the app.
*/
class ImageActivity : AppCompatActivity() {
// View binding
private lateinit var binding: ActivityImageBinding
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
// Inflate view binding and bind to this activity
binding = ActivityImageBinding.inflate(layoutInflater)
setContentView(binding.root)
// Set the image of the view
binding.imageView.setImageResource(when (intent.extras?.getString("img") ?: "") {
"bojack" -> { R.drawable.man }
"garbage" -> { R.drawable.garbage }
else -> { R.drawable.engineering }
})
}
}
@@ -41,20 +41,6 @@ class MainActivity : FragmentActivity() {
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Open the fragment that the user specified to open on app start
if (
AppRepository.getRepositoryInstance(application)
.getBooleanPreference(SettingsPreferences.LAUNCH_CANTEEN_ON_START)
) {
// Open canteen fragment
binding.contentMain.navView.selectedItemId = R.id.food
currentFragment = "canteen"
} else {
// Open event fragment
binding.contentMain.navView.selectedItemId = R.id.plan
currentFragment = "event"
}
// Set up navigation view bar to launch fragments
binding.contentMain.navView.setOnItemSelectedListener { item ->
// Launch fragment based on the item that has been clicked
@@ -65,8 +51,24 @@ class MainActivity : FragmentActivity() {
})
}
// Launch the fragment defined in currentFragment
loadFragment(currentFragment)
// Set up bottom nav bar and the initial fragment when the app launches
if (savedInstanceState == null) {
// Open the fragment that the user specified to open on app start
if (AppRepository.getRepositoryInstance(application)
.getBooleanPreference(SettingsPreferences.LAUNCH_CANTEEN_ON_START)
) {
// Open canteen fragment
binding.contentMain.navView.selectedItemId = R.id.food
currentFragment = "canteen"
} else {
// Open event fragment
binding.contentMain.navView.selectedItemId = R.id.plan
currentFragment = "event"
}
// Launch the fragment defined in currentFragment
loadFragment(currentFragment)
}
}
/**
@@ -1,19 +1,22 @@
package com.denizk0461.studip.adapter
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.denizk0461.studip.fragment.CanteenPageFragment
/**
* Custom ViewPager adapter for managing multiple pages of canteen offers.
*
* @param fragmentActivity parent fragment activity
* @param childFragmentManager child fragment manager of the parent fragment
* @param lifecycle parent fragment lifecycle
*/
class CanteenOfferPageAdapter(
fragmentActivity: FragmentActivity,
) : FragmentStateAdapter(fragmentActivity) {
childFragmentManager: FragmentManager,
lifecycle: Lifecycle,
) : FragmentStateAdapter(childFragmentManager, lifecycle) {
private var count: Int = 0
@@ -21,9 +24,11 @@ class CanteenOfferPageAdapter(
override fun getItemCount(): Int = count
override fun createFragment(position: Int): Fragment =
CanteenPageFragment(
position,
)
CanteenPageFragment().also { f ->
val bundle = Bundle()
bundle.putInt("currentDay", position)
f.arguments = bundle
}
fun setItemCount(newCount: Int) {
count = newCount
@@ -1,18 +1,22 @@
package com.denizk0461.studip.adapter
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.denizk0461.studip.fragment.EventPageFragment
/**
* Custom ViewPager adapter for managing multiple pages of Stud.IP events.
*
* @param fragmentActivity parent fragment activity
* @param childFragmentManager child fragment manager of the parent fragment
* @param lifecycle parent fragment lifecycle
*/
class StudIPEventPageAdapter(
fragmentActivity: FragmentActivity,
) : FragmentStateAdapter(fragmentActivity) {
childFragmentManager: FragmentManager,
lifecycle: Lifecycle,
) : FragmentStateAdapter(childFragmentManager, lifecycle) {
/*
* Assume that there will always be 7 pages, for 7 days - Monday through Sunday.
@@ -20,5 +24,9 @@ class StudIPEventPageAdapter(
override fun getItemCount(): Int = 7
override fun createFragment(position: Int): Fragment =
EventPageFragment(position)
EventPageFragment().also { f ->
val bundle = Bundle()
bundle.putInt("currentDay", position)
f.arguments = bundle
}
}
@@ -1,5 +1,6 @@
package com.denizk0461.studip.fragment
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.denizk0461.studip.sheet.AppSheet
@@ -10,6 +11,19 @@ import com.denizk0461.studip.sheet.AppSheet
*/
open class AppFragment : Fragment() {
// Internal context object
private lateinit var _context: Context
/**
* Get non-null context. Only valid after onAttach().
*/
override fun getContext(): Context = _context
override fun onAttach(context: Context) {
super.onAttach(context)
_context = context
}
/**
* Opens a bottom sheet. Sheet must be a subclass of [com.denizk0461.studip.sheet.AppSheet].
*
@@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.viewModels
import com.denizk0461.studip.R
import com.denizk0461.studip.adapter.CanteenOfferPageAdapter
@@ -137,7 +136,10 @@ class CanteenFragment : AppFragment() {
}
// Set up the view pager's adapter
viewPagerAdapter = CanteenOfferPageAdapter(activity as FragmentActivity)
viewPagerAdapter = CanteenOfferPageAdapter(
childFragmentManager,
lifecycle,
)
// Date count is observed to correctly set the amount of pages and the corresponding tabs
viewModel.getDates().observe(viewLifecycleOwner) { newDates ->
@@ -225,7 +227,7 @@ class CanteenFragment : AppFragment() {
binding.swipeRefreshLayout.isRefreshing = false
}, onError = {
context?.theme?.showErrorSnackBar(
context.theme?.showErrorSnackBar(
binding.snackbarContainer,
getString(R.string.canteen_fetch_error)
)
@@ -19,12 +19,8 @@ import com.denizk0461.studip.viewmodel.CanteenPageViewModel
/**
* Fragment that is instantiated by [StudIPEventPageAdapter] to display individual days' pages and
* their events.
*
* @param currentDay day to display
*/
class CanteenPageFragment(
private val currentDay: Int,
) : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
class CanteenPageFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
// Nullable view binding reference
private var _binding: RecyclerViewBinding? = null
@@ -42,8 +38,18 @@ class CanteenPageFragment(
private val offerList: MutableList<CanteenOffer> = mutableListOf()
/**
* Current day that is used to show only events of a given day (0 = Monday, 4 = Friday)
*/
private var currentDay: Int = -1
// Instantiate the view binding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
// Retrieve current day to fetch items specifically for that day
currentDay = arguments?.getInt("currentDay") ?: -1
// Inflate view binding
_binding = RecyclerViewBinding.inflate(inflater, container, false)
return binding.root
}
@@ -1,11 +1,9 @@
package com.denizk0461.studip.fragment
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.viewModels
import com.denizk0461.studip.R
import com.denizk0461.studip.adapter.StudIPEventPageAdapter
@@ -40,11 +38,6 @@ class EventFragment : AppFragment() {
// Titles for the view pager's tabs
private lateinit var weekdays: Array<String>
// private var viewPagerScrollPosition: Parcelable? = null
private var viewPagerPosition = -1
private var hasFragmentStarted = false
// Instantiate the view binding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentEventBinding.inflate(inflater, container, false)
@@ -55,7 +48,7 @@ class EventFragment : AppFragment() {
super.onViewCreated(view, savedInstanceState)
// Get localised weekday names
weekdays = context?.resources?.getStringArray(R.array.weekdays) ?: arrayOf()
weekdays = context.resources?.getStringArray(R.array.weekdays) ?: arrayOf()
// Determine the current day
dayOfWeek = when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) {
@@ -69,7 +62,10 @@ class EventFragment : AppFragment() {
}
// Set up the view pager's adapter
viewPagerAdapter = StudIPEventPageAdapter(activity as FragmentActivity)
viewPagerAdapter = StudIPEventPageAdapter(
childFragmentManager,
lifecycle,
)
// Assign the adapter to the view pager
binding.viewPager.adapter = viewPagerAdapter
@@ -78,75 +74,33 @@ class EventFragment : AppFragment() {
TabLayoutMediator(binding.dayTabLayout, binding.viewPager) { tab, position ->
tab.text = weekdays[position]
}.attach()
// Set up LiveData observer to refresh the view on update
// viewModel.allEvents.observe(viewLifecycleOwner) { events ->
//
// Log.d("AAAbA?", events.toString())
//
// // Update the item list in the view pager's adapter
// viewPagerAdapter.setNewItems(events)
//
// if (!hasFragmentStarted) {
// // Scroll to the current day, if no page has been stored to be scrolled to
// switchToCurrentDayView()
// hasFragmentStarted = true
//// } else {
//// /*
//// * If a page was previously saved, scroll to that one instead. This is meant to
//// * prevent jumping from
//// */
//// binding.viewPager.currentItem = viewPagerPosition
// }
// }
}
override fun onPause() {
// viewPagerPosition = binding.viewPager.currentItem
// Log.d("AAA?", "onpause: $viewPagerPosition")
super.onPause()
}
override fun onResume() {
super.onResume()
binding.viewPager.currentItem = viewPagerPosition
Log.d("AAA?", "onresume: pos: $viewPagerPosition; vpp: ${binding.viewPager.currentItem}")
// Scroll to the current day
// switchToCurrentDayView()
}
/**
* Called when the layout changes (e.g. device rotation) but NOT when the fragment is selected
* from the bottom navigation view.
*/
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Log.d("AAA?", "${binding.viewPager.currentItem}")
outState.putInt(
"viewPagerCurrentPage",
binding.viewPager.currentItem
)
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
val restoredPage = savedInstanceState?.getInt("viewPagerCurrentPage") ?: 0
viewPagerPosition = restoredPage
}
// override fun onSaveInstanceState(outState: Bundle) {
// super.onSaveInstanceState(outState)
//
// outState.putInt(
// "viewPagerCurrentPage",
// binding.viewPager.currentItem
// )
// }
//
// override fun onViewStateRestored(savedInstanceState: Bundle?) {
// super.onViewStateRestored(savedInstanceState)
//
// // Retrieve
// val restoredPage = savedInstanceState?.getInt("viewPagerCurrentPage") ?: 0
//
//// binding.viewPager.currentItem = restoredPage
// }
// Invalidate the view binding
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
/**
* Scroll to the current day. Current day is determined after the fragment's view has been
* created.
*/
private fun switchToCurrentDayView() {
binding.viewPager.currentItem = dayOfWeek
}
}
@@ -16,13 +16,8 @@ import com.denizk0461.studip.viewmodel.EventPageViewModel
/**
* Fragment that is instantiated by [StudIPEventPageAdapter] to display individual days' pages and
* their events.
*
* @param currentDay current day that is used to show only events of a given day (0 = Monday,
* 4 = Friday)
*/
class EventPageFragment(
private val currentDay: Int,
) : AppFragment(), StudIPEventItemAdapter.OnClickListener {
class EventPageFragment : AppFragment(), StudIPEventItemAdapter.OnClickListener {
// Nullable view binding reference
private var _binding: RecyclerViewBinding? = null
@@ -39,10 +34,23 @@ class EventPageFragment(
/**
* Adapter that manages the page's items
*/
private val eventAdapter = StudIPEventItemAdapter(currentDay, this)
private lateinit var eventAdapter: StudIPEventItemAdapter
/**
* Current day that is used to show only events of a given day (0 = Monday, 4 = Friday)
*/
private var currentDay = -1
// Instantiate the view binding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
// Retrieve current day to fetch items specifically for that day
currentDay = arguments?.getInt("currentDay") ?: -1
// Instantiate event adapter with the current day
eventAdapter = StudIPEventItemAdapter(currentDay, this)
// Inflate view binding
_binding = RecyclerViewBinding.inflate(inflater, container, false)
return binding.root
}
@@ -11,6 +11,8 @@ import androidx.fragment.app.viewModels
import com.denizk0461.studip.BuildConfig
import com.denizk0461.studip.R
import com.denizk0461.studip.activity.FetcherActivity
import com.denizk0461.studip.activity.ImageActivity
import com.denizk0461.studip.data.showToast
import com.denizk0461.studip.databinding.FragmentSettingsBinding
import com.denizk0461.studip.sheet.DevCodeSheet
import com.denizk0461.studip.sheet.TextSheet
@@ -36,7 +38,7 @@ class SettingsFragment : AppFragment() {
private val viewModel: SettingsViewModel by viewModels()
// Click counter on the app version button
private var appVersionClick = 0
private var appVersionClick = 1
// 222
private val mysteryLink = "https://www.youtube.com/watch?v=nhIQMCXJzLI"
@@ -129,7 +131,39 @@ class SettingsFragment : AppFragment() {
// Set click listener for the app version button
binding.buttonAppVersion.setOnClickListener {
when (appVersionClick) {
22 -> {
3 -> {
startActivity(Intent(context, ImageActivity::class.java).also { intent ->
val bundle = Bundle()
bundle.putString("img", "garbage")
intent.putExtras(bundle)
})
appVersionClick += 1
}
10 -> {
showToast(context, "ahhh yes")
appVersionClick += 1
}
15 -> {
showToast(context, "keep clicking")
appVersionClick += 1
}
20 -> {
showToast(context, "^_^")
appVersionClick += 1
}
30 -> {
showToast(context, "^_____^")
appVersionClick += 1
}
121 -> {
showToast(context, "Shouldn't you study for your exam?")
appVersionClick += 1
}
200 -> {
showToast(context, "\\__*")
appVersionClick += 1
}
222 -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(mysteryLink)))
appVersionClick = 0
}
@@ -145,7 +179,8 @@ class SettingsFragment : AppFragment() {
binding.appVersionText.text =
"${BuildConfig.VERSION_NAME}-${
if (BuildConfig.DEBUG)
"dev-[${SimpleDateFormat("yyyy-MM-dd, HH:mm:ss.SSS", Locale.GERMANY).format(Date(BuildConfig.TIMESTAMP))}]"
"dev-[${SimpleDateFormat("yyyy-MM-dd, HH:mm:ss.SSS", Locale.GERMANY)
.format(Date(BuildConfig.TIMESTAMP))}]"
else
"release"
}"
@@ -6,6 +6,7 @@ import android.os.Bundle
import android.util.Base64
import android.view.View
import com.denizk0461.studip.R
import com.denizk0461.studip.activity.ImageActivity
import com.denizk0461.studip.data.showToast
import com.denizk0461.studip.data.viewBinding
import com.denizk0461.studip.databinding.SheetDevCodeBinding
@@ -63,6 +64,14 @@ class DevCodeSheet(
"X0RSV05f".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9SUVpUUy1CWjhtcw==".d64)
"TUFSR0Uh".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS8tbHFxRHZXRjQ1dw==".d64)
"UE9XRUxM".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9XUGMtVkVxQlBISQ==".d64)
"Q0FMTE1F".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS8xbTV1WnJNMnktMA==".d64)
"Qk9KQUNL".d64 -> {
startActivity(Intent(context, ImageActivity::class.java).also { intent ->
val bundle = Bundle()
bundle.putString("img", "bojack")
intent.putExtras(bundle)
})
}
"NEVENT" -> { // nuke events
nukeEvents()
showToast(context, "Nuked all events")
Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

@@ -0,0 +1,17 @@
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:scaleType="fitCenter"/>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -104,6 +104,9 @@
android:id="@+id/chip_pref_fair"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/handshake"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_fair"/>
<com.google.android.material.chip.Chip
@@ -111,6 +114,9 @@
android:id="@+id/chip_pref_fish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/fish"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_fish"/>
<com.google.android.material.chip.Chip
@@ -118,6 +124,9 @@
android:id="@+id/chip_pref_poultry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/chicken"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_poultry"/>
<com.google.android.material.chip.Chip
@@ -125,6 +134,9 @@
android:id="@+id/chip_pref_lamb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/sheep"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_lamb"/>
<com.google.android.material.chip.Chip
@@ -132,6 +144,9 @@
android:id="@+id/chip_pref_vital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/yoga"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_vital"/>
<com.google.android.material.chip.Chip
@@ -139,6 +154,9 @@
android:id="@+id/chip_pref_beef"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/cow"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_beef"/>
<com.google.android.material.chip.Chip
@@ -146,6 +164,9 @@
android:id="@+id/chip_pref_pork"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/pig"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_pork"/>
<com.google.android.material.chip.Chip
@@ -153,6 +174,9 @@
android:id="@+id/chip_pref_vegetarian"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/carrot"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_vegetarian"/>
<com.google.android.material.chip.Chip
@@ -160,6 +184,9 @@
android:id="@+id/chip_pref_vegan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/leaf"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_vegan"/>
<com.google.android.material.chip.Chip
@@ -167,6 +194,9 @@
android:id="@+id/chip_pref_game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/deer"
app:chipIconEnabled="true"
app:chipIconTint="?attr/colorText"
android:text="@string/pref_game"/>
</com.google.android.material.chip.ChipGroup>
+360 -351
View File
@@ -1,471 +1,480 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.appcompat.widget.LinearLayoutCompat 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"
tools:context=".fragment.SettingsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragment.SettingsFragment">
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<TextView
android:id="@+id/app_title_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="@string/title_settings"
android:textSize="32sp"
android:fontFamily="@font/lato_bolditalic"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"/>
android:layout_marginTop="16dp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/title_settings"
android:textSize="32sp" />
</com.google.android.material.appbar.AppBarLayout>
</com.google.android.material.appbar.AppBarLayout>
<!-- Stud.IP schedule settings -->
<com.google.android.material.card.MaterialCardView
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="4dp"
style="@style/Widget.Material3.CardView.Outlined">
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
<!-- Stud.IP schedule settings -->
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Outlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:textSize="22sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_schedule"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="16dp"/>
<com.google.android.material.divider.MaterialDivider
style="@style/DividerTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"/>
<!-- Refresh schedule -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/button_refresh_schedule"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:background="?android:attr/selectableItemBackground">
android:paddingBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/refresh_schedule_title"/>
android:text="@string/settings_schedule"
android:textSize="22sp" />
<TextView
android:layout_width="wrap_content"
<com.google.android.material.divider.MaterialDivider
style="@style/DividerTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/refresh_schedule_subtitle"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- Highlight course -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_highlight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
android:layout_marginHorizontal="16dp" />
<!-- Refresh schedule -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:id="@+id/button_refresh_schedule"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_highlight"
android:layout_marginEnd="8dp">
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_highlight_title"/>
android:text="@string/refresh_schedule_title"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_highlight_subtitle"/>
android:text="@string/refresh_schedule_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_highlight"
android:layout_width="wrap_content"
<!-- Highlight course -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_highlight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_highlight"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.appcompat.widget.LinearLayoutCompat>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_highlight_title"
android:textSize="16sp" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_highlight_subtitle"
android:textSize="16sp" />
<!-- canteen settings -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="4dp"
style="@style/Widget.Material3.CardView.Outlined">
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_highlight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.card.MaterialCardView>
<!-- canteen settings -->
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Outlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:textSize="22sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_canteen"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="16dp"/>
<com.google.android.material.divider.MaterialDivider
style="@style/DividerTheme"
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"/>
android:orientation="vertical"
android:paddingBottom="8dp">
<!-- Allergens -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_allergens"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_allergens"
android:layout_marginEnd="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_allergens_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_allergens_subtitle"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_allergens"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_canteen"
android:textSize="22sp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Preference colouring -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_pref_colour"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
<com.google.android.material.divider.MaterialDivider
style="@style/DividerTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_pref_colour"
android:layout_marginEnd="8dp">
android:layout_marginHorizontal="16dp" />
<TextView
<!-- Allergens -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_allergens"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_allergens"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_allergens_title"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_allergens_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_allergens"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_pref_colour_title"/>
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Preference colouring -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_pref_colour"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_pref_colour"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_pref_colour_title"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_pref_colour_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_pref_colour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_pref_colour_subtitle"/>
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_pref_colour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.card.MaterialCardView>
<!-- miscellaneous settings -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="4dp"
style="@style/Widget.Material3.CardView.Outlined">
<androidx.appcompat.widget.LinearLayoutCompat
<!-- miscellaneous settings -->
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Outlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:textSize="22sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_misc"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="16dp"/>
<com.google.android.material.divider.MaterialDivider
style="@style/DividerTheme"
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"/>
android:orientation="vertical"
android:paddingBottom="8dp">
<!-- show canteen plan on app launch -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_launch_canteen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_misc"
android:textSize="22sp" />
<com.google.android.material.divider.MaterialDivider
style="@style/DividerTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp" />
<!-- show canteen plan on app launch -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_launch_canteen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_launch_canteen"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_launch_canteen_title"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_launch_canteen_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_launch_canteen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- crashlytics opt-in -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_crashlytics"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_crashlytics"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_crashlytics_title"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_crashlytics_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_crashlytics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Data handling -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/button_data_handling"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_launch_canteen"
android:layout_marginEnd="8dp">
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_launch_canteen_title"/>
android:text="@string/settings_data_title"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_launch_canteen_subtitle"/>
android:text="@string/settings_data_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_launch_canteen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- crashlytics opt-in -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_crashlytics"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<!-- Licences -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:id="@+id/button_licences"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_crashlytics"
android:layout_marginEnd="8dp">
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_crashlytics_title"/>
android:text="@string/settings_licences_title"
android:textSize="16sp" />
<TextView
android:id="@+id/licences_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_crashlytics_subtitle"/>
android:text="@string/settings_licences_subtitle"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_crashlytics"
android:layout_width="wrap_content"
<!-- App version -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/button_app_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_app_version"
android:textSize="16sp" />
<!-- Data handling -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/button_data_handling"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/app_version_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_data_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_data_subtitle"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- Licences -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/button_licences"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:background="?android:attr/selectableItemBackground">
</com.google.android.material.card.MaterialCardView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_licences_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:text="@string/with_love"
android:textAlignment="center"
android:textSize="8sp"
tools:ignore="SmallSp" />
<TextView
android:id="@+id/licences_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/settings_licences_subtitle"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView>
<!-- App version -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/button_app_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:background="?android:attr/selectableItemBackground">
</androidx.appcompat.widget.LinearLayoutCompat>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:fontFamily="@font/lato_bolditalic"
android:text="@string/settings_app_version"/>
<TextView
android:id="@+id/app_version_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.card.MaterialCardView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/with_love"
android:textSize="8sp"
android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:textAlignment="center"
tools:ignore="SmallSp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView>
+3 -1
View File
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.appcompat.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="8dp"
@@ -50,4 +51,5 @@
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.card.MaterialCardView>
</androidx.appcompat.widget.LinearLayoutCompat>
+1 -1
View File
@@ -32,7 +32,7 @@
<item name="android:textColor">@color/md_theme_dark_onSurfaceVariant</item>
<item name="colorText">@color/md_theme_dark_onSurfaceVariant</item>
<item name="android:scrollbarThumbVertical">@color/md_theme_dark_onSurfaceVariant</item>
<item name="android:scrollbarThumbVertical">@color/md_theme_dark_primary</item> <!-- md_theme_dark_onSurfaceVariant -->
<item name="colorOutlineVariant">@color/md_theme_dark_outlineVariant</item>
<!-- is this correct? -->
+1 -1
View File
@@ -30,7 +30,7 @@
<item name="android:textColor">@color/md_theme_light_onSurfaceVariant</item>
<item name="colorText">@color/md_theme_light_onSurfaceVariant</item>
<item name="android:scrollbarThumbVertical">@color/md_theme_light_onSurfaceVariant</item>
<item name="android:scrollbarThumbVertical">@color/md_theme_light_primary</item> <!-- md_theme_light_onSurfaceVariant -->
<item name="colorOutlineVariant">@color/md_theme_light_outlineVariant</item>
<item name="colorErrorText">@color/md_theme_light_error</item>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en"/>
<locale android:name="de"/>
</locale-config>