Add timeline empty state and date control buttons

This commit is contained in:
Chumva 2019-07-13 16:34:25 +03:00
parent 474e620bf3
commit 3788f5183c
4 changed files with 129 additions and 31 deletions

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/empty_state_background_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding_big"
android:layout_marginBottom="@dimen/content_padding_standard"
android:scaleType="center"
android:src="@drawable/img_timeline_no_data"
android:tint="@color/icon_light" />
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_half"
android:background="@null"
android:text="@string/timeline_no_data"
android:textColor="?android:attr/textColorSecondary"
android:textSize="20sp"
osmand:typeface="@string/font_roboto_medium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/empty_state_descr_margin"
android:layout_marginRight="@dimen/empty_state_descr_margin"
android:background="@null"
android:gravity="center"
android:text="@string/timeline_no_data_descr"
android:textColor="?android:attr/textColorSecondary"
android:textSize="18sp" />
</LinearLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -20,11 +21,11 @@
android:letterSpacing="@dimen/title_letter_spacing" android:letterSpacing="@dimen/title_letter_spacing"
android:maxLines="1" android:maxLines="1"
android:paddingLeft="@dimen/content_padding_standard" android:paddingLeft="@dimen/content_padding_standard"
android:paddingTop="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard" android:paddingRight="@dimen/content_padding_standard"
android:paddingBottom="12dp"
android:text="@string/timeline" android:text="@string/timeline"
android:textColor="@color/app_bar_title_light" android:textColor="@color/app_bar_title_light"
android:paddingTop="@dimen/content_padding_standard"
android:paddingBottom="12dp"
android:textSize="@dimen/title_text_size" android:textSize="@dimen/title_text_size"
app:typeface="@string/font_roboto_mono_bold" /> app:typeface="@string/font_roboto_mono_bold" />
@ -84,6 +85,19 @@
android:paddingLeft="@dimen/content_padding_standard" android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"> android:paddingRight="@dimen/content_padding_standard">
<ImageView
android:id="@+id/date_btn_previous"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="start|center_vertical"
android:background="@drawable/btn_round_border"
android:paddingStart="@dimen/content_padding_half"
android:paddingLeft="@dimen/content_padding_half"
android:paddingEnd="@dimen/content_padding_big"
android:paddingRight="@dimen/content_padding_big"
android:src="@drawable/ic_arrow_back"
tools:tint="?attr/ctrl_active_color" />
<net.osmand.telegram.ui.views.TextViewEx <net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_btn" android:id="@+id/date_btn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -103,6 +117,20 @@
android:textSize="@dimen/text_button_text_size" android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium" /> app:typeface="@string/font_roboto_medium" />
<ImageView
android:id="@+id/date_btn_next"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="end|center_vertical"
android:background="@drawable/btn_round_border"
android:paddingStart="@dimen/content_padding_big"
android:paddingLeft="@dimen/content_padding_big"
android:paddingEnd="@dimen/content_padding_half"
android:paddingRight="@dimen/content_padding_half"
android:src="@drawable/ic_arrow_forward"
tools:tint="?attr/ctrl_active_color" />
</FrameLayout> </FrameLayout>
</android.support.design.widget.AppBarLayout> </android.support.design.widget.AppBarLayout>
@ -112,7 +140,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<net.osmand.telegram.ui.views.EmptyStateRecyclerView
android:id="@+id/recycler_view" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -120,6 +152,12 @@
android:paddingBottom="@dimen/list_item_content_margin" android:paddingBottom="@dimen/list_item_content_margin"
android:scrollbars="vertical" /> android:scrollbars="vertical" />
<include
android:id="@+id/empty_view"
layout="@layout/empty_state_timeline" />
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout> </android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout> </LinearLayout>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="timeline_no_data_descr">We don`t have collected data for the selected day</string>
<string name="timeline_no_data">No data</string>
<string name="shared_string_select">Select</string> <string name="shared_string_select">Select</string>
<string name="min_logging_distance">Minimum logging distance</string> <string name="min_logging_distance">Minimum logging distance</string>
<string name="min_logging_distance_descr">Filter: minimum distance to log a new point</string> <string name="min_logging_distance_descr">Filter: minimum distance to log a new point</string>

View file

@ -16,15 +16,16 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Switch import android.widget.Switch
import android.widget.TextView import android.widget.TextView
import net.osmand.PlatformUtil
import net.osmand.telegram.R import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.LocationMessages import net.osmand.telegram.helpers.LocationMessages
import net.osmand.telegram.helpers.TelegramUiHelper import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.helpers.TelegramUiHelper.ListItem import net.osmand.telegram.helpers.TelegramUiHelper.ListItem
import net.osmand.telegram.ui.TimelineTabFragment.LiveNowListAdapter.BaseViewHolder import net.osmand.telegram.ui.TimelineTabFragment.LiveNowListAdapter.BaseViewHolder
import net.osmand.telegram.ui.views.EmptyStateRecyclerView
import net.osmand.telegram.utils.AndroidUtils import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.OsmandFormatter import net.osmand.telegram.utils.OsmandFormatter
import java.util.* import java.util.*
@ -32,8 +33,6 @@ import java.util.*
class TimelineTabFragment : Fragment() { class TimelineTabFragment : Fragment() {
private val log = PlatformUtil.getLog(TimelineTabFragment::class.java)
private val app: TelegramApplication private val app: TelegramApplication
get() = activity?.application as TelegramApplication get() = activity?.application as TelegramApplication
@ -43,11 +42,12 @@ class TimelineTabFragment : Fragment() {
private lateinit var adapter: LiveNowListAdapter private lateinit var adapter: LiveNowListAdapter
private lateinit var dateBtn: TextView private lateinit var dateBtn: TextView
private lateinit var previousDateBtn: ImageView
private lateinit var nextDateBtn: ImageView
private lateinit var mainView: View private lateinit var mainView: View
private lateinit var switcher: Switch private lateinit var switcher: Switch
private var start = 0L private lateinit var calendar: Calendar
private var end = 0L
private var updateEnable: Boolean = false private var updateEnable: Boolean = false
@ -59,15 +59,16 @@ class TimelineTabFragment : Fragment() {
mainView = inflater.inflate(R.layout.fragment_timeline_tab, container, false) mainView = inflater.inflate(R.layout.fragment_timeline_tab, container, false)
val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout) val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout)
val calendar = Calendar.getInstance() calendar = Calendar.getInstance()
start = getStartOfDay(calendar)
end = getEndOfDay(calendar)
AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout) AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout)
adapter = LiveNowListAdapter() adapter = LiveNowListAdapter()
mainView.findViewById<RecyclerView>(R.id.recycler_view).apply {
val emptyView = mainView.findViewById<LinearLayout>(R.id.empty_view)
mainView.findViewById<EmptyStateRecyclerView>(R.id.recycler_view).apply {
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
adapter = this@TimelineTabFragment.adapter adapter = this@TimelineTabFragment.adapter
setEmptyView(emptyView)
} }
switcher = mainView.findViewById<Switch>(R.id.monitoring_switcher) switcher = mainView.findViewById<Switch>(R.id.monitoring_switcher)
@ -88,7 +89,25 @@ class TimelineTabFragment : Fragment() {
} }
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_start), null, null, null) setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_start), null, null, null)
setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light)) setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
text = OsmandFormatter.getFormattedDate(start / 1000) }
updateDateButton()
previousDateBtn = mainView.findViewById<ImageView>(R.id.date_btn_previous).apply {
setImageDrawable(getPressedStateIcon(R.drawable.ic_arrow_back))
setOnClickListener {
calendar.add(Calendar.DAY_OF_MONTH, -1)
updateList()
updateDateButton()
}
}
nextDateBtn = mainView.findViewById<ImageView>(R.id.date_btn_next).apply {
setImageDrawable(getPressedStateIcon(R.drawable.ic_arrow_forward))
setOnClickListener {
calendar.add(Calendar.DAY_OF_MONTH, 1)
updateList()
updateDateButton()
}
} }
mainView.findViewById<SwipeRefreshLayout>(R.id.swipe_refresh).apply { mainView.findViewById<SwipeRefreshLayout>(R.id.swipe_refresh).apply {
@ -122,25 +141,21 @@ class TimelineTabFragment : Fragment() {
fun tabClosed() {} fun tabClosed() {}
private fun selectDate() { private fun selectDate() {
val dateFromDialog = val dateSetListener =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth -> DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
val calendar = Calendar.getInstance() calendar = Calendar.getInstance()
calendar.set(Calendar.YEAR, year) calendar.set(Calendar.YEAR, year)
calendar.set(Calendar.MONTH, monthOfYear) calendar.set(Calendar.MONTH, monthOfYear)
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth) calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
start = getStartOfDay(calendar)
end = getEndOfDay(calendar)
updateList() updateList()
updateDateButton() updateDateButton()
} }
val startCalendar = Calendar.getInstance() DatePickerDialog(
startCalendar.timeInMillis = start context, dateSetListener,
DatePickerDialog(context, dateFromDialog, calendar.get(Calendar.YEAR),
startCalendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
startCalendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)
startCalendar.get(Calendar.DAY_OF_MONTH)
).show() ).show()
} }
@ -161,7 +176,7 @@ class TimelineTabFragment : Fragment() {
} }
private fun updateDateButton() { private fun updateDateButton() {
dateBtn.text = OsmandFormatter.getFormattedDate(start / 1000) dateBtn.text = OsmandFormatter.getFormattedDate(getStartOfDay(calendar) / 1000)
} }
private fun getPressedStateIcon(@DrawableRes iconId: Int): Drawable? { private fun getPressedStateIcon(@DrawableRes iconId: Int): Drawable? {
@ -187,6 +202,8 @@ class TimelineTabFragment : Fragment() {
private fun updateList() { private fun updateList() {
val res = mutableListOf<ListItem>() val res = mutableListOf<ListItem>()
val start = getStartOfDay(calendar)
val end = getEndOfDay(calendar)
app.locationMessages.getIngoingUserLocations(start, end).forEach { app.locationMessages.getIngoingUserLocations(start, end).forEach {
TelegramUiHelper.userLocationsToChatItem(telegramHelper, it)?.also { chatItem -> TelegramUiHelper.userLocationsToChatItem(telegramHelper, it)?.also { chatItem ->
res.add(chatItem) res.add(chatItem)
@ -309,6 +326,7 @@ class TimelineTabFragment : Fragment() {
var minTime: Long, var minTime: Long,
var maxTime: Long var maxTime: Long
) )
companion object { companion object {
private const val ADAPTER_UPDATE_INTERVAL_MIL = 15 * 1000L // 15 sec private const val ADAPTER_UPDATE_INTERVAL_MIL = 15 * 1000L // 15 sec
} }