Füge Jahresauswahl hinzu

master
Niko Diamadis 4 years ago
parent e95e4aaf6f
commit 22ff78202a
Signed by: niko
GPG Key ID: BE53B0B17B1B142E

@ -2,26 +2,19 @@ package com.cyb3rko.techniklogger
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.input.getInputField
import com.afollestad.materialdialogs.input.input
import com.androidnetworking.AndroidNetworking import com.androidnetworking.AndroidNetworking
import com.androidnetworking.error.ANError import com.androidnetworking.error.ANError
import com.androidnetworking.interfaces.StringRequestListener import com.androidnetworking.interfaces.StringRequestListener
import com.cyb3rko.techniklogger.databinding.ActivityMainBinding import com.cyb3rko.techniklogger.databinding.ActivityMainBinding
import java.util.*
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null private var _binding: ActivityMainBinding? = null
@ -43,7 +36,9 @@ class MainActivity : AppCompatActivity() {
navController = findNavController(R.id.nav_host_fragment_activity_main) navController = findNavController(R.id.nav_host_fragment_activity_main)
// Passing each menu ID as a set of Ids because each // Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations. // menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_listing)) val appBarConfiguration = AppBarConfiguration(
setOf(R.id.navigation_years, R.id.navigation_listing)
)
setupActionBarWithNavController(navController, appBarConfiguration) setupActionBarWithNavController(navController, appBarConfiguration)
sharedPref = getSharedPreferences("Safe", 0) sharedPref = getSharedPreferences("Safe", 0)
@ -51,7 +46,7 @@ class MainActivity : AppCompatActivity() {
sharedPrefEditor.apply() sharedPrefEditor.apply()
if (sharedPref.getString("name", "") == "") { if (sharedPref.getString("name", "") == "") {
showNameDialog() showNameDialog(this, sharedPref, sharedPrefEditor)
} else { } else {
updateCheck() updateCheck()
} }
@ -64,30 +59,6 @@ class MainActivity : AppCompatActivity() {
) )
} }
private fun showNameDialog() {
val currentName = getSharedPreferences("Safe", 0).getString("name", "")
MaterialDialog(this)
.cancelable(false)
.title(0, "Bitte gib deinen Namen ein")
.show {
input(hint = "Dein Name", prefill = currentName, waitForPositiveButton = false) { dialog, inputName ->
try {
if (!inputName[0].isUpperCase()) {
dialog.getInputField().error = "Der Anfangsbuchstabe sollte groß sein"
}
} catch (ignored: IndexOutOfBoundsException) {
}
positiveButton(0, "Speichern") {
sharedPref.edit().putString("name", inputName.toString()).commit()
finish()
startActivity(Intent(applicationContext, MainActivity::class.java))
}
}
}
}
private fun updateCheck() { private fun updateCheck() {
AndroidNetworking.initialize(applicationContext) AndroidNetworking.initialize(applicationContext)
AndroidNetworking.get("https://git.aldiserver.de/api/v1/repos/niko/technik-logger-app/contents/app/build.gradle") AndroidNetworking.get("https://git.aldiserver.de/api/v1/repos/niko/technik-logger-app/contents/app/build.gradle")
@ -108,22 +79,4 @@ class MainActivity : AppCompatActivity() {
override fun onSupportNavigateUp(): Boolean { override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp() return navController.navigateUp() || super.onSupportNavigateUp()
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_rename -> showNameDialog()
R.id.action_about -> navController.navigate(R.id.navigation_about)
}
return super.onOptionsItemSelected(item)
}
} }

@ -0,0 +1,43 @@
package com.cyb3rko.techniklogger
import android.content.Intent
import android.content.SharedPreferences
import androidx.core.content.ContextCompat.startActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.input.getInputField
import com.afollestad.materialdialogs.input.input
internal const val CURRENT_YEAR = "current_year"
internal const val CURRENT_YEAR_NAME = "current_year_name"
internal const val COLUMN_JAHR = "jahr"
internal const val COLUMN_JAHR_NAME = "name"
internal const val COLUMN_TECHNIKER_NAME = "name"
internal const val SHARED_PREFERENCE = "Safe"
internal fun showNameDialog(
activity: MainActivity,
sharedPref: SharedPreferences,
sharedPrefEditor: SharedPreferences.Editor
) {
val currentName = sharedPref.getString(COLUMN_TECHNIKER_NAME, "")
MaterialDialog(activity)
.cancelable(false)
.title(0, "Bitte gib deinen Namen ein")
.show {
input(hint = "Dein Name", prefill = currentName, waitForPositiveButton = false) { dialog, inputName ->
try {
if (!inputName[0].isUpperCase()) {
dialog.getInputField().error = "Der Anfangsbuchstabe sollte groß sein"
}
} catch (ignored: IndexOutOfBoundsException) {
}
positiveButton(0, "Speichern") {
sharedPrefEditor.putString("name", inputName.toString()).commit()
activity.finish()
startActivity(activity, Intent(activity, MainActivity::class.java), null)
}
}
}
}

@ -5,24 +5,25 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.*
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.cyb3rko.techniklogger.R import com.cyb3rko.techniklogger.*
import com.cyb3rko.techniklogger.COLUMN_JAHR
import com.cyb3rko.techniklogger.CURRENT_YEAR
import com.cyb3rko.techniklogger.databinding.FragmentListingBinding import com.cyb3rko.techniklogger.databinding.FragmentListingBinding
import com.cyb3rko.techniklogger.recycler.ProjectEntryViewHolder import com.cyb3rko.techniklogger.recycler.ProjectEntryViewHolder
import com.cyb3rko.techniklogger.recycler.ProjectViewState import com.cyb3rko.techniklogger.recycler.ProjectViewState
import com.cyb3rko.techniklogger.showNameDialog
import com.cyb3rko.techniklogger.table.ExportBuilder import com.cyb3rko.techniklogger.table.ExportBuilder
import com.parse.ParseObject import com.parse.ParseObject
import com.parse.ParseQuery import com.parse.ParseQuery
import es.dmoral.toasty.Toasty import es.dmoral.toasty.Toasty
import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter
import me.ibrahimyilmaz.kiel.core.RecyclerViewHolder
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter
import me.ibrahimyilmaz.kiel.core.RecyclerViewHolder
class ListingFragment : Fragment() { class ListingFragment : Fragment() {
private var _binding: FragmentListingBinding? = null private var _binding: FragmentListingBinding? = null
@ -38,13 +39,16 @@ class ListingFragment : Fragment() {
private val binding get() = _binding!! private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
setHasOptionsMenu(true)
_binding = FragmentListingBinding.inflate(inflater, container, false) _binding = FragmentListingBinding.inflate(inflater, container, false)
val root = binding.root val root = binding.root
myContext = requireContext() myContext = requireContext()
sharedPref = myContext.getSharedPreferences("Safe", 0) sharedPref = myContext.getSharedPreferences("Safe", 0)
sharedPrefEditor = sharedPref.edit() sharedPrefEditor = sharedPref.edit()
sharedPrefEditor.apply() if (sharedPref.getString(CURRENT_YEAR, "") == "") {
findNavController().navigate(R.id.navigation_years)
}
binding.loadingAnimation.playAnimation() binding.loadingAnimation.playAnimation()
@ -139,6 +143,13 @@ class ListingFragment : Fragment() {
data.clear() data.clear()
val query = ParseQuery.getQuery<ParseObject>("Einsatz") val query = ParseQuery.getQuery<ParseObject>("Einsatz")
query.limit = 100000 query.limit = 100000
query.whereEqualTo(
COLUMN_JAHR,
ParseObject.createWithoutData(
"Jahr",
sharedPref.getString(CURRENT_YEAR, "")
)
)
query.findInBackground { objects, e -> query.findInBackground { objects, e ->
if (e == null) { if (e == null) {
@ -243,4 +254,21 @@ class ListingFragment : Fragment() {
override fun onAnimationRepeat(animation: Animator?) {} override fun onAnimationRepeat(animation: Animator?) {}
}) })
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_year -> findNavController().navigate(R.id.navigation_years)
R.id.action_rename -> showNameDialog(requireActivity() as MainActivity, sharedPref, sharedPrefEditor)
R.id.action_about -> findNavController().navigate(R.id.navigation_about)
}
return super.onOptionsItemSelected(item)
}
} }

@ -0,0 +1,117 @@
package com.cyb3rko.techniklogger.fragments
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.cyb3rko.techniklogger.*
import com.cyb3rko.techniklogger.COLUMN_JAHR_NAME
import com.cyb3rko.techniklogger.CURRENT_YEAR
import com.cyb3rko.techniklogger.CURRENT_YEAR_NAME
import com.cyb3rko.techniklogger.SHARED_PREFERENCE
import com.cyb3rko.techniklogger.databinding.FragmentYearsBinding
import com.cyb3rko.techniklogger.recycler.YearAdapter
import com.parse.ParseObject
import com.parse.ParseQuery
import es.dmoral.toasty.Toasty
class YearsFragment : Fragment() {
private var _binding: FragmentYearsBinding? = null
private lateinit var myContext: Context
private lateinit var yearAdapter: YearAdapter
private var data: MutableList<ParseObject> = mutableListOf()
private lateinit var sharedPref: SharedPreferences
private lateinit var sharedPrefEditor: SharedPreferences.Editor
// This property is only valid between onCreateView and onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentYearsBinding.inflate(inflater, container, false)
val root = binding.root
myContext = requireContext()
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedPref = myContext.getSharedPreferences(SHARED_PREFERENCE, Context.MODE_PRIVATE)
sharedPrefEditor = sharedPref.edit()
binding.loadingAnimation.playAnimation()
yearAdapter = YearAdapter { objectId, name ->
sharedPrefEditor.putString(CURRENT_YEAR, objectId)
sharedPrefEditor.putString(CURRENT_YEAR_NAME, name).commit()
findNavController().navigate(R.id.navigation_listing)
}
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(myContext)
adapter = yearAdapter
}
loadEntries()
binding.swipeRefreshLayout.apply {
setProgressBackgroundColorSchemeResource(R.color.refreshLayoutBackground)
setColorSchemeResources(R.color.refreshLayoutArrow)
setOnRefreshListener {
loadEntries()
}
}
binding.fab.setOnClickListener {
}
}
private fun loadEntries() {
val query = ParseQuery.getQuery<ParseObject>("Jahr")
query.limit = -1
query.cachePolicy = ParseQuery.CachePolicy.CACHE_THEN_NETWORK
query.orderByDescending(COLUMN_JAHR_NAME)
query.findInBackground { objects, e ->
if (e == null) {
data = objects
showAnimation(false)
binding.swipeRefreshLayout.isRefreshing = false
yearAdapter.submitList(data)
} else {
binding.swipeRefreshLayout.isRefreshing = false
if (data.isEmpty()) {
showAnimation(true, false)
}
Toasty.error(myContext, "Abruf fehlgeschlagen", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.JahrSuche", e.message.toString())
}
}
}
private fun showAnimation(show: Boolean, connected: Boolean = true) {
val viewVisibility = if (show) View.VISIBLE else View.INVISIBLE
val newSpeed = if (!connected) 1.2f else 1.5f
val animation = if (connected) "loading.json" else "no-connection.json"
binding.apply {
loadingAnimation.apply {
setAnimation(animation)
speed = newSpeed
visibility = viewVisibility
playAnimation()
}
}
}
}

@ -0,0 +1,48 @@
package com.cyb3rko.techniklogger.recycler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.cyb3rko.techniklogger.R
import com.parse.ParseObject
class YearAdapter(
val action: (objectId: String, year: String) -> Unit
) : ListAdapter<ParseObject, YearAdapter.ViewHolder>(YearDiffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_recycler_year, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val entry = getItem(position)
val name = entry.getString("name")!!
holder.nameView.text = name
holder.cardView.setOnClickListener {
action(entry.objectId, name)
}
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val cardView: CardView = view.findViewById(R.id.root)
val nameView: TextView = view.findViewById(R.id.name_text)
}
object YearDiffCallback : DiffUtil.ItemCallback<ParseObject>() {
override fun areItemsTheSame(oldItem: ParseObject, newItem: ParseObject): Boolean {
return oldItem.objectId == newItem.objectId
}
override fun areContentsTheSame(oldItem: ParseObject, newItem: ParseObject): Boolean {
return oldItem.getString("name") == newItem.getString("name")
}
}
}

@ -0,0 +1,159 @@
<?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"
android:orientation="vertical"
tools:context=".MainActivity">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/loading_animation"
android:layout_width="150dp"
android:layout_height="150dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/swipe_refresh_layout"
android:layout_marginTop="30dp"
app:lottie_fileName="loading.json"
app:lottie_loop="true"
app:lottie_speed="1.5"/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe_refresh_layout">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/recycler_animation" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<View
android:id="@+id/fab_bg_Layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/blurBackground"
android:visibility="gone" />
<LinearLayout
android:id="@+id/fab_layout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="4dp"
android:clipToPadding="false"
android:layout_marginEnd="16dp"
android:gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_gravity="bottom|end"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:text="Neuer Eintrag" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:tint="@null"
app:srcCompat="@drawable/_icon_add"
app:fabSize="mini" />
</LinearLayout>
<LinearLayout
android:id="@+id/fab_layout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="4dp"
android:clipToPadding="false"
android:layout_marginEnd="16dp"
android:gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_gravity="bottom|end"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:text="Liste exportieren" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:tint="@null"
app:srcCompat="@drawable/_icon_export"
app:fabSize="mini" />
</LinearLayout>
<LinearLayout
android:id="@+id/fab_layout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="4dp"
android:clipToPadding="false"
android:layout_marginEnd="16dp"
android:gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_gravity="bottom|end"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:text="Techniker verwalten" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:tint="@null"
app:srcCompat="@drawable/_icon_techniker"
app:fabSize="mini" />
</LinearLayout>
<LinearLayout
android:id="@+id/fab_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:clipToPadding="false"
android:padding="16dp"
android:layout_gravity="bottom|end"
tools:visibility="visible">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
app:tint="@null"
app:srcCompat="@drawable/_icon_dot_menu"
app:fabSize="normal" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:background="@color/cardBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/name_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:fontFamily="sans-serif-black"
android:layout_margin="25dp"
android:gravity="center_horizontal"
tools:text="1900/1901" />
</androidx.cardview.widget.CardView>

@ -2,6 +2,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context="com.cyb3rko.techniklogger.MainActivity"> tools:context="com.cyb3rko.techniklogger.MainActivity">
<item
android:id="@+id/action_year"
android:title="Schuljahr wechseln"
app:showAsAction="never" />
<item <item
android:id="@+id/action_rename" android:id="@+id/action_rename"
android:title="Namen ändern" android:title="Namen ändern"

@ -5,6 +5,12 @@
android:id="@+id/mobile_navigation" android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_listing"> app:startDestination="@+id/navigation_listing">
<fragment
android:id="@+id/navigation_years"
android:name="com.cyb3rko.techniklogger.fragments.YearsFragment"
android:label="Schuljahre"
tools:layout="@layout/fragment_years" />
<fragment <fragment
android:id="@+id/navigation_listing" android:id="@+id/navigation_listing"
android:name="com.cyb3rko.techniklogger.fragments.ListingFragment" android:name="com.cyb3rko.techniklogger.fragments.ListingFragment"

Loading…
Cancel
Save