From 3b239fc22d2e6823bf284ddeaf5ae9272fd00c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20D=C3=BCzg=C3=B6ren?= Date: Tue, 15 Oct 2019 08:29:53 +0200 Subject: [PATCH] Changed colour picker from a single palette dialog to recycler view to gain parity with iOS-version --- .../adapters/ColourPickerAdapter.kt | 58 +++++ ...olourAdapter.kt => CourseColourAdapter.kt} | 18 +- .../adapters/RingtoneAdapter.kt | 2 +- .../adapters/SubstitutionAdapter.kt | 2 +- .../substitutionplan/data/HelperFunctions.kt | 65 +++-- .../fragments/SettingsFragment.kt | 60 +++-- .../substitutionplan/models/Substitution.kt | 1 - app/src/main/res/drawable/circle.xml | 10 + app/src/main/res/drawable/circle_border.xml | 12 + app/src/main/res/layout/activity_login.xml | 140 ---------- app/src/main/res/layout/bg_colour_picker.xml | 241 ------------------ .../main/res/layout/colour_picker_item.xml | 46 ++++ ...item.xml => course_colour_picker_item.xml} | 3 +- app/src/main/res/layout/empty_dialog.xml | 38 --- app/src/main/res/layout/food_layout.xml | 2 +- app/src/main/res/layout/plan.xml | 1 - app/src/main/res/values-de/strings.xml | 27 ++ app/src/main/res/values-night/colors.xml | 1 + app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 28 ++ 20 files changed, 262 insertions(+), 494 deletions(-) create mode 100644 app/src/main/java/com/denizd/substitutionplan/adapters/ColourPickerAdapter.kt rename app/src/main/java/com/denizd/substitutionplan/adapters/{ColourAdapter.kt => CourseColourAdapter.kt} (74%) create mode 100644 app/src/main/res/drawable/circle.xml create mode 100644 app/src/main/res/drawable/circle_border.xml delete mode 100644 app/src/main/res/layout/activity_login.xml delete mode 100644 app/src/main/res/layout/bg_colour_picker.xml create mode 100644 app/src/main/res/layout/colour_picker_item.xml rename app/src/main/res/layout/{list_item.xml => course_colour_picker_item.xml} (93%) delete mode 100644 app/src/main/res/layout/empty_dialog.xml diff --git a/app/src/main/java/com/denizd/substitutionplan/adapters/ColourPickerAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/adapters/ColourPickerAdapter.kt new file mode 100644 index 0000000..4d0eff1 --- /dev/null +++ b/app/src/main/java/com/denizd/substitutionplan/adapters/ColourPickerAdapter.kt @@ -0,0 +1,58 @@ +package com.denizd.substitutionplan.adapters + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.denizd.substitutionplan.models.Colour +import com.denizd.substitutionplan.R +import com.google.android.material.card.MaterialCardView + +/** + * Adapter class used for displaying the colours available for tinting courses on the substitution + * plan. Used in SettingsFragment.kt + * + * @param colours a list of all available colours + * @param onClickListener a reference to an OnClickListener + */ +internal class ColourPickerAdapter(private var colours: List, private val onClickListener: OnColourClickListener) : RecyclerView.Adapter() { + + internal class ColourPickerViewHolder(view: View, private val clickListener: OnColourClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener { + val title: TextView = view.findViewById(R.id.item_text) + var image: ImageView = view.findViewById(R.id.item_image) + var colourNoLang = "" + init { view.setOnClickListener(this) } + + override fun onClick(v: View?) { clickListener.onColourClick(adapterPosition, colourNoLang) } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourPickerViewHolder { + val v = LayoutInflater.from(parent.context).inflate(R.layout.colour_picker_item, parent, false) + return ColourPickerViewHolder(v, onClickListener) + } + + override fun onBindViewHolder(holder: ColourPickerViewHolder, position: Int) { + val currentItem = colours[position] + + holder.title.text = currentItem.title + holder.colourNoLang = currentItem.titleNoLang + + val bg = ContextCompat.getDrawable(holder.image.context, R.drawable.circle) + bg?.setTint((ContextCompat.getColor(holder.image.context, if (currentItem.colour != 0) { + currentItem.colour + } else { + R.color.colorBackgroundLight + }))) + + holder.image.background = bg + } + + override fun getItemCount(): Int = colours.size + + internal interface OnColourClickListener { + fun onColourClick(position: Int, colourNoLang: String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/adapters/CourseColourAdapter.kt similarity index 74% rename from app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt rename to app/src/main/java/com/denizd/substitutionplan/adapters/CourseColourAdapter.kt index 3a00294..1ffd0ad 100644 --- a/app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt +++ b/app/src/main/java/com/denizd/substitutionplan/adapters/CourseColourAdapter.kt @@ -18,25 +18,25 @@ import com.google.android.material.card.MaterialCardView * @param colours a list of all courses and their associated colour * @param onClickListener a reference to an OnClickListener */ -internal class ColourAdapter(private var colours: List, private val onClickListener: OnColourClickListener) : RecyclerView.Adapter() { +internal class CourseColourAdapter(private var colours: List, private val onClickListener: OnCourseColourClickListener) : RecyclerView.Adapter() { - internal class ColourViewHolder(view: View, private val clickListener: OnColourClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener { + internal class CourseColourViewHolder(view: View, private val clickListener: OnCourseColourClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener { val title: TextView = view.findViewById(R.id.item_text) var image: ImageView = view.findViewById(R.id.item_image) var titleNoLang: String = "" val cardView: MaterialCardView = view.findViewById(R.id.cardView) init { view.setOnClickListener(this) } - override fun onClick(v: View?) { clickListener.onColourClick(adapterPosition, title.text.toString(), titleNoLang) } + override fun onClick(v: View?) { clickListener.onCourseClick(adapterPosition, title.text.toString(), titleNoLang) } } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourViewHolder { - val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) - return ColourViewHolder(v, onClickListener) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CourseColourViewHolder { + val v = LayoutInflater.from(parent.context).inflate(R.layout.course_colour_picker_item, parent, false) + return CourseColourViewHolder(v, onClickListener) } - override fun onBindViewHolder(holder: ColourViewHolder, position: Int) { + override fun onBindViewHolder(holder: CourseColourViewHolder, position: Int) { val currentItem = colours[position] holder.title.text = currentItem.title @@ -60,7 +60,7 @@ internal class ColourAdapter(private var colours: List, private val onCl override fun getItemCount(): Int = colours.size - internal interface OnColourClickListener { - fun onColourClick(position: Int, title: String, titleNoLang: String) + internal interface OnCourseColourClickListener { + fun onCourseClick(position: Int, title: String, titleNoLang: String) } } \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/adapters/RingtoneAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/adapters/RingtoneAdapter.kt index c87a1d5..4b916a4 100644 --- a/app/src/main/java/com/denizd/substitutionplan/adapters/RingtoneAdapter.kt +++ b/app/src/main/java/com/denizd/substitutionplan/adapters/RingtoneAdapter.kt @@ -32,7 +32,7 @@ internal class RingtoneAdapter(private val ringtones: List, private va } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RingtoneViewHolder { - val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) + val v = LayoutInflater.from(parent.context).inflate(R.layout.course_colour_picker_item, parent, false) return RingtoneViewHolder(v, onClickListener) } diff --git a/app/src/main/java/com/denizd/substitutionplan/adapters/SubstitutionAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/adapters/SubstitutionAdapter.kt index 509d06e..f2413c3 100644 --- a/app/src/main/java/com/denizd/substitutionplan/adapters/SubstitutionAdapter.kt +++ b/app/src/main/java/com/denizd/substitutionplan/adapters/SubstitutionAdapter.kt @@ -119,7 +119,7 @@ internal class SubstitutionAdapter(private var substitutions: List } else { "" } - colour = HelperFunctions.getColourForString(colourPrefsInt) + colour = HelperFunctions.getColourForString(colourPrefsInt, holder.context) cardBackgroundColour = if (colour != 0) { colour } else { diff --git a/app/src/main/java/com/denizd/substitutionplan/data/HelperFunctions.kt b/app/src/main/java/com/denizd/substitutionplan/data/HelperFunctions.kt index 813e093..f3675da 100644 --- a/app/src/main/java/com/denizd/substitutionplan/data/HelperFunctions.kt +++ b/app/src/main/java/com/denizd/substitutionplan/data/HelperFunctions.kt @@ -20,6 +20,7 @@ import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat.checkSelfPermission import androidx.fragment.app.FragmentActivity import com.denizd.substitutionplan.R +import com.denizd.substitutionplan.models.Colour import com.denizd.substitutionplan.models.Substitution import java.util.* import java.io.File @@ -43,8 +44,8 @@ internal object HelperFunctions { "Physics", "CompSci", "PhysEd", "GLL", "WAT", "Forder", "WP") val colourNames = arrayOf("default", "red", "orange", "yellow", "green", "teal", "cyan", "blue", "purple", "pink", - "brown", "grey", "pureWhite", "salmon", "tangerine", "banana", "flora", "spindrift", "sky", "orchid", - "lavender", "carnation", "brown2", "pureBlack") + "brown", "grey", "salmon", "tangerine", "banana", "flora", "spindrift", "sky", "orchid", + "lavender", "carnation", "brown2", "pureWhite", "pureBlack") /** * A lower-cased list of all phrases used to describe that a course has been cancelled. Expand @@ -83,33 +84,41 @@ internal object HelperFunctions { const val notificationChannelId = "general" - fun getColourForString(name: String): Int { - return when (name) { - "red" -> R.color.bgRed - "orange" -> R.color.bgOrange - "yellow" -> R.color.bgYellow - "green" -> R.color.bgGreen - "teal" -> R.color.bgTeal - "cyan" -> R.color.bgCyan - "blue" -> R.color.bgBlue - "purple" -> R.color.bgPurple - "pink" -> R.color.bgPink - "brown" -> R.color.bgBrown - "grey" -> R.color.bgGrey - "pureWhite" -> R.color.bgPureWhite - "salmon" -> R.color.bgSalmon - "tangerine" -> R.color.bgTangerine - "banana" -> R.color.bgBanana - "flora" -> R.color.bgFlora - "spindrift" -> R.color.bgSpindrift - "sky" -> R.color.bgSky - "orchid" -> R.color.bgOrchid - "lavender" -> R.color.bgLavender - "carnation" -> R.color.bgCarnation - "brown2" -> R.color.bgBrown2 - "pureBlack" -> R.color.bgPureBlack - else -> R.color.colorBackgroundLight + fun getColourArray(c: Context): Array { + val titles = c.resources.getStringArray(R.array.colour_names) + return arrayOf( + Colour(titles[0], "default", 0, 0), + Colour(titles[1], "red", 0, R.color.bgRed), + Colour(titles[2], "orange", 0, R.color.bgOrange), + Colour(titles[3], "yellow", 0, R.color.bgYellow), + Colour(titles[4], "green", 0, R.color.bgGreen), + Colour(titles[5], "teal", 0, R.color.bgTeal), + Colour(titles[6], "cyan", 0, R.color.bgCyan), + Colour(titles[7], "blue", 0, R.color.bgBlue), + Colour(titles[8], "purple", 0, R.color.bgPurple), + Colour(titles[9], "pink", 0, R.color.bgPink), + Colour(titles[10], "brown", 0, R.color.bgBrown), + Colour(titles[11], "grey", 0, R.color.bgGrey), + Colour(titles[12], "salmon", 0, R.color.bgSalmon), + Colour(titles[13], "tangerine", 0, R.color.bgTangerine), + Colour(titles[14], "banana", 0, R.color.bgBanana), + Colour(titles[15], "flora", 0, R.color.bgFlora), + Colour(titles[16], "spindrift", 0, R.color.bgSpindrift), + Colour(titles[17], "sky", 0, R.color.bgSky), + Colour(titles[18], "orchid", 0, R.color.bgOrchid), + Colour(titles[19], "lavender", 0, R.color.bgLavender), + Colour(titles[20], "carnation", 0, R.color.bgCarnation), + Colour(titles[21], "brown2", 0, R.color.bgBrown2), + Colour(titles[22], "pureWhite", 0, R.color.bgPureWhite), + Colour(titles[23], "pureBlack", 0, R.color.bgPureBlack) + ) + } + + fun getColourForString(name: String, context: Context): Int { + for (colour in getColourArray(context)) { + if (colour.titleNoLang == name) return colour.colour } + return 0 } fun getIconForCourse(course: String): Int { diff --git a/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt index 9239b03..5d604d5 100644 --- a/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt @@ -27,7 +27,8 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.denizd.substitutionplan.* -import com.denizd.substitutionplan.adapters.ColourAdapter +import com.denizd.substitutionplan.adapters.ColourPickerAdapter +import com.denizd.substitutionplan.adapters.CourseColourAdapter import com.denizd.substitutionplan.adapters.RingtoneAdapter import com.denizd.substitutionplan.data.DataFetcher import com.denizd.substitutionplan.data.HelperFunctions @@ -41,8 +42,8 @@ import com.google.firebase.messaging.FirebaseMessaging import kotlin.collections.ArrayList internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongClickListener, - CompoundButton.OnCheckedChangeListener, ColourAdapter.OnColourClickListener, - RingtoneAdapter.OnRingtoneClickListener { + CompoundButton.OnCheckedChangeListener, CourseColourAdapter.OnCourseColourClickListener, + RingtoneAdapter.OnRingtoneClickListener, ColourPickerAdapter.OnColourClickListener { private lateinit var mContext: Context private lateinit var prefs: SharedPreferences @@ -50,6 +51,7 @@ internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongC private var window: Window? = null private var longPressed = false private var versionCount = 0 + private var currentCourseSelectedInColourPicker = "" private val ringtones: List by lazy { getRingtones() @@ -57,6 +59,7 @@ internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongC private lateinit var colourRecycler: RecyclerView private lateinit var ringtoneDialog: AlertDialog + private lateinit var colourPickerDialog: AlertDialog private lateinit var binding: ContentSettingsBinding private lateinit var textCustomiseColoursTitle: TextView @@ -311,36 +314,31 @@ internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongC } // Functions for handling touch events for recycler view elements - override fun onColourClick(position: Int, title: String, titleNoLang: String) { + override fun onCourseClick(position: Int, title: String, titleNoLang: String) { + currentCourseSelectedInColourPicker = titleNoLang + val colourPickerBuilder = AlertDialog.Builder(mContext) - val pickerDialogView = View.inflate(mContext, R.layout.empty_dialog, null) - val pickerTitleText = pickerDialogView.findViewById(R.id.empty_textviewtitle) - val pickerLayout = pickerDialogView.findViewById(R.id.empty_linearlayout) - pickerTitleText.text = title - - val picker = View.inflate(mContext, R.layout.bg_colour_picker, null) - pickerLayout.addView(picker) - colourPickerBuilder.setView(pickerDialogView) - val colourPickerDialog: AlertDialog = colourPickerBuilder.create() - - val buttons = intArrayOf(R.id.def, R.id.red, R.id.orange, R.id.yellow, R.id.green, - R.id.teal, R.id.cyan, R.id.blue, R.id.purple, R.id.pink, R.id.brown, R.id.grey, - R.id.pureWhite, R.id.salmon, R.id.tangerine, R.id.banana, R.id.flora, R.id.spindrift, - R.id.sky, R.id.orchid, R.id.lavender, R.id.carnation, R.id.brown2, R.id.pureBlack) - val colours = HelperFunctions.colourNames - - for (i2 in buttons.indices) { - picker.findViewById(buttons[i2]).setOnClickListener { - prefs.edit().putString("card$titleNoLang", colours[i2]).apply() - val recyclerViewState = colourRecycler.layoutManager?.onSaveInstanceState() - colourRecycler.adapter = ColourAdapter(getColourList(), this) - colourRecycler.layoutManager?.onRestoreInstanceState(recyclerViewState) - colourPickerDialog.dismiss() - } + val dialogView = View.inflate(mContext, R.layout.recycler_dialog, null) + val titleText = dialogView.findViewById(R.id.empty_textviewtitle) + titleText.text = title + val colourRecycler = dialogView.findViewById(R.id.recyclerView) + colourRecycler.apply { + hasFixedSize() + layoutManager = GridLayoutManager(mContext, 1) + adapter = ColourPickerAdapter(HelperFunctions.getColourArray(mContext).toList(), this@SettingsFragment) } + colourPickerDialog = colourPickerBuilder.setView(dialogView).create() colourPickerDialog.show() } + override fun onColourClick(position: Int, colourNoLang: String) { + prefs.edit().putString("card$currentCourseSelectedInColourPicker", colourNoLang).apply() + val recyclerViewState = colourRecycler.layoutManager?.onSaveInstanceState() + colourRecycler.adapter = CourseColourAdapter(getColourList(), this) + colourRecycler.layoutManager?.onRestoreInstanceState(recyclerViewState) + colourPickerDialog.dismiss() + } + override fun onRingtoneClick(position: Int, name: String, uri: String) { prefs.edit().apply { putString("ringtoneName", name) @@ -365,11 +363,11 @@ internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongC val dialogView = View.inflate(mContext, R.layout.recycler_dialog, null) val titleText = dialogView.findViewById(R.id.empty_textviewtitle) titleText.text = getString(R.string.customise_colours_title) - val colourRecycler = dialogView.findViewById(R.id.recyclerView) + colourRecycler = dialogView.findViewById(R.id.recyclerView) colourRecycler.apply { hasFixedSize() layoutManager = GridLayoutManager(mContext, 1) - adapter = ColourAdapter(getColourList(), this@SettingsFragment) + adapter = CourseColourAdapter(getColourList(), this@SettingsFragment) } colourCustomisationDialogBuilder.setView(dialogView) val colourCustomisationDialog = colourCustomisationDialogBuilder.create() @@ -550,7 +548,7 @@ internal class SettingsFragment : Fragment(), View.OnClickListener, View.OnLongC courses[i], coursesNoLang[i], coursesIcons[i], - HelperFunctions.getColourForString(prefs.getString("card${coursesNoLang[i]}", "") ?: "") + HelperFunctions.getColourForString(prefs.getString("card${coursesNoLang[i]}", "") ?: "", mContext) ) ) } diff --git a/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt b/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt index 305c875..1cda345 100644 --- a/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt +++ b/app/src/main/java/com/denizd/substitutionplan/models/Substitution.kt @@ -17,7 +17,6 @@ internal data class Substitution( val date_priority: Int, val website_priority: Int ) { - @PrimaryKey(autoGenerate = true) var id: Int = 0 } \ No newline at end of file diff --git a/app/src/main/res/drawable/circle.xml b/app/src/main/res/drawable/circle.xml new file mode 100644 index 0000000..69c1547 --- /dev/null +++ b/app/src/main/res/drawable/circle.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/circle_border.xml b/app/src/main/res/drawable/circle_border.xml new file mode 100644 index 0000000..15f751d --- /dev/null +++ b/app/src/main/res/drawable/circle_border.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml deleted file mode 100644 index 0910eb9..0000000 --- a/app/src/main/res/layout/activity_login.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - - - - - - - - - - - - -