From 6faf2856b23a8509d42540fc7ed413d77d864361 Mon Sep 17 00:00:00 2001 From: Mori Atsushi Date: Sat, 19 May 2018 20:14:24 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[delete]=20=E6=98=94=E3=81=AE=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../syncpod/view/fragment/ChatFragment.kt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/app/src/main/kotlin/com/cyder/android/syncpod/view/fragment/ChatFragment.kt b/app/src/main/kotlin/com/cyder/android/syncpod/view/fragment/ChatFragment.kt index 4ccded41..31beeb73 100644 --- a/app/src/main/kotlin/com/cyder/android/syncpod/view/fragment/ChatFragment.kt +++ b/app/src/main/kotlin/com/cyder/android/syncpod/view/fragment/ChatFragment.kt @@ -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)) @@ -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() } From d8162f9ff69fe3b6aadbe4636c86632b165afd25 Mon Sep 17 00:00:00 2001 From: Mori Atsushi Date: Sat, 19 May 2018 20:14:57 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[add]=20=E8=87=AA=E5=8B=95=E3=81=A7?= =?UTF-8?q?=E3=82=B9=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=AB=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/syncpod/util/CustomBinder.kt | 21 +++++++++++++++++-- .../viewmodel/ChatFragmentViewModel.kt | 7 +++++++ app/src/main/res/layout/fragment_chat.xml | 6 ++++-- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt b/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt index 75b74192..a0206870 100644 --- a/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt +++ b/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt @@ -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 @@ -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() { @@ -57,6 +60,7 @@ fun RecyclerView.setOnScrollChangedListeners( val nowHeadPos = layoutManager.findFirstVisibleItemPosition() val lastPos = layoutManager.findLastCompletelyVisibleItemPosition() onScrolled?.onScrolled(totalCount <= childCount + nowHeadPos + OFFSET) + scrollAttrChanged?.onChange() } } @@ -71,6 +75,19 @@ interface OnScrollStateChangedListener { fun onScrollStateChanged(recycler: RecyclerView, newState: Int) } +@BindingAdapter("scrollToEnd") +fun RecyclerView.setScrollToEnd(flag: Boolean) { + if (flag) 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, diff --git a/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt b/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt index 0d793822..7190595c 100644 --- a/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt +++ b/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt @@ -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 @@ -22,6 +23,7 @@ class ChatFragmentViewModel @Inject constructor( private val repository: ChatRepository ) : FragmentViewModel() { var chatViewModels: ObservableList = ObservableArrayList() + var isScrolledToEnd = ObservableBoolean() private val onPauseSubject = PublishSubject.create() override fun onStart() { @@ -45,7 +47,12 @@ class ChatFragmentViewModel @Inject constructor( ChatViewModel(ObservableField(it)) } .subscribe { + val flag = isScrolledToEnd.get() + isScrolledToEnd.set(false) chatViewModels.add(it) + if (flag) { + isScrolledToEnd.set(true) + } } } diff --git a/app/src/main/res/layout/fragment_chat.xml b/app/src/main/res/layout/fragment_chat.xml index 7c9fc00c..69be357d 100644 --- a/app/src/main/res/layout/fragment_chat.xml +++ b/app/src/main/res/layout/fragment_chat.xml @@ -1,5 +1,6 @@ - + @@ -15,6 +16,7 @@ + android:layout_height="match_parent" + app:scrollToEnd="@={viewModel.isScrolledToEnd}" /> \ No newline at end of file From 7e2058dfb2a1551a1bba730c87e79998390c66d8 Mon Sep 17 00:00:00 2001 From: Mori Atsushi Date: Sat, 19 May 2018 20:19:00 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[fix]=20=E4=BD=99=E8=A8=88=E3=81=AA?= =?UTF-8?q?=E3=82=B9=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=AB=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/cyder/android/syncpod/util/CustomBinder.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt b/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt index a0206870..6967eb52 100644 --- a/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt +++ b/app/src/main/kotlin/com/cyder/android/syncpod/util/CustomBinder.kt @@ -77,7 +77,9 @@ interface OnScrollStateChangedListener { @BindingAdapter("scrollToEnd") fun RecyclerView.setScrollToEnd(flag: Boolean) { - if (flag) smoothScrollToPosition(adapter.itemCount) + if (flag && !isScrollToEnd()) { + smoothScrollToPosition(adapter.itemCount) + } } @InverseBindingAdapter(attribute = "scrollToEnd", event = "scrollAttrChanged") From 7948f75f41253bb6c0be3bf173a4a6c0f8fb6335 Mon Sep 17 00:00:00 2001 From: Mori Atsushi Date: Sat, 19 May 2018 20:24:51 +0900 Subject: [PATCH 4/5] =?UTF-8?q?[clear]=20=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/syncpod/viewmodel/ChatFragmentViewModel.kt | 10 +++++----- app/src/main/res/layout/fragment_chat.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt b/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt index 7190595c..52743e6f 100644 --- a/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt +++ b/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt @@ -23,7 +23,7 @@ class ChatFragmentViewModel @Inject constructor( private val repository: ChatRepository ) : FragmentViewModel() { var chatViewModels: ObservableList = ObservableArrayList() - var isScrolledToEnd = ObservableBoolean() + var scrolledToEnd = ObservableBoolean() private val onPauseSubject = PublishSubject.create() override fun onStart() { @@ -47,11 +47,11 @@ class ChatFragmentViewModel @Inject constructor( ChatViewModel(ObservableField(it)) } .subscribe { - val flag = isScrolledToEnd.get() - isScrolledToEnd.set(false) + val isScrolledToEnd = scrolledToEnd.get() + scrolledToEnd.set(false) chatViewModels.add(it) - if (flag) { - isScrolledToEnd.set(true) + if (isScrolledToEnd) { + scrolledToEnd.set(true) } } } diff --git a/app/src/main/res/layout/fragment_chat.xml b/app/src/main/res/layout/fragment_chat.xml index 69be357d..89467a87 100644 --- a/app/src/main/res/layout/fragment_chat.xml +++ b/app/src/main/res/layout/fragment_chat.xml @@ -17,6 +17,6 @@ android:id="@+id/chat_list" android:layout_width="match_parent" android:layout_height="match_parent" - app:scrollToEnd="@={viewModel.isScrolledToEnd}" /> + app:scrollToEnd="@={viewModel.scrolledToEnd}" /> \ No newline at end of file From afcd0ed8c653045cc01bbd6d7ab396a3db4f64ea Mon Sep 17 00:00:00 2001 From: Mori Atsushi Date: Wed, 23 May 2018 18:19:12 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[clear]=20=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../syncpod/viewmodel/ChatFragmentViewModel.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt b/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt index 52743e6f..4542c445 100644 --- a/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt +++ b/app/src/main/kotlin/com/cyder/android/syncpod/viewmodel/ChatFragmentViewModel.kt @@ -47,12 +47,7 @@ class ChatFragmentViewModel @Inject constructor( ChatViewModel(ObservableField(it)) } .subscribe { - val isScrolledToEnd = scrolledToEnd.get() - scrolledToEnd.set(false) - chatViewModels.add(it) - if (isScrolledToEnd) { - scrolledToEnd.set(true) - } + addChat(it) } } @@ -67,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 }