OsmAnd/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt
2018-06-27 11:06:24 +03:00

293 lines
8.9 KiB
Kotlin

package net.osmand.telegram.ui
import android.animation.*
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.Bundle
import android.support.design.widget.AppBarLayout
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.*
import android.widget.*
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.helpers.TelegramHelper.TelegramListener
import net.osmand.telegram.ui.MyLocationTabFragment.MyLocationListAdapter.ChatViewHolder
import org.drinkless.td.libcore.telegram.TdApi
private const val SELECTED_CHATS_KEY = "selected_chats"
class MyLocationTabFragment : Fragment(), TelegramListener {
private var textMarginSmall: Int = 0
private var textMarginBig: Int = 0
private var searchBoxHeight: Int = 0
private var searchBoxSidesMargin: Int = 0
private val app: TelegramApplication
get() = activity?.application as TelegramApplication
private val telegramHelper get() = app.telegramHelper
private lateinit var appBarLayout: AppBarLayout
private lateinit var textContainer: LinearLayout
private lateinit var title: TextView
private lateinit var description: TextView
private lateinit var searchBox: FrameLayout
private lateinit var searchBoxBg: GradientDrawable
private val adapter = MyLocationListAdapter()
private var appBarCollapsed = false
private lateinit var appBarOutlineProvider: ViewOutlineProvider
private val selectedChats = HashSet<Long>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
textMarginSmall = resources.getDimensionPixelSize(R.dimen.content_padding_standard)
textMarginBig = resources.getDimensionPixelSize(R.dimen.my_location_text_sides_margin)
searchBoxHeight = resources.getDimensionPixelSize(R.dimen.search_box_height)
searchBoxSidesMargin = resources.getDimensionPixelSize(R.dimen.content_padding_half)
savedInstanceState?.apply {
selectedChats.addAll(getLongArray(SELECTED_CHATS_KEY).toSet())
}
val mainView = inflater.inflate(R.layout.fragment_my_location_tab, container, false)
appBarLayout = mainView.findViewById<AppBarLayout>(R.id.app_bar_layout).apply {
if (Build.VERSION.SDK_INT >= 21) {
appBarOutlineProvider = outlineProvider
outlineProvider = null
}
addOnOffsetChangedListener { appBar, offset ->
val collapsed = Math.abs(offset) == appBar.totalScrollRange
if (collapsed != appBarCollapsed) {
appBarCollapsed = collapsed
adjustText()
adjustSearchBox()
}
}
}
textContainer = mainView.findViewById<LinearLayout>(R.id.text_container).apply {
if (Build.VERSION.SDK_INT >= 16) {
layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
}
title = findViewById(R.id.title)
description = findViewById(R.id.description)
}
searchBoxBg = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
setColor(ContextCompat.getColor(context!!, R.color.screen_bg_light))
cornerRadius = (searchBoxHeight / 2).toFloat()
}
searchBox = mainView.findViewById<FrameLayout>(R.id.search_box).apply {
if (Build.VERSION.SDK_INT >= 16) {
background = searchBoxBg
} else {
@Suppress("DEPRECATION")
setBackgroundDrawable(searchBoxBg)
}
findViewById<View>(R.id.search_button).setOnClickListener {
Toast.makeText(context, "Search", Toast.LENGTH_SHORT).show()
}
findViewById<ImageView>(R.id.search_icon)
.setImageDrawable(app.uiUtils.getThemedIcon(R.drawable.ic_action_search_dark))
}
mainView.findViewById<RecyclerView>(R.id.recycler_view).apply {
layoutManager = LinearLayoutManager(context)
adapter = this@MyLocationTabFragment.adapter
}
return mainView
}
override fun onResume() {
super.onResume()
updateList()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putLongArray(SELECTED_CHATS_KEY, selectedChats.toLongArray())
}
override fun onTelegramStatusChanged(
prevTelegramAuthorizationState: TelegramHelper.TelegramAuthorizationState,
newTelegramAuthorizationState: TelegramHelper.TelegramAuthorizationState
) {
when (newTelegramAuthorizationState) {
TelegramHelper.TelegramAuthorizationState.READY -> {
updateList()
}
TelegramHelper.TelegramAuthorizationState.CLOSED,
TelegramHelper.TelegramAuthorizationState.UNKNOWN -> {
adapter.chats = emptyList()
}
else -> Unit
}
}
override fun onTelegramChatsRead() {
updateList()
}
override fun onTelegramChatsChanged() {
updateList()
}
override fun onTelegramChatChanged(chat: TdApi.Chat) {
updateList()
}
override fun onTelegramUserChanged(user: TdApi.User) {
updateList()
}
override fun onTelegramError(code: Int, message: String) {
}
override fun onSendLiveLocationError(code: Int, message: String) {
}
private fun adjustText() {
val gravity = if (appBarCollapsed) Gravity.START else Gravity.CENTER
val padding = if (appBarCollapsed) textMarginSmall else textMarginBig
textContainer.apply {
setPadding(padding, paddingTop, padding, paddingBottom)
}
title.gravity = gravity
description.gravity = gravity
}
private fun adjustSearchBox() {
val cornerRadiusFrom = if (appBarCollapsed) searchBoxHeight / 2 else 0
val cornerRadiusTo = if (appBarCollapsed) 0 else searchBoxHeight / 2
val marginFrom = if (appBarCollapsed) searchBoxSidesMargin else 0
val marginTo = if (appBarCollapsed) 0 else searchBoxSidesMargin
val cornerAnimator = ObjectAnimator.ofFloat(
searchBoxBg,
"cornerRadius",
cornerRadiusFrom.toFloat(),
cornerRadiusTo.toFloat()
)
val marginAnimator = ValueAnimator.ofInt(marginFrom, marginTo)
marginAnimator.addUpdateListener {
val value = it.animatedValue as Int
val params = searchBox.layoutParams as LinearLayout.LayoutParams
params.setMargins(value, params.topMargin, value, params.bottomMargin)
searchBox.layoutParams = params
}
val animatorSet = AnimatorSet()
animatorSet.duration = 200
animatorSet.playTogether(cornerAnimator, marginAnimator)
if (Build.VERSION.SDK_INT >= 21) {
if (appBarCollapsed) {
animatorSet.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
if (Build.VERSION.SDK_INT >= 21 && appBarCollapsed) {
appBarLayout.outlineProvider = appBarOutlineProvider
}
}
})
} else {
appBarLayout.outlineProvider = null
}
}
animatorSet.start()
}
private fun updateList() {
val chatList = telegramHelper.getChatList()
val chats: MutableList<TdApi.Chat> = mutableListOf()
for (orderedChat in chatList) {
val chat = telegramHelper.getChat(orderedChat.chatId)
if (chat != null) {
chats.add(chat)
}
}
adapter.chats = chats
}
inner class MyLocationListAdapter : RecyclerView.Adapter<ChatViewHolder>() {
var chats: List<TdApi.Chat> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.user_list_item, parent, false)
return ChatViewHolder(view)
}
override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
val chat = chats[position]
val lastItem = position == itemCount - 1
var drawable: Drawable? = null
var bitmap: Bitmap? = null
val chatPhoto = chat.photo?.small
if (chatPhoto != null && chatPhoto.local.path.isNotEmpty()) {
bitmap = app.uiUtils.getCircleBitmap(chatPhoto.local.path)
}
if (bitmap == null) {
drawable = app.uiUtils.getThemedIcon(R.drawable.ic_group)
}
if (bitmap != null) {
holder.icon?.setImageBitmap(bitmap)
} else {
holder.icon?.setImageDrawable(drawable)
}
holder.title?.text = chat.title
holder.description?.text = "Some description" // FIXME
holder.checkBox?.apply {
visibility = View.VISIBLE
setOnCheckedChangeListener(null)
isChecked = selectedChats.contains(chat.id)
setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
selectedChats.add(chat.id)
} else {
selectedChats.remove(chat.id)
}
}
}
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
holder.itemView.setOnClickListener {
holder.checkBox?.apply {
isChecked = !isChecked
}
}
}
override fun getItemCount() = chats.size
inner class ChatViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val icon: ImageView? = view.findViewById(R.id.icon)
val title: TextView? = view.findViewById(R.id.title)
val description: TextView? = view.findViewById(R.id.description)
val checkBox: CheckBox? = view.findViewById(R.id.check_box)
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
}
}
}