Android 如何在 Fragment 中使用 setUserVisibleHint
How to use setUserVisibleHint in Fragment on Android
在我的应用程序中,我有 BottomNavBar
,我希望在单击此 BottomNavBar
的项目时显示 fragments
!
为了将此 fragments
设置为 BottomNavBar
,我使用了 NavigationGraph
组件!
我想对其中一个 fragment
使用 setUserVisibleHint
方法,但是当显示此 fragment
时不调用 setUserVisibleHint
!
我的 Activity 代码 用于设置 fragments
到 BottomNavBar
项:
class HomeActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupNavigation()
}
private fun setupNavigation() {
val navController = Navigation.findNavController(this, R.id.homePage_fragmentNavHost)
NavigationUI.setupWithNavController(homePage_bottomNavBar, navController)
}
override fun onSupportNavigateUp() = Navigation.findNavController(this, R.id.homePage_fragmentNavHost).navigateUp()
}
我的片段代码:
class HomeDashboardFragment : Fragment(){
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home_dashboard, container, false)
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
Handler().postDelayed({ requireContext().toast("Show") }, 500)
}
}
}
为什么不把 setUserVisibleHint
变成 fragment
?
在输入此代码之前,您了解片段生命周期
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
// post your code
}
}
override fun onStart() {
super.onStart()
userVisibleHint = true
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser){
if (NetworkUtils.isConnected(getActivity())) {
callYourApi();
}
}
}
使用 BottomSheetBehavior https://developer.android.com/reference/android/support/design/widget/BottomSheetBehavior 进行此类实施。您也可以使用 BottomSheetDialogFragment。
要设置特定行为,请使用此代码,例如
bottomSheetBehavior.setPeekHeight(300);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
如果你正在使用 Navigation, this may not be the best way to achieve the behavior you desire. Navigation has an OnDestinationChangedListener Interface that receives a callback whenever NavController.getCurrentDestination 被调用。
幸运的是,您使用的是 Kotlin,并且在 HomeActivity 中,您也许可以通过以下方式逃脱:
navController.addOnDestinationChangedListener { _, destination, _ ->
Handler().postDelayed({ requireContext().toast("Show") }, 500)
}
你应该会得到想要的结果。
如果您是 Navigation 的新手,我会在 Github 上推荐 this codelab. It goes through some of the basics and can help get you started. For some of the more advanced concepts, you can checkout the NavigationAdvancedSample。
如果您想直接使用片段,使用生命周期方法 (onStart) 可能比 setUserVisibleHint() 更可靠。
由于 setUserVisibleHint(boolean aBoolean) 现已弃用,对于那些仍然想知道片段何时可见的人,您仍然可以使用
public FragmentTransaction setMaxLifecycle(Fragment fragment, Lifecycle.State state)
间接使用 FragmentPagerAdapter(或 FragmentStatePagerAdapter)
只需使用新的构造函数
MyFPagerAdapter(FragmentManager fm) {
super(fm ,FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
//...
}
请注意
FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 允许适配器在内部使用 setMaxLifecycle(通过 setPrimaryItem)而不是 setUserVisibleHint。
因此,在您的片段实现中,您将不再需要使用
setUserVisibleHint(boolean aBoolean)
但相反,onResume() 导致现在 onResume() 将仅针对可见片段调用。其余的仍然可以到达 onCreateView()。
直接的方法是在添加或切换片段时使用setMaxLifeCycle和FragmentTransaction,然后
setMaxLifecycle(fragment, Lifecycle.State.STARTED);
相当于
setUserVisibleHint(false);
和
setMaxLifecycle(fragment, Lifecycle.State.RESUMED);
相当于
setUserVisibleHint(true);
然后再次监听 Fragment 的 onResume() 回调
override fun onPrimaryNavigationFragmentChanged(isPrimaryNavigationFragment: Boolean) {
super.onPrimaryNavigationFragmentChanged(isPrimaryNavigationFragment)
if (isPrimaryNavigationFragment) {
// Your fragment is shown
} else {
// Your fragment is hidden
}
}
After AndroidX setUserVisibleHint is deprecated as a replacement
we can use the setMenuVisibility Method.
override fun setMenuVisibility(menuVisible: Boolean) {
super.setMenuVisibility(menuVisible)
}
在我的应用程序中,我有 BottomNavBar
,我希望在单击此 BottomNavBar
的项目时显示 fragments
!
为了将此 fragments
设置为 BottomNavBar
,我使用了 NavigationGraph
组件!
我想对其中一个 fragment
使用 setUserVisibleHint
方法,但是当显示此 fragment
时不调用 setUserVisibleHint
!
我的 Activity 代码 用于设置 fragments
到 BottomNavBar
项:
class HomeActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupNavigation()
}
private fun setupNavigation() {
val navController = Navigation.findNavController(this, R.id.homePage_fragmentNavHost)
NavigationUI.setupWithNavController(homePage_bottomNavBar, navController)
}
override fun onSupportNavigateUp() = Navigation.findNavController(this, R.id.homePage_fragmentNavHost).navigateUp()
}
我的片段代码:
class HomeDashboardFragment : Fragment(){
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home_dashboard, container, false)
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
Handler().postDelayed({ requireContext().toast("Show") }, 500)
}
}
}
为什么不把 setUserVisibleHint
变成 fragment
?
在输入此代码之前,您了解片段生命周期
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
// post your code
}
}
override fun onStart() {
super.onStart()
userVisibleHint = true
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser){
if (NetworkUtils.isConnected(getActivity())) {
callYourApi();
}
}
}
使用 BottomSheetBehavior https://developer.android.com/reference/android/support/design/widget/BottomSheetBehavior 进行此类实施。您也可以使用 BottomSheetDialogFragment。
要设置特定行为,请使用此代码,例如
bottomSheetBehavior.setPeekHeight(300);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
如果你正在使用 Navigation, this may not be the best way to achieve the behavior you desire. Navigation has an OnDestinationChangedListener Interface that receives a callback whenever NavController.getCurrentDestination 被调用。
幸运的是,您使用的是 Kotlin,并且在 HomeActivity 中,您也许可以通过以下方式逃脱:
navController.addOnDestinationChangedListener { _, destination, _ ->
Handler().postDelayed({ requireContext().toast("Show") }, 500)
}
你应该会得到想要的结果。
如果您是 Navigation 的新手,我会在 Github 上推荐 this codelab. It goes through some of the basics and can help get you started. For some of the more advanced concepts, you can checkout the NavigationAdvancedSample。
如果您想直接使用片段,使用生命周期方法 (onStart) 可能比 setUserVisibleHint() 更可靠。
由于 setUserVisibleHint(boolean aBoolean) 现已弃用,对于那些仍然想知道片段何时可见的人,您仍然可以使用
public FragmentTransaction setMaxLifecycle(Fragment fragment, Lifecycle.State state)
间接使用 FragmentPagerAdapter(或 FragmentStatePagerAdapter) 只需使用新的构造函数
MyFPagerAdapter(FragmentManager fm) {
super(fm ,FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
//...
}
请注意 FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 允许适配器在内部使用 setMaxLifecycle(通过 setPrimaryItem)而不是 setUserVisibleHint。 因此,在您的片段实现中,您将不再需要使用
setUserVisibleHint(boolean aBoolean)
但相反,onResume() 导致现在 onResume() 将仅针对可见片段调用。其余的仍然可以到达 onCreateView()。
直接的方法是在添加或切换片段时使用setMaxLifeCycle和FragmentTransaction,然后
setMaxLifecycle(fragment, Lifecycle.State.STARTED);
相当于
setUserVisibleHint(false);
和
setMaxLifecycle(fragment, Lifecycle.State.RESUMED);
相当于
setUserVisibleHint(true);
然后再次监听 Fragment 的 onResume() 回调
override fun onPrimaryNavigationFragmentChanged(isPrimaryNavigationFragment: Boolean) {
super.onPrimaryNavigationFragmentChanged(isPrimaryNavigationFragment)
if (isPrimaryNavigationFragment) {
// Your fragment is shown
} else {
// Your fragment is hidden
}
}
After AndroidX setUserVisibleHint is deprecated as a replacement we can use the setMenuVisibility Method.
override fun setMenuVisibility(menuVisible: Boolean) {
super.setMenuVisibility(menuVisible)
}