在androidx.fragment.app.Fragment中,setUserVisibleHint()被弃用了,并且没有被执行,为什么?
in androidx.fragment.app.Fragment,setUserVisibleHint()is Deprecated,and not executed,why?
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInVisible();
}
}
发现这部分代码没有执行
现在 AndroidX
方法 setUserVisibleHint(boolean isVisibleToUser)
已弃用,如果您查看文档,它会说:
You can now set a max Lifecycle
state for a Fragment by calling
setMaxLifecycle()
on a FragmentTransaction
. This replaces the now
deprecated setUserVisibleHint()
. FragmentPagerAdapter
and
FragmentStatePagerAdapter
have a new constructor that allows you to
switch to the new behavior.
所以基本上当你在 FragmentTransaction
中使用这种方法时:
.getSupportFragmentManager()
.beginTransaction()
.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
等同于 setUserVisibleHint(false)
并且:
.getSupportFragmentManager()
.beginTransaction()
.setMaxLifecycle(fragment, Lifecycle.State.RESUMED);
相当于:setUserVisibleHint(true)
他们刚刚在 Fragments 中更改了 API。
如果使用此方法限制片段生命周期:
You can now set a max Lifecycle state for a Fragment by calling
setMaxLifecycle() on a FragmentTransaction. This replaces the now
deprecated setUserVisibleHint().
来源:https://developer.android.com/jetpack/androidx/releases/fragment#1.1.0-alpha07 .
如果您需要此方法,因为您试图检测哪个片段当前在 ViewPager
中可见。您现在可以只使用 onResume
和 onPause
方法,但在此之前您应该更改 FragmentPagerAdapter
构造函数中的默认行为。
像这样:
FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
编辑:
因为 FragmentPagerAdapter
也被弃用了,所以现在最好使用 ViewPager2。
在 ViewPager2
的情况下,这是默认行为,我们可以使用 onResume
和 onPause
方法来了解哪个片段当前可见。
此答案假定您使用的是 FragmentStatePagerAdapter
在 androidx.fragment
的新版本中(从 1.1.0+ 开始),如果您的 FragmentStatePagerAdapter
使用由 [=16 指定的旧行为,Fragment.setUserVisibleHint
仍将被调用=].
如果您构建了 FragmentStatePagerAdapter
并通过了 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
,那么 Fragment.setUserVisibleHint
将不再在 FragmentStatePagerAdapter.instantiateItem
中被调用。
注意: 如果您在 FragmentStatePagerAdapter
中指定了 BEHAVIOR_SET_USER_VISIBLE_HINT
,您仍然可以调用已弃用的 Fragment.getUserVisibleHint
,但请注意将 return true
即使 Fragment.isResumed()
将 return false.
androidx
项目是开源的。查看master上的最新代码,可以看到在instantiateItem
里面的setUserVisibleHint
周围增加了一个if
:https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStatePagerAdapter.java#195
- TL;DR:
1.0.x:
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
1.1.0+:
fragment.setMenuVisibility(false);
if (mBehavior == BEHAVIOR_SET_USER_VISIBLE_HINT) {
fragment.setUserVisibleHint(false);
}
如果您正在使用 FragmentStateAdapter
,您应该使用 registerFragmentTransactionCallback
方法来检查 Fragment 与 ViewPager2
交互的生命周期。
我需要像我一样拥有 ViewPager2 的返回堆栈 ,实现是
init {
// Add a FragmentTransactionCallback to handle changing
// the primary navigation fragment
registerFragmentTransactionCallback(object : FragmentTransactionCallback() {
override fun onFragmentMaxLifecyclePreUpdated(
fragment: Fragment,
maxLifecycleState: Lifecycle.State
) = if (maxLifecycleState == Lifecycle.State.RESUMED) {
// This fragment is becoming the active Fragment - set it to
// the primary navigation fragment in the OnPostEventListener
OnPostEventListener {
fragment.parentFragmentManager.commitNow {
setPrimaryNavigationFragment(fragment)
}
}
} else {
super.onFragmentMaxLifecyclePreUpdated(fragment, maxLifecycleState)
}
})
}
我的问题是为 ViewPager2 的片段设置返回堆栈,每个片段只有在它们可见时才有自己的返回堆栈,因为在每个片段上设置 OnBackPressed 会导致不需要的弹出堆栈,您可以修改或使用 [=14= 的其他方法].
但是,我不知道它是否是误报,但 Leak Canary 有时会显示 FragmentMaxLifeCycleEnforcer
实例泄漏,所以如果您遇到这样的问题,您可能需要在 FragmentTransactionCallback
中注销 FragmentTransactionCallback
onPause
或其他相关方法
片段本身有一个新方法
Return true if the fragment is in the resumed state. This is true for the duration of onResume() and onPause() as well.
package androidx.fragment.app;
final public boolean isResumed() {
return mState >= RESUMED;
}
您可以通过键入以下内容调用此方法:
if (isResumed) {
// your code here
}
不懂的简单解释一下
在你的 ViewPagerAdapter 中必须是这样的,构造函数发送 super
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
整个代码如下所示。
private static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments = new ArrayList<>();
private final List<String> fragmentTitle = new ArrayList<>();
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
public void addFragment(Fragment fragment, String title) {
fragments.add(fragment);
fragmentTitle.add(title);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitle.get(position);
}
}
这样,fragment中的onresume方法就可以了
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInVisible();
}
}
发现这部分代码没有执行
现在 AndroidX
方法 setUserVisibleHint(boolean isVisibleToUser)
已弃用,如果您查看文档,它会说:
You can now set a max
Lifecycle
state for a Fragment by callingsetMaxLifecycle()
on aFragmentTransaction
. This replaces the now deprecatedsetUserVisibleHint()
.FragmentPagerAdapter
andFragmentStatePagerAdapter
have a new constructor that allows you to switch to the new behavior.
所以基本上当你在 FragmentTransaction
中使用这种方法时:
.getSupportFragmentManager()
.beginTransaction()
.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
等同于 setUserVisibleHint(false)
并且:
.getSupportFragmentManager()
.beginTransaction()
.setMaxLifecycle(fragment, Lifecycle.State.RESUMED);
相当于:setUserVisibleHint(true)
他们刚刚在 Fragments 中更改了 API。
如果使用此方法限制片段生命周期:
You can now set a max Lifecycle state for a Fragment by calling setMaxLifecycle() on a FragmentTransaction. This replaces the now deprecated setUserVisibleHint().
来源:https://developer.android.com/jetpack/androidx/releases/fragment#1.1.0-alpha07 .
如果您需要此方法,因为您试图检测哪个片段当前在 ViewPager
中可见。您现在可以只使用 onResume
和 onPause
方法,但在此之前您应该更改 FragmentPagerAdapter
构造函数中的默认行为。
像这样:
FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
编辑:
因为 FragmentPagerAdapter
也被弃用了,所以现在最好使用 ViewPager2。
在 ViewPager2
的情况下,这是默认行为,我们可以使用 onResume
和 onPause
方法来了解哪个片段当前可见。
此答案假定您使用的是 FragmentStatePagerAdapter
在 androidx.fragment
的新版本中(从 1.1.0+ 开始),如果您的 FragmentStatePagerAdapter
使用由 [=16 指定的旧行为,Fragment.setUserVisibleHint
仍将被调用=].
如果您构建了 FragmentStatePagerAdapter
并通过了 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
,那么 Fragment.setUserVisibleHint
将不再在 FragmentStatePagerAdapter.instantiateItem
中被调用。
注意: 如果您在 FragmentStatePagerAdapter
中指定了 BEHAVIOR_SET_USER_VISIBLE_HINT
,您仍然可以调用已弃用的 Fragment.getUserVisibleHint
,但请注意将 return true
即使 Fragment.isResumed()
将 return false.
androidx
项目是开源的。查看master上的最新代码,可以看到在instantiateItem
里面的setUserVisibleHint
周围增加了一个if
:https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStatePagerAdapter.java#195
- TL;DR:
1.0.x:
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
1.1.0+:
fragment.setMenuVisibility(false);
if (mBehavior == BEHAVIOR_SET_USER_VISIBLE_HINT) {
fragment.setUserVisibleHint(false);
}
如果您正在使用 FragmentStateAdapter
,您应该使用 registerFragmentTransactionCallback
方法来检查 Fragment 与 ViewPager2
交互的生命周期。
我需要像我一样拥有 ViewPager2 的返回堆栈
init {
// Add a FragmentTransactionCallback to handle changing
// the primary navigation fragment
registerFragmentTransactionCallback(object : FragmentTransactionCallback() {
override fun onFragmentMaxLifecyclePreUpdated(
fragment: Fragment,
maxLifecycleState: Lifecycle.State
) = if (maxLifecycleState == Lifecycle.State.RESUMED) {
// This fragment is becoming the active Fragment - set it to
// the primary navigation fragment in the OnPostEventListener
OnPostEventListener {
fragment.parentFragmentManager.commitNow {
setPrimaryNavigationFragment(fragment)
}
}
} else {
super.onFragmentMaxLifecyclePreUpdated(fragment, maxLifecycleState)
}
})
}
我的问题是为 ViewPager2 的片段设置返回堆栈,每个片段只有在它们可见时才有自己的返回堆栈,因为在每个片段上设置 OnBackPressed 会导致不需要的弹出堆栈,您可以修改或使用 [=14= 的其他方法].
但是,我不知道它是否是误报,但 Leak Canary 有时会显示 FragmentMaxLifeCycleEnforcer
实例泄漏,所以如果您遇到这样的问题,您可能需要在 FragmentTransactionCallback
中注销 FragmentTransactionCallback
onPause
或其他相关方法
片段本身有一个新方法
Return true if the fragment is in the resumed state. This is true for the duration of onResume() and onPause() as well.
package androidx.fragment.app;
final public boolean isResumed() {
return mState >= RESUMED;
}
您可以通过键入以下内容调用此方法:
if (isResumed) {
// your code here
}
不懂的简单解释一下
在你的 ViewPagerAdapter 中必须是这样的,构造函数发送 super
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
整个代码如下所示。
private static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments = new ArrayList<>();
private final List<String> fragmentTitle = new ArrayList<>();
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
public void addFragment(Fragment fragment, String title) {
fragments.add(fragment);
fragmentTitle.add(title);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitle.get(position);
}
}
这样,fragment中的onresume方法就可以了