Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.cyder.android.syncpod.util

import android.databinding.BindingAdapter
import android.databinding.InverseBindingAdapter
import android.databinding.InverseBindingListener
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SwitchCompat
Expand Down Expand Up @@ -39,10 +41,11 @@ fun TextView.setLinksNavigable(flag: Boolean) {
@BindingAdapter("onEnterClick")
fun EditText.setKeyboardClick(listener: TextView.OnEditorActionListener) = setOnEditorActionListener(listener)

@BindingAdapter(value = ["onScrolled", "onScrollStateChanged"], requireAll = false)
@BindingAdapter(value = ["onScrolled", "onScrollStateChanged", "scrollAttrChanged"], requireAll = false)
fun RecyclerView.setOnScrollChangedListeners(
onScrolled: OnScrolledListener?,
onScrollStateChanged: OnScrollStateChangedListener?
onScrollStateChanged: OnScrollStateChangedListener?,
scrollAttrChanged: InverseBindingListener?
) {
val OFFSET = 5
val listener = object : RecyclerView.OnScrollListener() {
Expand All @@ -57,6 +60,7 @@ fun RecyclerView.setOnScrollChangedListeners(
val nowHeadPos = layoutManager.findFirstVisibleItemPosition()
val lastPos = layoutManager.findLastCompletelyVisibleItemPosition()
onScrolled?.onScrolled(totalCount <= childCount + nowHeadPos + OFFSET)
scrollAttrChanged?.onChange()
}
}

Expand All @@ -71,6 +75,21 @@ interface OnScrollStateChangedListener {
fun onScrollStateChanged(recycler: RecyclerView, newState: Int)
}

@BindingAdapter("scrollToEnd")
fun RecyclerView.setScrollToEnd(flag: Boolean) {
if (flag && !isScrollToEnd()) {
smoothScrollToPosition(adapter.itemCount)
}
}

@InverseBindingAdapter(attribute = "scrollToEnd", event = "scrollAttrChanged")
fun RecyclerView.isScrollToEnd(): Boolean {
val manager = layoutManager as LinearLayoutManager
val lastVisiblePosition = manager.findLastVisibleItemPosition()
val lastListPosition = adapter.itemCount - 1
return lastListPosition == lastVisiblePosition
}

@BindingAdapter(value = ["animatedVisibility", "originalHeight", "animationDuration"])
fun View.setAnimatedVisibility(
visibility: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ class ChatFragment : BaseFragment() {
val manager = LinearLayoutManager(activity)
manager.stackFromEnd = true
val adapter = ChatAdapter(viewModel.chatViewModels)
val dataObserver = AutoScrollDataObserver(manager, adapter)
adapter.registerAdapterDataObserver(dataObserver)
binding.chatList.adapter = adapter
binding.chatList.layoutManager = manager
binding.chatList.addItemDecoration(DividerItemDecoration(binding.chatList.context, manager.orientation))
Expand All @@ -61,20 +59,6 @@ class ChatFragment : BaseFragment() {
}
}

inner class AutoScrollDataObserver(
private val manager: LinearLayoutManager,
private val adapter: ChatAdapter
) : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
super.onItemRangeInserted(positionStart, itemCount)
val lastVisiblePosition = manager.findLastVisibleItemPosition()
val lastListPosition = adapter.itemCount - 1
if (lastListPosition - 1 == lastVisiblePosition) {
binding.chatList.smoothScrollToPosition(lastListPosition + 1)
}
}
}

companion object {
fun createInstance() = ChatFragment()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.cyder.android.syncpod.viewmodel

import android.databinding.ObservableArrayList
import android.databinding.ObservableBoolean
import android.databinding.ObservableField
import android.databinding.ObservableList
import com.cyder.android.syncpod.model.Chat
Expand All @@ -22,6 +23,7 @@ class ChatFragmentViewModel @Inject constructor(
private val repository: ChatRepository
) : FragmentViewModel() {
var chatViewModels: ObservableList<ChatViewModel> = ObservableArrayList()
var scrolledToEnd = ObservableBoolean()
private val onPauseSubject = PublishSubject.create<Unit>()

override fun onStart() {
Expand All @@ -45,7 +47,7 @@ class ChatFragmentViewModel @Inject constructor(
ChatViewModel(ObservableField(it))
}
.subscribe {
chatViewModels.add(it)
addChat(it)
}
}

Expand All @@ -60,6 +62,15 @@ class ChatFragmentViewModel @Inject constructor(
return chats.map { ChatViewModel(ObservableField(it)) }
}

private fun addChat(chatViewModel: ChatViewModel) {
val isScrolledToEnd = scrolledToEnd.get()
scrolledToEnd.set(false)
chatViewModels.add(chatViewModel)
if (isScrolledToEnd) {
scrolledToEnd.set(true)
}
}

companion object {
val INVOCATION = Unit
}
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/res/layout/fragment_chat.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

Expand All @@ -15,6 +16,7 @@
<android.support.v7.widget.RecyclerView
android:id="@+id/chat_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
app:scrollToEnd="@={viewModel.scrolledToEnd}" />
</LinearLayout>
</layout>