Merge pull request #7248 from osmandapp/TrackerTimelineEmptyStateControls
Add timeline empty state and date control buttons
This commit is contained in:
commit
61f4b7239e
4 changed files with 129 additions and 31 deletions
40
OsmAnd-telegram/res/layout/empty_state_timeline.xml
Normal file
40
OsmAnd-telegram/res/layout/empty_state_timeline.xml
Normal 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>
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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">
|
||||
|
@ -20,11 +21,11 @@
|
|||
android:letterSpacing="@dimen/title_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingTop="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/timeline"
|
||||
android:textColor="@color/app_bar_title_light"
|
||||
android:paddingTop="@dimen/content_padding_standard"
|
||||
android:paddingBottom="12dp"
|
||||
android:textSize="@dimen/title_text_size"
|
||||
app:typeface="@string/font_roboto_mono_bold" />
|
||||
|
||||
|
@ -84,6 +85,19 @@
|
|||
android:paddingLeft="@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
|
||||
android:id="@+id/date_btn"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -103,6 +117,20 @@
|
|||
android:textSize="@dimen/text_button_text_size"
|
||||
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>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
@ -112,13 +140,23 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="@dimen/list_item_content_margin"
|
||||
android:scrollbars="vertical" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<net.osmand.telegram.ui.views.EmptyStateRecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="@dimen/list_item_content_margin"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
<include
|
||||
android:id="@+id/empty_view"
|
||||
layout="@layout/empty_state_timeline" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="min_logging_distance">Minimum logging distance</string>
|
||||
<string name="min_logging_distance_descr">Filter: minimum distance to log a new point</string>
|
||||
|
|
|
@ -16,15 +16,16 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Switch
|
||||
import android.widget.TextView
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.helpers.LocationMessages
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper.ListItem
|
||||
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.OsmandFormatter
|
||||
import java.util.*
|
||||
|
@ -32,8 +33,6 @@ import java.util.*
|
|||
|
||||
class TimelineTabFragment : Fragment() {
|
||||
|
||||
private val log = PlatformUtil.getLog(TimelineTabFragment::class.java)
|
||||
|
||||
private val app: TelegramApplication
|
||||
get() = activity?.application as TelegramApplication
|
||||
|
||||
|
@ -43,11 +42,12 @@ class TimelineTabFragment : Fragment() {
|
|||
private lateinit var adapter: LiveNowListAdapter
|
||||
|
||||
private lateinit var dateBtn: TextView
|
||||
private lateinit var previousDateBtn: ImageView
|
||||
private lateinit var nextDateBtn: ImageView
|
||||
private lateinit var mainView: View
|
||||
private lateinit var switcher: Switch
|
||||
|
||||
private var start = 0L
|
||||
private var end = 0L
|
||||
private lateinit var calendar: Calendar
|
||||
|
||||
private var updateEnable: Boolean = false
|
||||
|
||||
|
@ -59,15 +59,16 @@ class TimelineTabFragment : Fragment() {
|
|||
mainView = inflater.inflate(R.layout.fragment_timeline_tab, container, false)
|
||||
val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout)
|
||||
|
||||
val calendar = Calendar.getInstance()
|
||||
start = getStartOfDay(calendar)
|
||||
end = getEndOfDay(calendar)
|
||||
calendar = Calendar.getInstance()
|
||||
|
||||
AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout)
|
||||
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)
|
||||
adapter = this@TimelineTabFragment.adapter
|
||||
setEmptyView(emptyView)
|
||||
}
|
||||
|
||||
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)
|
||||
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 {
|
||||
|
@ -122,25 +141,21 @@ class TimelineTabFragment : Fragment() {
|
|||
fun tabClosed() {}
|
||||
|
||||
private fun selectDate() {
|
||||
val dateFromDialog =
|
||||
val dateSetListener =
|
||||
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar = Calendar.getInstance()
|
||||
calendar.set(Calendar.YEAR, year)
|
||||
calendar.set(Calendar.MONTH, monthOfYear)
|
||||
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||
|
||||
start = getStartOfDay(calendar)
|
||||
end = getEndOfDay(calendar)
|
||||
|
||||
updateList()
|
||||
updateDateButton()
|
||||
}
|
||||
val startCalendar = Calendar.getInstance()
|
||||
startCalendar.timeInMillis = start
|
||||
DatePickerDialog(context, dateFromDialog,
|
||||
startCalendar.get(Calendar.YEAR),
|
||||
startCalendar.get(Calendar.MONTH),
|
||||
startCalendar.get(Calendar.DAY_OF_MONTH)
|
||||
DatePickerDialog(
|
||||
context, dateSetListener,
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
|
||||
|
@ -161,7 +176,7 @@ class TimelineTabFragment : Fragment() {
|
|||
}
|
||||
|
||||
private fun updateDateButton() {
|
||||
dateBtn.text = OsmandFormatter.getFormattedDate(start / 1000)
|
||||
dateBtn.text = OsmandFormatter.getFormattedDate(getStartOfDay(calendar) / 1000)
|
||||
}
|
||||
|
||||
private fun getPressedStateIcon(@DrawableRes iconId: Int): Drawable? {
|
||||
|
@ -187,6 +202,8 @@ class TimelineTabFragment : Fragment() {
|
|||
|
||||
private fun updateList() {
|
||||
val res = mutableListOf<ListItem>()
|
||||
val start = getStartOfDay(calendar)
|
||||
val end = getEndOfDay(calendar)
|
||||
app.locationMessages.getIngoingUserLocations(start, end).forEach {
|
||||
TelegramUiHelper.userLocationsToChatItem(telegramHelper, it)?.also { chatItem ->
|
||||
res.add(chatItem)
|
||||
|
@ -303,12 +320,13 @@ class TimelineTabFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
data class UITrackData (
|
||||
data class UITrackData(
|
||||
var dist: Float,
|
||||
var points: Int,
|
||||
var minTime: Long,
|
||||
var maxTime: Long
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val ADAPTER_UPDATE_INTERVAL_MIL = 15 * 1000L // 15 sec
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue