如何在Android的Fragment中使用setUserVisibleHint

时间:2019-05-14 12:31:06

标签: android android-fragments kotlin fragment

在我的应用程序中,我有BottomNavBar,并且我想在点击此fragments的项目时显示BottomNavBar
为了将这个fragmentsBottomNavBar一起使用,我使用了NavigationGraph组件!

我想对其中一个setUserVisibleHint使用 fragment 方法,但是在显示此fragment时不要调用 setUserVisibleHint

我的活动代码,用于将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

7 个答案:

答案 0 :(得分:1)

在放置此代码之前,您应该了解片段生命周期

 override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isVisibleToUser) {
           // post your code
        }
    }

    override fun onStart() {
        super.onStart()
        userVisibleHint = true
    }

快乐编码。...

答案 1 :(得分:1)

不推荐使用AndroidX setUserVisibleHint 作为替换项 我们可以使用 setMenuVisibility 方法。

  override fun setMenuVisibility(menuVisible: Boolean) {
        super.setMenuVisibility(menuVisible)
  }

答案 2 :(得分:0)

 @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser){
        if (NetworkUtils.isConnected(getActivity())) {
            callYourApi();
        } 
    }
}

答案 3 :(得分:0)

使用BottomSheetBehavior https://developer.android.com/reference/android/support/design/widget/BottomSheetBehavior进行此类实现。您也可以使用BottomSheetDialogFragment。

要设置特定行为,请使用以下代码,例如

bottomSheetBehavior.setPeekHeight(300);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

答案 4 :(得分:0)

如果您使用的是Navigation,则这可能不是实现所需行为的最佳方法。导航具有一个OnDestinationChangedListener接口,该接口在每次调用NavController.getCurrentDestination时都会接收回调。

幸运的是,您正在使用Kotlin,并且在HomeActivity中,您可能可以摆脱类似的情况:

navController.addOnDestinationChangedListener { _, destination, _ ->
    Handler().postDelayed({ requireContext().toast("Show") }, 500)
}

您应该得到想要的结果。

如果您不熟悉导航,建议您使用this代码实验室。它涵盖了一些基础知识,可以帮助您入门。对于某些更高级的概念,您可以在Github上检出NavigationAdvancedSample

如果您仍然想直接使用Fragments,则在setUserVisibleHint()上使用生命周期方法(onStart)可能会更可靠。

答案 5 :(得分:0)

现在已弃用setUserVisibleHint(boolean aBoolean),对于仍想知道何时可见片段的用户,仍可以使用

 public FragmentTransaction setMaxLifecycle(Fragment fragment, Lifecycle.State state)

通过FragmentPagerAdapter(或FragmentStatePagerAdapter)间接 只需使用新的Constructor

MyFPagerAdapter(FragmentManager fm) {
        super(fm ,FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
       //...
}

请注意 FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT允许适配器在内部(通过setPrimaryItem)使用setMaxLifecycle而不是setUserVisibleHint。 因此,在片段的实现中,您将不再需要使用

setUserVisibleHint(boolean aBoolean)

,但是,onResume()导致现在仅针对可见片段调用onResume()。其余的仍然可以访问onCreateView()。

直接方法是在添加或切换片段时使用带​​有FragmentTransaction的setMaxLifeCycle,然后

setMaxLifecycle(fragment, Lifecycle.State.STARTED);

等价

setUserVisibleHint(false);

setMaxLifecycle(fragment, Lifecycle.State.RESUMED);

等同于

setUserVisibleHint(true);

然后再次使用Fragment的onResume()回调

答案 6 :(得分:0)

override fun onPrimaryNavigationFragmentChanged(isPrimaryNavigationFragment: Boolean) {
        super.onPrimaryNavigationFragmentChanged(isPrimaryNavigationFragment)
        if (isPrimaryNavigationFragment) {
            // Your fragment is shown
        } else {
            // Your fragment is hidden
        }
    }