feat:优化首页Tab-Fragment的可见检测逻辑

fix:修复部分空指针异常
This commit is contained in:
max
2024-05-11 10:54:27 +08:00
parent f121ef5ad1
commit f76582b1f6
8 changed files with 90 additions and 47 deletions

View File

@@ -600,16 +600,10 @@ public class MainActivity extends BaseMvpActivity<IMainView, MainPresenter>
transaction.show(showFragment);
if (tempFragment != null) {
transaction.hide(tempFragment);
if (tempFragment instanceof MainTabContentView) {
((MainTabContentView) tempFragment).onVisibleStateChanged(false);
}
}
tempFragment = showFragment;
if (!isDestroyed()) {
transaction.commitNowAllowingStateLoss();
if (tempFragment instanceof MainTabContentView) {
((MainTabContentView) tempFragment).onVisibleStateChanged(true);
}
}
mCurrentTabType = tabType;

View File

@@ -1,5 +1,4 @@
package com.chwl.app
interface MainTabContentView {
fun onVisibleStateChanged(showOrHide: Boolean) {}
}

View File

@@ -13,6 +13,7 @@ import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.util.Consumer;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
@@ -56,6 +57,7 @@ public abstract class BaseFragment extends RxFragment implements KeyEvent.Callba
protected RxPermissions rxPermissions;
private boolean isLoaded = false;
public Consumer<Boolean> onHiddenChangedListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -182,6 +184,9 @@ public abstract class BaseFragment extends RxFragment implements KeyEvent.Callba
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (onHiddenChangedListener != null) {
onHiddenChangedListener.accept(hidden);
}
}
public Stack<Integer> activityForResult = new Stack<Integer>();

View File

@@ -1,10 +1,13 @@
package com.chwl.app.home.fragment
import android.annotation.SuppressLint
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.RecyclerView
@@ -19,6 +22,7 @@ import com.chwl.app.home.HomeMessageViewModel
import com.chwl.app.home.adapter.PublicChatLaneAdapter
import com.chwl.app.home.helper.AutoScrollTask
import com.chwl.app.public_chat.ui.message.PublicChatRoomMessageActivity
import com.chwl.app.support.FragmentVisibleStateHelper
import com.chwl.app.ui.im.friend.FriendListFragment
import com.chwl.app.ui.im.recent.RecentListFragment
import com.chwl.app.ui.relation.FansListFragment
@@ -39,6 +43,9 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
private val viewModel: HomeMessageViewModel by activityViewModels()
private val publicChatAdapter = PublicChatLaneAdapter(ArrayList())
private val stateHelper = FragmentVisibleStateHelper(this) {
onVisibleChanged(it)
}
companion object {
const val TAG = "ContactsListFragment"
@@ -114,6 +121,7 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
})
}
@SuppressLint("ClickableViewAccessibility")
private fun initPublicChatView() {
val gestureDetectorCompat = GestureDetectorCompat(requireContext(), object :
GestureDetector.OnGestureListener {
@@ -163,38 +171,24 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
val newList = it.data
if (it.isSuccess && !newList.isNullOrEmpty()) {
publicChatAdapter.setNewData(newList)
switchPublicChatMessageScrollState(true)
switchPublicChatMessageScrollState(stateHelper.isVisible)
}
binding.recyclerViewPublicChat.isVisible = (publicChatAdapter.getRealItemCount() > 0)
}
}
private fun refreshPublicChatMessage() {
viewModel.getTopPublicChatMessage()
}
override fun onStart() {
super.onStart()
onVisibleStateChanged(true)
refreshPublicChatMessage()
}
override fun onStop() {
super.onStop()
onVisibleStateChanged(false)
}
override fun onVisibleStateChanged(showOrHide: Boolean) {
switchPublicChatMessageScrollState(showOrHide)
}
private fun switchPublicChatMessageScrollState(showOrHide: Boolean) {
if (_binding == null) {
return
}
if (showOrHide && publicChatAdapter.getRealItemCount() > 0) {
private fun switchPublicChatMessageScrollState(isVisible: Boolean) {
if (isVisible && publicChatAdapter.getRealItemCount() > 0) {
autoScrollTask.start()
} else {
autoScrollTask.stop()
}
}
private fun onVisibleChanged(isVisible: Boolean) {
switchPublicChatMessageScrollState(isVisible)
if (isVisible) {
viewModel.getTopPublicChatMessage()
}
}
}

View File

@@ -11,6 +11,7 @@ import com.chwl.app.MainTabContentView
import com.chwl.app.R
import com.chwl.app.base.BaseViewBindingFragment
import com.chwl.app.databinding.StarFragmentBinding
import com.chwl.app.support.FragmentVisibleStateHelper
import com.chwl.app.ui.im.avtivity.NimP2PMessageActivity
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.utils.loadAvatar
@@ -41,6 +42,9 @@ class StarFragment : BaseViewBindingFragment<StarFragmentBinding>(), MainTabCont
private var currentUser: StarUser? = null
override fun init() {
FragmentVisibleStateHelper(this) {
onVisibleChanged(it)
}
initView()
initObserve()
viewModel.refreshList()
@@ -331,21 +335,8 @@ class StarFragment : BaseViewBindingFragment<StarFragmentBinding>(), MainTabCont
}
}
override fun onStart() {
super.onStart()
onVisibleStateChanged(true)
}
override fun onStop() {
super.onStop()
onVisibleStateChanged(false)
}
override fun onVisibleStateChanged(showOrHide: Boolean) {
if (_binding == null) {
return
}
if (showOrHide) {
private fun onVisibleChanged(isVisible: Boolean) {
if (isVisible) {
if (binding.ivGift.isVisible) {
switchGiftAnimState(true)
}

View File

@@ -0,0 +1,52 @@
package com.chwl.app.support
import androidx.core.util.Consumer
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.chwl.app.base.BaseFragment
class FragmentVisibleStateHelper(
private val fragment: Fragment,
private val onVisibleChanged: (Boolean) -> Unit
) : LifecycleEventObserver {
private var isRealVisible = false
val isVisible get() = isRealVisible
init {
fragment.lifecycle.addObserver(this)
(fragment as? BaseFragment)?.let {
it.onHiddenChangedListener = Consumer<Boolean> {
checkVisibleState()
}
}
}
fun checkVisibleState() {
val newRealVisible =
fragment.isAdded && !fragment.isHidden && fragment.lifecycle.currentState.isAtLeast(
Lifecycle.State.RESUMED
)
if (isRealVisible != newRealVisible) {
isRealVisible = newRealVisible
onVisibleChanged(newRealVisible)
}
}
private fun onVisibleChanged(isVisible: Boolean) {
onVisibleChanged.invoke(isVisible)
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (event == Lifecycle.Event.ON_RESUME) {
checkVisibleState()
} else if (event == Lifecycle.Event.ON_PAUSE) {
checkVisibleState()
} else if (event == Lifecycle.Event.ON_DESTROY) {
fragment.lifecycle.removeObserver(this)
}
}
}

View File

@@ -55,6 +55,8 @@
app:layout_constraintTop_toTopOf="@id/line_public_chat_title_top" />
<androidx.recyclerview.widget.RecyclerView
android:visibility="gone"
tools:visibility="visible"
android:id="@+id/recycler_view_public_chat"
android:layout_width="match_parent"
android:layout_height="0dp"

View File

@@ -840,6 +840,9 @@ public final class UserModel extends BaseModel implements IUserModel {
@Override
public boolean isSamePartition(long partitionId) {
if (currentUserInfo == null) {
return false;
}
if (currentUserInfo.partitionId == 0) {
return true;
}
@@ -848,6 +851,9 @@ public final class UserModel extends BaseModel implements IUserModel {
@Override
public long getPartitionId() {
if (currentUserInfo == null) {
return 0;
}
return currentUserInfo.partitionId;
}