From 0aac6459f37593d243fd6c3db0d364e75a9b845d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Mon, 2 Sep 2019 12:56:13 +0200 Subject: [PATCH] Fix elevation overlay on pre-lolipop (#475) --- .../modules/attendance/AttendanceFragment.kt | 25 ++++++----- .../summary/AttendanceSummaryFragment.kt | 30 ++++++------- .../summary/AttendanceSummaryPresenter.kt | 2 +- .../wulkanowy/ui/modules/exam/ExamFragment.kt | 22 ++++----- .../ui/modules/grade/GradeFragment.kt | 45 ++++++++++--------- .../statistics/GradeStatisticsFragment.kt | 24 +++++----- .../statistics/GradeStatisticsPresenter.kt | 6 +-- .../ui/modules/homework/HomeworkFragment.kt | 20 ++++----- .../ui/modules/message/MessageFragment.kt | 19 ++++---- .../ui/modules/timetable/TimetableFragment.kt | 27 ++++++----- .../completed/CompletedLessonsFragment.kt | 26 +++++------ .../FittedScrollableTabLayout.kt} | 5 +-- .../ui/widgets/MaterialLinearLayout.kt | 12 ++++- .../wulkanowy/ui/widgets/MaterialTabLayout.kt | 25 +++++++++++ .../wulkanowy/utils/SpinnerExtension.kt | 5 ++- .../main/res/layout/fragment_attendance.xml | 1 - .../layout/fragment_attendance_summary.xml | 1 - app/src/main/res/layout/fragment_exam.xml | 1 - app/src/main/res/layout/fragment_grade.xml | 3 +- .../res/layout/fragment_grade_statistics.xml | 1 - app/src/main/res/layout/fragment_homework.xml | 1 - app/src/main/res/layout/fragment_message.xml | 3 +- .../main/res/layout/fragment_timetable.xml | 1 - .../layout/fragment_timetable_completed.xml | 1 - 24 files changed, 167 insertions(+), 139 deletions(-) rename app/src/main/java/io/github/wulkanowy/ui/{modules/grade/CustomTabLayout.kt => widgets/FittedScrollableTabLayout.kt} (88%) create mode 100644 app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt index f61753c9..fb6309f7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt @@ -17,11 +17,13 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_attendance.* import javax.inject.Inject -class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, MainView.TitledView { +class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, + MainView.TitledView { @Inject lateinit var presenter: AttendancePresenter @@ -35,14 +37,11 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie fun newInstance() = AttendanceFragment() } - override val titleStringId: Int - get() = R.string.attendance_title + override val titleStringId get() = R.string.attendance_title - override val isViewEmpty: Boolean - get() = attendanceAdapter.isEmpty + override val isViewEmpty get() = attendanceAdapter.isEmpty - override val currentStackSize: Int? - get() = (activity as? MainActivity)?.currentStackSize + override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -60,19 +59,21 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie } override fun initView() { - attendanceAdapter.setOnItemClickListener { presenter.onAttendanceItemSelected(it) } + attendanceAdapter.setOnItemClickListener(presenter::onAttendanceItemSelected) - attendanceRecycler.run { + with(attendanceRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) adapter = attendanceAdapter addItemDecoration(FlexibleItemDecoration(context) .withDefaultDivider() - .withDrawDividerOnLastItem(false) - ) + .withDrawDividerOnLastItem(false)) } - attendanceSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + + attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh) attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() } attendanceNextButton.setOnClickListener { presenter.onNextDay() } + + attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt index 1845bdda..4109bbea 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt @@ -15,6 +15,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.R import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemSelectedListener import kotlinx.android.synthetic.main.fragment_attendance_summary.* import javax.inject.Inject @@ -35,11 +36,9 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie fun newInstance() = AttendanceSummaryFragment() } - override val titleStringId: Int - get() = R.string.attendance_title + override val titleStringId get() = R.string.attendance_title - override val isViewEmpty - get() = attendanceSummaryAdapter.isEmpty + override val isViewEmpty get() = attendanceSummaryAdapter.isEmpty override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_attendance_summary, container, false) @@ -52,25 +51,26 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie } override fun initView() { - attendanceSummaryRecycler.run { + with(attendanceSummaryRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) adapter = attendanceSummaryAdapter } - attendanceSummarySwipe.setOnRefreshListener { presenter.onSwipeRefresh() } - context?.let { - subjectsAdapter = ArrayAdapter(it, android.R.layout.simple_spinner_item, ArrayList()) - subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject) - } + attendanceSummarySwipe.setOnRefreshListener(presenter::onSwipeRefresh) - attendanceSummarySubjects.run { + subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf()) + subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject) + + with(attendanceSummarySubjects) { adapter = subjectsAdapter - setOnItemSelectedListener { presenter.onSubjectSelected((it as TextView).text.toString()) } + setOnItemSelectedListener { presenter.onSubjectSelected(it?.text?.toString()) } } + + attendanceSummarySubjectsContainer.setElevationCompat(requireContext().dpToPx(1f)) } override fun updateSubjects(data: ArrayList) { - subjectsAdapter.run { + with(subjectsAdapter) { clear() addAll(data) notifyDataSetChanged() @@ -78,9 +78,9 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie } override fun updateDataSet(data: List, header: AttendanceSummaryScrollableHeader) { - attendanceSummaryAdapter.apply { + with(attendanceSummaryAdapter) { updateDataSet(data, true) - removeAllScrollableHeaders() + removeAllScrollableFooters() addScrollableHeader(header) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt index dc6fe5b3..40339299 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt @@ -46,7 +46,7 @@ class AttendanceSummaryPresenter @Inject constructor( loadData(currentSubjectId, true) } - fun onSubjectSelected(name: String) { + fun onSubjectSelected(name: String?) { Timber.i("Select attendance summary subject $name") view?.run { showContent(false) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt index 47f6d587..c762fa15 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt @@ -16,6 +16,7 @@ import io.github.wulkanowy.data.db.entities.Exam import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_exam.* import javax.inject.Inject @@ -34,11 +35,9 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView. fun newInstance() = ExamFragment() } - override val titleStringId: Int - get() = R.string.exam_title + override val titleStringId get() = R.string.exam_title - override val isViewEmpty: Boolean - get() = examAdapter.isEmpty + override val isViewEmpty get() = examAdapter.isEmpty override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_exam, container, false) @@ -51,20 +50,21 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView. } override fun initView() { - examAdapter.run { - setOnItemClickListener { presenter.onExamItemSelected(it) } - } - examRecycler.run { + examAdapter.setOnItemClickListener(presenter::onExamItemSelected) + + with(examRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) adapter = examAdapter addItemDecoration(FlexibleItemDecoration(context) .withDefaultDivider(R.layout.item_exam) - .withDrawDividerOnLastItem(false) - ) + .withDrawDividerOnLastItem(false)) } - examSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + + examSwipe.setOnRefreshListener(presenter::onSwipeRefresh) examPreviousButton.setOnClickListener { presenter.onPreviousWeek() } examNextButton.setOnClickListener { presenter.onNextWeek() } + + examNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } override fun hideRefresh() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt index b37fda74..68ae57ec 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt @@ -17,6 +17,7 @@ import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnSelectPageListener import kotlinx.android.synthetic.main.fragment_grade.* import javax.inject.Inject @@ -37,11 +38,9 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie fun newInstance() = GradeFragment() } - override val titleStringId: Int - get() = R.string.grade_title + override val titleStringId get() = R.string.grade_title - override val currentPageIndex: Int - get() = gradeViewPager.currentItem + override val currentPageIndex get() = gradeViewPager.currentItem override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -64,7 +63,7 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie } override fun initView() { - pagerAdapter.apply { + with(pagerAdapter) { containerId = gradeViewPager.id addFragmentsWithTitle(mapOf( GradeDetailsFragment.newInstance() to getString(R.string.all_details), @@ -73,14 +72,18 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie )) } - gradeViewPager.run { + with(gradeViewPager) { adapter = pagerAdapter offscreenPageLimit = 3 - setOnSelectPageListener { presenter.onPageSelected(it) } + setOnSelectPageListener(presenter::onPageSelected) } - gradeTabLayout.setupWithViewPager(gradeViewPager) - gradeSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + with(gradeTabLayout) { + setupWithViewPager(gradeViewPager) + setElevationCompat(context.dpToPx(4f)) + } + + gradeSwipe.setOnRefreshListener(presenter::onSwipeRefresh) } override fun onOptionsItemSelected(item: MenuItem): Boolean { @@ -118,19 +121,19 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie } override fun showSemesterDialog(selectedIndex: Int) { - arrayOf(getString(R.string.grade_semester, 1), - getString(R.string.grade_semester, 2)).also { array -> - context?.let { - AlertDialog.Builder(it) - .setSingleChoiceItems(array, selectedIndex) { dialog, which -> - presenter.onSemesterSelected(which) - dialog.dismiss() - } - .setTitle(R.string.grade_switch_semester) - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .show() + val choices = arrayOf( + getString(R.string.grade_semester, 1), + getString(R.string.grade_semester, 2) + ) + + AlertDialog.Builder(requireContext()) + .setSingleChoiceItems(choices, selectedIndex) { dialog, which -> + presenter.onSemesterSelected(which) + dialog.dismiss() } - } + .setTitle(R.string.grade_switch_semester) + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .show() } fun onChildRefresh() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt index a1257f57..4b6c1675 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt @@ -19,6 +19,7 @@ import io.github.wulkanowy.data.db.entities.GradeStatistics import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment import io.github.wulkanowy.ui.modules.grade.GradeView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.setOnItemSelectedListener import kotlinx.android.synthetic.main.fragment_grade_statistics.* @@ -37,8 +38,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G fun newInstance() = GradeStatisticsFragment() } - override val isViewEmpty - get() = gradeStatisticsChart.isEmpty + override val isViewEmpty get() = gradeStatisticsChart.isEmpty private lateinit var gradeColors: List> @@ -75,7 +75,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G } override fun initView() { - gradeStatisticsChart.run { + with(gradeStatisticsChart) { description.isEnabled = false setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground)) setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary)) @@ -84,21 +84,21 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G legend.textColor = context.getThemeAttrColor(android.R.attr.textColorPrimary) } - context?.let { - subjectsAdapter = ArrayAdapter(it, android.R.layout.simple_spinner_item, ArrayList()) - subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject) - } + subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf()) + subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject) - gradeStatisticsSubjects.run { + with(gradeStatisticsSubjects) { adapter = subjectsAdapter - setOnItemSelectedListener { presenter.onSubjectSelected((it as TextView).text.toString()) } + setOnItemSelectedListener { presenter.onSubjectSelected(it?.text?.toString()) } } - gradeStatisticsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + gradeStatisticsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) + + gradeStatisticsSubjectsContainer.setElevationCompat(requireContext().dpToPx(1f)) } override fun updateSubjects(data: ArrayList) { - subjectsAdapter.run { + with(subjectsAdapter) { clear() addAll(data) notifyDataSetChanged() @@ -202,7 +202,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putBoolean(GradeStatisticsFragment.SAVED_CHART_TYPE, presenter.currentIsSemester) + outState.putBoolean(SAVED_CHART_TYPE, presenter.currentIsSemester) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt index 55ea611f..0259557a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt @@ -62,7 +62,7 @@ class GradeStatisticsPresenter @Inject constructor( view?.notifyParentRefresh() } - fun onSubjectSelected(name: String) { + fun onSubjectSelected(name: String?) { Timber.i("Select grade stats subject $name") view?.run { showContent(false) @@ -71,8 +71,8 @@ class GradeStatisticsPresenter @Inject constructor( showEmpty(false) clearView() } - (subjects.singleOrNull { it.name == name }?.name).let { - if (it != currentSubjectName) loadData(currentSemesterId, name, currentIsSemester) + (subjects.singleOrNull { it.name == name }?.name)?.let { + if (it != currentSubjectName) loadData(currentSemesterId, it, currentIsSemester) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt index 01fdc909..8195dd20 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkFragment.kt @@ -13,6 +13,7 @@ import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_homework.* import javax.inject.Inject @@ -31,8 +32,7 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView { fun newInstance() = HomeworkFragment() } - override val titleStringId: Int - get() = R.string.homework_title + override val titleStringId get() = R.string.homework_title override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_homework, container, false) @@ -45,21 +45,21 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView { } override fun initView() { - homeworkAdapter.run { - setOnItemClickListener { presenter.onHomeworkItemSelected(it) } - } + homeworkAdapter.setOnItemClickListener(presenter::onHomeworkItemSelected) - homeworkRecycler.run { + with(homeworkRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) adapter = homeworkAdapter addItemDecoration(FlexibleItemDecoration(context) .withDefaultDivider() - .withDrawDividerOnLastItem(false) - ) + .withDrawDividerOnLastItem(false)) } - homeworkSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + + homeworkSwipe.setOnRefreshListener(presenter::onSwipeRefresh) homeworkPreviousButton.setOnClickListener { presenter.onPreviousDay() } homeworkNextButton.setOnClickListener { presenter.onNextDay() } + + homeworkNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } override fun updateData(data: List) { @@ -110,7 +110,7 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView { override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putLong(HomeworkFragment.SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) + outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt index 7bd35f2d..7a3e135d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt @@ -16,6 +16,7 @@ import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnSelectPageListener import kotlinx.android.synthetic.main.fragment_message.* import javax.inject.Inject @@ -32,11 +33,9 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView { fun newInstance() = MessageFragment() } - override val titleStringId: Int - get() = R.string.message_title + override val titleStringId get() = R.string.message_title - override val currentPageIndex: Int - get() = messageViewPager.currentItem + override val currentPageIndex get() = messageViewPager.currentItem override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_message, container, false) @@ -48,7 +47,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView { } override fun initView() { - pagerAdapter.apply { + with(pagerAdapter) { containerId = messageViewPager.id addFragmentsWithTitle(mapOf( MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox), @@ -57,12 +56,16 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView { )) } - messageViewPager.run { + with(messageViewPager) { adapter = pagerAdapter offscreenPageLimit = 2 - setOnSelectPageListener { presenter.onPageSelected(it) } + setOnSelectPageListener(presenter::onPageSelected) + } + + with(messageTabLayout) { + setupWithViewPager(messageViewPager) + setElevationCompat(context.dpToPx(4f)) } - messageTabLayout.setupWithViewPager(messageViewPager) openSendMessageButton.setOnClickListener { presenter.onSendMessageButtonClicked() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt index e60be74c..a580a417 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt @@ -17,11 +17,13 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_timetable.* import javax.inject.Inject -class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, MainView.TitledView { +class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, + MainView.TitledView { @Inject lateinit var presenter: TimetablePresenter @@ -35,17 +37,13 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, fun newInstance() = TimetableFragment() } - override val titleStringId: Int - get() = R.string.timetable_title + override val titleStringId get() = R.string.timetable_title - override val roomString: String - get() = getString(R.string.timetable_room) + override val roomString get() = getString(R.string.timetable_room) - override val isViewEmpty: Boolean - get() = timetableAdapter.isEmpty + override val isViewEmpty get() = timetableAdapter.isEmpty - override val currentStackSize: Int? - get() = (activity as? MainActivity)?.currentStackSize + override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -63,11 +61,9 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, } override fun initView() { - timetableAdapter.run { - setOnItemClickListener { presenter.onTimetableItemSelected(it) } - } + timetableAdapter.setOnItemClickListener(presenter::onTimetableItemSelected) - timetableRecycler.run { + with(timetableRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) adapter = timetableAdapter addItemDecoration(FlexibleItemDecoration(context) @@ -75,9 +71,12 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, .withDrawDividerOnLastItem(false) ) } - timetableSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + + timetableSwipe.setOnRefreshListener(presenter::onSwipeRefresh) timetablePreviousButton.setOnClickListener { presenter.onPreviousDay() } timetableNextButton.setOnClickListener { presenter.onNextDay() } + + timetableNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt index b1db1bb8..c7b5c6ca 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt @@ -12,6 +12,7 @@ import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.getCompatDrawable import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_timetable_completed.* @@ -31,11 +32,9 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView. fun newInstance() = CompletedLessonsFragment() } - override val titleStringId: Int - get() = R.string.completed_lessons_title + override val titleStringId get() = R.string.completed_lessons_title - override val isViewEmpty - get() = completedLessonsAdapter.isEmpty + override val isViewEmpty get() = completedLessonsAdapter.isEmpty override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_timetable_completed, container, false) @@ -48,17 +47,18 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView. } override fun initView() { - completedLessonsAdapter.run { - setOnItemClickListener { presenter.onCompletedLessonsItemSelected(it) } - } + completedLessonsAdapter.setOnItemClickListener(presenter::onCompletedLessonsItemSelected) - completedLessonsRecycler.run { + with(completedLessonsRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) adapter = completedLessonsAdapter } - completedLessonsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + + completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) completedLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() } completedLessonsNextButton.setOnClickListener { presenter.onNextDay() } + + completedLessonsNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } override fun updateData(data: List) { @@ -82,10 +82,8 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView. } override fun showFeatureDisabled() { - context?.let { - completedLessonsInfo.text = getString(R.string.error_feature_disabled) - completedLessonsInfoImage.setImageDrawable(it.getCompatDrawable(R.drawable.ic_all_close_circle)) - } + completedLessonsInfo.text = getString(R.string.error_feature_disabled) + completedLessonsInfoImage.setImageDrawable(requireContext().getCompatDrawable(R.drawable.ic_all_close_circle)) } override fun showProgress(show: Boolean) { @@ -114,7 +112,7 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView. override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putLong(CompletedLessonsFragment.SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) + outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/CustomTabLayout.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt similarity index 88% rename from app/src/main/java/io/github/wulkanowy/ui/modules/grade/CustomTabLayout.kt rename to app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt index e6f01497..0f121dc5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/CustomTabLayout.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt @@ -1,14 +1,13 @@ -package io.github.wulkanowy.ui.modules.grade +package io.github.wulkanowy.ui.widgets import android.content.Context import android.util.AttributeSet import android.view.ViewGroup -import com.google.android.material.tabs.TabLayout /** * @see Tabs don't fit to screen with tabmode=scrollable, Even with a Custom Tab Layout */ -class CustomTabLayout : TabLayout { +class FittedScrollableTabLayout : MaterialTabLayout { constructor(context: Context) : super(context) diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt index 7afd6e78..cad26f2e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt @@ -1,11 +1,12 @@ package io.github.wulkanowy.ui.widgets import android.content.Context +import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION_CODES.LOLLIPOP import android.util.AttributeSet import android.widget.LinearLayout -import androidx.annotation.RequiresApi import androidx.core.view.ViewCompat +import com.google.android.material.elevation.ElevationOverlayProvider import com.google.android.material.shape.MaterialShapeDrawable class MaterialLinearLayout : LinearLayout { @@ -21,11 +22,18 @@ class MaterialLinearLayout : LinearLayout { ViewCompat.setBackground(this, drawable) } - @RequiresApi(LOLLIPOP) override fun setElevation(elevation: Float) { super.setElevation(elevation) if (background is MaterialShapeDrawable) { (background as MaterialShapeDrawable).elevation = elevation } } + + fun setElevationCompat(elevation: Float) { + if (SDK_INT >= LOLLIPOP) { + setElevation(elevation) + } else { + setBackgroundColor(ElevationOverlayProvider(context).getSurfaceColorWithOverlayIfNeeded(elevation)) + } + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt new file mode 100644 index 00000000..3bcaae7d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.ui.widgets + +import android.content.Context +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP +import android.util.AttributeSet +import com.google.android.material.elevation.ElevationOverlayProvider +import com.google.android.material.tabs.TabLayout + +open class MaterialTabLayout : TabLayout { + + constructor(context: Context) : super(context) + + constructor(context: Context, attr: AttributeSet) : super(context, attr) + + constructor(context: Context, attr: AttributeSet, defStyleAttr: Int) : super(context, attr, defStyleAttr) + + fun setElevationCompat(elevation: Float) { + if (SDK_INT >= LOLLIPOP) { + setElevation(elevation) + } else { + setBackgroundColor(ElevationOverlayProvider(context).getSurfaceColorWithOverlayIfNeeded(elevation)) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/SpinnerExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/SpinnerExtension.kt index d9e34e87..1f721690 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/SpinnerExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/SpinnerExtension.kt @@ -7,14 +7,15 @@ import android.widget.Spinner /** * @see How to keep onItemSelected from firing off on a newly instantiated Spinner? */ -inline fun Spinner.setOnItemSelectedListener(crossinline listener: (view: View?) -> Unit) { +@Suppress("UNCHECKED_CAST") +inline fun Spinner.setOnItemSelectedListener(crossinline listener: (view: T?) -> Unit) { onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?) {} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?) {} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - listener(view) + listener(view as T?) } } } diff --git a/app/src/main/res/layout/fragment_attendance.xml b/app/src/main/res/layout/fragment_attendance.xml index 1f2a9371..033a6772 100644 --- a/app/src/main/res/layout/fragment_attendance.xml +++ b/app/src/main/res/layout/fragment_attendance.xml @@ -60,7 +60,6 @@ android:layout_width="match_parent" android:layout_height="50dp" android:layout_gravity="bottom" - android:elevation="8dp" android:orientation="horizontal" tools:ignore="UnusedAttribute"> diff --git a/app/src/main/res/layout/fragment_attendance_summary.xml b/app/src/main/res/layout/fragment_attendance_summary.xml index 8b7fe6cf..31be9900 100644 --- a/app/src/main/res/layout/fragment_attendance_summary.xml +++ b/app/src/main/res/layout/fragment_attendance_summary.xml @@ -15,7 +15,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:windowBackground" - android:elevation="1dp" android:padding="5dp" android:visibility="invisible" tools:ignore="UnusedAttribute" diff --git a/app/src/main/res/layout/fragment_exam.xml b/app/src/main/res/layout/fragment_exam.xml index 155f18f9..23086bfb 100644 --- a/app/src/main/res/layout/fragment_exam.xml +++ b/app/src/main/res/layout/fragment_exam.xml @@ -60,7 +60,6 @@ android:layout_width="match_parent" android:layout_height="50dp" android:layout_gravity="bottom" - android:elevation="8dp" android:orientation="horizontal" tools:ignore="UnusedAttribute"> diff --git a/app/src/main/res/layout/fragment_grade.xml b/app/src/main/res/layout/fragment_grade.xml index ce614703..d134ec17 100644 --- a/app/src/main/res/layout/fragment_grade.xml +++ b/app/src/main/res/layout/fragment_grade.xml @@ -5,12 +5,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - diff --git a/app/src/main/res/layout/fragment_message.xml b/app/src/main/res/layout/fragment_message.xml index 8a36e7f3..7a2cfcf4 100644 --- a/app/src/main/res/layout/fragment_message.xml +++ b/app/src/main/res/layout/fragment_message.xml @@ -5,12 +5,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - diff --git a/app/src/main/res/layout/fragment_timetable_completed.xml b/app/src/main/res/layout/fragment_timetable_completed.xml index bddc3b67..dee31ae4 100644 --- a/app/src/main/res/layout/fragment_timetable_completed.xml +++ b/app/src/main/res/layout/fragment_timetable_completed.xml @@ -64,7 +64,6 @@ android:layout_width="match_parent" android:layout_height="50dp" android:layout_gravity="bottom" - android:elevation="8dp" android:orientation="horizontal" tools:ignore="UnusedAttribute">