Android导航组件中的处理后退按钮

时间:2018-06-26 12:52:12

标签: android navigation fragment android-jetpack

我想知道如何使用导航控制器正确处理系统后退按钮动作。在我的应用程序中,我有两个片段(例如fragment1和fragment2),并且我在fragment1中有一个动作,目标是fragment2。除一件事情外,其他所有东西都运行良好-当用户在fragment2中按下系统后退按钮时,我想显示一个对话框(例如,使用DialogFragment)以确认退出。实施此行为的最佳方法是什么?如果我在主机片段中使用app:defaultNavHost="true",则它会自动返回并忽略我的规则。另外,此组件是做什么用的?

enter image description here

我应该使用“流行于”吗?

28 个答案:

答案 0 :(得分:19)

  

2019年4月25日最新更新

新版本androidx.activity ver. 1.0.0-alpha07带来了一些变化

Android官方指南中的更多说明:Provide custom back navigation

示例:

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback will only be called when MyFragment is at least Started.
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public boolean handleOnBackPressed() {
                // Handle the back button event
            }
        });
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}
  

旧更新

UPD:2019年4月3日

现在将其简化。更多信息here

示例:

requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), this);

@Override
public boolean handleOnBackPressed() {
    //Do your job here
    //use next line if you just need navigate up
    //NavHostFragment.findNavController(this).navigateUp(); 
    //Log.e(getClass().getSimpleName(), "handleOnBackPressed");
    return true;
    }

已弃用(自1.0.0-alpha06版本开始 2019年4月3日):

this起,只需在您的片段中使用JetPack实现OnBackPressedCallback即可实现 并将其添加到活动中: getActivity().addOnBackPressedCallback(getViewLifecycleOwner(),this);

您的片段应如下所示:

public MyFragment extends Fragment implements OnBackPressedCallback {

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        getActivity().addOnBackPressedCallback(getViewLifecycleOwner(),this);
}

    @Override
    public boolean handleOnBackPressed() {
        //Do your job here
        //use next line if you just need navigate up
        //NavHostFragment.findNavController(this).navigateUp(); 
        //Log.e(getClass().getSimpleName(), "handleOnBackPressed");
        return true;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        getActivity().removeOnBackPressedCallback(this);
    }
}

UPD: 您的活动应扩展AppCompatActivityFragmentActivity并在Gradle文件中进行:

 implementation 'androidx.appcompat:appcompat:{lastVersion}'

答案 1 :(得分:12)

所以,我创建了一个界面

public interface OnBackPressedListener {
    void onBackPressed();
}

并由需要处理后退按钮的所有片段实现。在主要活动中,我重写了onBackPressed()方法:

@Override
public void onBackPressed() {
    final Fragment currentFragment = mNavHostFragment.getChildFragmentManager().getFragments().get(0);
    final NavController controller = Navigation.findNavController(this, R.id.nav_host_fragment);
    if (currentFragment instanceof OnBackPressedListener)
        ((OnBackPressedListener) currentFragment).onBackPressed();
    else if (!controller.popBackStack())
        finish();

}

因此,如果我的导航主机的顶部片段实现了OnBackPressedListener接口,我将调用其onBackPressed()方法,而在其他地方,我只是弹出堆栈并在返回堆栈为空的情况下关闭应用程序。

答案 2 :(得分:4)

这是应该执行您想要的操作的解决方案,但是我认为这是一个糟糕的解决方案,因为它与Android导航组件的想法(让android处理导航)背道而驰。

覆盖活动中的“ onBackPressed”

override fun onBackPressed() {
    when(NavHostFragment.findNavController(nav_host_fragment).currentDestination.id) {
        R.id.fragment2-> {
            val dialog=AlertDialog.Builder(this).setMessage("Hello").setPositiveButton("Ok", DialogInterface.OnClickListener { dialogInterface, i ->
                finish()
            }).show()
        }
        else -> {
            super.onBackPressed()
        }
    }
} 

答案 3 :(得分:4)

我在这样的主要活动中写作

override fun onSupportNavigateUp(): Boolean {
        return findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
    }   

答案 4 :(得分:3)

聚会晚了一点,但是在导航组件1.0.0-alpha09的最新版本中,现在有了AppBarConfiguration.OnNavigateUpListener。

有关更多信息,请参阅以下链接: https://developer.android.com/reference/androidx/navigation/ui/AppBarConfiguration.OnNavigateUpListener https://developer.android.com/jetpack/docs/release-notes

答案 5 :(得分:2)

您可以使用OnBackPressedDispatcher提供自定义的后退导航

class MyFragment : Fragment() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // This callback will only be called when MyFragment is at least Started.
    val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
        // Handle the back button event
// and if you want to need navigate up
//NavHostFragment.findNavController(this).navigateUp()
    }

    // The callback can be enabled or disabled here or in the lambda
}
}

Android官方指南中的更多说明:https://developer.android.com/guide/navigation/navigation-custom-back

答案 6 :(得分:1)

推荐的方法对我有用,但是在更新了库implementation 'androidx.appcompat:appcompat:1.1.0'

之后

实施如下

 val onBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // Handle the back button event
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(this, onBackPressedCallback)

使用Kotlin

答案 7 :(得分:1)

如果您确实想专门处理后退按钮,那么您可以使用@Jurij Pitulja 回答。

但是,如果您想要弹出 SecondFragment(开始片段 FirstFragment)而不返回FirstFragment,那么您可以使用:

Navigation.findNavController(view).popBackStack()

来自SecondFragment。这样,当您从 FirstFragment 按下返回按钮时,您将弹出返回堆栈的 SecondFragmetn,并且不会返回到 SecondFragment

答案 8 :(得分:1)

只需添加这些行

<iframe width="560" height="315" src="https://www.youtube.com/embed/XQsmrfUbOP8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" class="slick-slide" data-slick-index="1" aria-hidden="true" style="width: 458px;"></iframe>

navController.popBackStack()只会弹出您的片段,如果这不是您的最后一个片段

答案 9 :(得分:1)

如果您也希望工具栏的“后退”按钮具有相同的行为,只需将其添加到活动中即可:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home) {
        getOnBackPressedDispatcher().onBackPressed();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

答案 10 :(得分:1)

如果您使用导航组件,请在onCreateView()方法中遵循以下代码(在此示例中,我只想通过此片段关闭我的应用程序)

 OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) {
        @Override
        public void handleOnBackPressed() {
            new AlertDialog.Builder(Objects.requireNonNull(getActivity()))
                    .setIcon(R.drawable.icon_01)
                    .setTitle(getResources().getString(R.string.close_app_title))
                    .setMessage(getResources().getString(R.string.close_app_message))
                    .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            getActivity().finish();
                        }
                    })
                    .setNegativeButton(R.string.no, null)
                    .show();
        }
    };
    requireActivity().getOnBackPressedDispatcher().addCallback(this, backPressedCallback);

答案 11 :(得分:1)

  

截至androidx.activity:activity:1.0.0-alpha08(2019年5月7日)

OnBackPressedDispatcher中检索Activity,并向其中添加一个OnBackPressedCallback。在科特林,您最终会拥有这种美丽:

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // add callback to dispatcher
        requireActivity().onBackPressedDispatcher.addCallback(this) {
            // handle back button event
        }
    }
}

docs提供了更新的解释以及与Java等效的解释。

答案 12 :(得分:0)

这是我的解决方法

对包含androidx.appcompat.app.AppCompatActivity片段的活动使用NavHostFragment

定义以下接口并将其实现在所有导航目标片段中

interface InterceptionInterface {

    fun onNavigationUp(): Boolean
    fun onBackPressed(): Boolean
}

在您的活动中覆盖onSupportNavigateUponBackPressed

override fun onSupportNavigateUp(): Boolean {
        return getCurrentNavDest().onNavigationUp() || navigation_host_fragment.findNavController().navigateUp()
}

override fun onBackPressed() {
        if (!getCurrentNavDest().onBackPressed()){
            super.onBackPressed()
        }
}

private fun getCurrentNavDest(): InterceptionInterface {
        val currentFragment = navigation_host_fragment.childFragmentManager.primaryNavigationFragment as InterceptionInterface
        return currentFragment
}

此解决方案的优势在于,导航目标片段无需担心监听器一分离就立即注销。

答案 13 :(得分:0)

ktx 版本:

fun Fragment.handleBackButtonEvent(
    onBackPressed: OnBackPressedCallback.() -> Unit
) {
    requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
        onBackPressed()
    }
}

您可以简单地在 Fragmnet 中使用它。

答案 14 :(得分:0)

使用导航组件 这对我有好处:

Navigation.findNavController(requireView()).popBackStack()

android documentation

答案 15 :(得分:0)

尝试一下。我认为这会对您有所帮助。

重写乐趣onBackPressed(){     什么时候(mNavController.getCurrentDestination()!!。getId()){

    R.id.loginFragment -> {
        onWarningAlertDialog(this, "Alert", "Do you want to close this application ?")
    }
    R.id.registerFragment -> {
        super.onBackPressed()
    }
}

}

  

onWarningAlertDialog(mainActivity:MainActivity,s:   字符串,s1:字符串){

    val dialogBuilder = AlertDialog.Builder(this)
    dialogBuilder.setMessage(/*""*/s1)
            .setCancelable(false)
            .setPositiveButton("Proceed", DialogInterface.OnClickListener { dialog, id ->
                finish()
            })
            .setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, id ->
                dialog.cancel()
            })

    // create dialog box
    val alert = dialogBuilder.create()
    // set title for alert dialog box
    alert.setTitle("AlertDialogExample")
    // show alert dialog
    alert.show()
}

答案 16 :(得分:0)

简单地说,在您的 onCreate()Fragment 方法中,在 super.onCreate(savedInstanceState) 之后使用此代码:

// This callback will only be called when MyFragment is at least Started.
val callback = requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
            // Handle the back button event
}

答案 17 :(得分:0)

我需要同时支持真正的后退按钮和工具栏后退按钮,并能够在两种情况下覆盖“后退”点击(显示对话框或其他东西)。我在活动和相应的布尔检查(在我的例子中是'onBackPressed')中做了一个额外的方法:

// Process hardware Back button
override fun onBackPressed() {
    if (canCloseActivity()) {
        super.onBackPressed()
    }
}

// Process toobar Back and Menu button
override fun onSupportNavigateUp(): Boolean {
    if (canCloseActivity()) {
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
    return false
}

// Do real check if has unfinished tasks, return false to override activity closing
private fun canCloseActivity(): Boolean {
    val currentFragment = navHostFragment.childFragmentManager.primaryNavigationFragment

    return when {
        currentFragment is MyFragment && currentFragment.onBackPressed() -> false

        drawerLayout.isOpen -> {
            drawerLayout.close()
            false
        }
        fullScreenPreviewLayout.visibility == View.VISIBLE -> {
            closeFullscreenPreview()
            false
        }
        else -> true
    }
}

答案 18 :(得分:0)

只需为片段创建扩展功能

fun Fragment.onBackPressedAction(action: () -> Boolean) {
    requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object :
        OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            this.isEnabled = action()
            if (!this.isEnabled) {
                requireActivity().onBackPressed()
            }
        }
    })
}

然后在片段中将代码放入onCreateView(操作必须返回false才能调用活动onBackPressed)

onBackPressedAction { //do something }

答案 19 :(得分:0)

我搜索了许多线程,但没有一个起作用。终于我找到了一个:

WindowGroup { ContentView() .onContinueUserActivity(<your_activity_type_here>) { userActivity in if let incomingURL = userActivity.webpageURL { print("Incoming URL is \(incomingURL)") let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in guard error == nil else{ print("Found an error! \(error!.localizedDescription)") return } if let dynamicLink = dynamicLink { self.handleIncomingDynamicLink(dynamicLink) } } } } }

MainActivity.java

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar mToolbar = findViewById(R.id.topAppBar); setSupportActionBar(mToolbar); } @Override public boolean onSupportNavigateUp() { navController.navigateUp(); return super.onSupportNavigateUp(); }

MyFragment.java

答案 20 :(得分:0)

如果您正在使用片段或将其添加到按钮单击侦听器中,请使用此选项。这对我有用。

requireActivity().onBackPressed()

在活动检测到用户按下返回键时调用。在调用android.app.Activity#onBackPressed()}的默认行为之前,可以让getOnBackPressedDispatcher()OnBackPressedDispatcher}处理后退按钮。

答案 21 :(得分:0)

如果您的应用程序使用BaseFragment,则可以将onBackPressedDispatcher添加到基本片段中。

//Make a BaseFragment for all your fragments
abstract class BaseFragment : Fragment() {

private lateinit var callback: OnBackPressedCallback

/**
 * SetBackButtonDispatcher in OnCreate
 */

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setBackButtonDispatcher()
}

/**
 * Adding BackButtonDispatcher callback to activity
 */
private fun setBackButtonDispatcher() {
    callback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            onBackPressed()
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(this, callback)
}

/**
 * Override this method into your fragment to handleBackButton
 */
  open fun onBackPressed() {
  }

}

通过扩展基本片段覆盖片段中的onBackPressed()

//How to use this into your fragment
class MyFragment() : BaseFragment(){

private lateinit var mView: View

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    mView = inflater.inflate(R.layout.fragment_my, container, false)
    return mView.rootView
}

override fun onBackPressed() {
    //Write your code here on back pressed.
}

}

答案 22 :(得分:0)

我尝试了Jurij Pitulja解决方案,但只是找不到getOnBackPressedDispatcher或addOnBackPressedCallback 还使用Kiryl Tkach的解决方案无法找到当前片段,所以这是我的:

interface OnBackPressedListener {
    fun onBackPressed(): Boolean
}

override fun onBackPressed() {
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
    val currentFragment = navHostFragment?.childFragmentManager!!.fragments[0]
    if (currentFragment !is OnBackPressedListener || !(currentFragment as OnBackPressedListener).onBackPressed()) super.onBackPressed()

通过这种方式,您可以分段确定活动是否应控制后按。

或者,您对所有活动都具有BaseActivity,可以像这样实现

override fun onBackPressed() {
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
    if (navHostFragment != null){
        val currentFragment = navHostFragment.childFragmentManager.fragments[0]
        if (currentFragment !is AuthContract.OnBackPressedListener ||
                !(currentFragment as AuthContract.OnBackPressedListener).onBackPressed()) super.onBackPressed()
    } else {
        super.onBackPressed()
    }
}

答案 23 :(得分:0)

2.1.0-alpha06

如果您只想在当前片段中处理backpress

requireActivity().onBackPressedDispatcher.addCallback(this@LoginFragment) {
    // handle back event
}

对于整个活动

requireActivity().onBackPressedDispatcher.addCallback() {
    // handle back event
}

答案 24 :(得分:0)

对于任何寻求Kotlin实现的人,请参见下文。

请注意,OnBackPressedCallback似乎仅用于为内置软件/硬件后退按钮提供自定义后退行为,而不是为操作栏/工具栏中的向上箭头提供后退箭头按钮/主页。为了也覆盖actionbar / toolbar后退按钮的行为,我提供了适用于我的解决方案。如果这是一个错误,或者您知道针对该情况的更好解决方案,请发表评论。

build.gradle

...
implementation "androidx.appcompat:appcompat:1.1.0-rc01"
implementation "androidx.navigation:navigation-fragment-ktx:2.0.0"
implementation "androidx.navigation:navigation-ui-ktx:2.0.0"
...

MainActivity.kt

...
import androidx.appcompat.app.AppCompatActivity
...

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        setContentView(R.layout.activity_main)

        ...

        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(navController.graph)

        // This line is only necessary if using the default action bar.
        setupActionBarWithNavController(navController, appBarConfiguration)

        // This remaining block is only necessary if using a Toolbar from your layout.
        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        toolbar.setupWithNavController(navController, appBarConfiguration)
        // This will handle back actions initiated by the the back arrow 
        // at the start of the toolbar.
        toolbar.setNavigationOnClickListener {
            // Handle the back button event and return to override 
            // the default behavior the same way as the OnBackPressedCallback.
            // TODO(reason: handle custom back behavior here if desired.)

            // If no custom behavior was handled perform the default action.
            navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
        }
    }

    /**
     * If using the default action bar this must be overridden.
     * This will handle back actions initiated by the the back arrow 
     * at the start of the action bar.
     */
    override fun onSupportNavigateUp(): Boolean {
        // Handle the back button event and return true to override 
        // the default behavior the same way as the OnBackPressedCallback.
        // TODO(reason: handle custom back behavior here if desired.)

        // If no custom behavior was handled perform the default action.
        val navController = findNavController(R.id.nav_host_fragment)
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
}

MyFragment.kt

...
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
...

class MyFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val onBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // Handle the back button event
            }
        }
        requireActivity().getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback)
    }
}

可以在https://developer.android.com/guide/navigation/navigation-custom-back

查看官方文档

答案 25 :(得分:0)

这是两行代码,可以监听片段中的回压, [TESTED and WORKING]

"/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activemodel-6.0.0/lib/active_model/attribute_methods.rb:431:in `method_missing'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema/member/instrumentation.rb:93:in `proxy_to_depth'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema/member/instrumentation.rb:85:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/field.rb:248:in `resolve'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:321:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema/middleware_chain.rb:49:in `invoke_core'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema/middleware_chain.rb:38:in `invoke'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:129:in `block in resolve_field'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:62:in `block in trace'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:76:in `call_tracers'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:62:in `trace'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:128:in `resolve_field'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:92:in `block in resolve_selection'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:85:in `each'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:85:in `resolve_selection'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:284:in `resolve_value'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:278:in `resolve_value'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:213:in `continue_resolve_field'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:184:in `continue_or_wait'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:263:in `block in resolve_value'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:256:in `each'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:256:in `resolve_value'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:278:in `resolve_value'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:213:in `continue_resolve_field'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:184:in `continue_or_wait'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:157:in `resolve_field'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:92:in `block in resolve_selection'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:85:in `each'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:85:in `resolve_selection'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:56:in `block in resolve_root_selection'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:62:in `block in trace'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:76:in `call_tracers'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:62:in `trace'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:49:in `resolve_root_selection'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/execute.rb:31:in `begin_query'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:112:in `begin_query'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:84:in `block in run_as_multiplex'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:83:in `map'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:83:in `run_as_multiplex'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:62:in `block (2 levels) in run_queries'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:186:in `block in instrument_and_analyze'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:29:in `block (2 levels) in apply_instrumenters'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:46:in `block (2 levels) in each_query_call_hooks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:41:in `each_query_call_hooks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:45:in `block in each_query_call_hooks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:72:in `call_hooks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:44:in `each_query_call_hooks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:27:in `block in apply_instrumenters'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:72:in `call_hooks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/instrumentation.rb:26:in `apply_instrumenters'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:174:in `instrument_and_analyze'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:61:in `block in run_queries'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:62:in `block in trace'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:76:in `call_tracers'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/tracing.rb:62:in `trace'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:59:in `run_queries'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/execution/multiplex.rb:49:in `run_all'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema.rb:392:in `block in multiplex'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema.rb:1279:in `with_definition_error_check'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema.rb:391:in `multiplex'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/graphql-1.9.12/lib/graphql/schema.rb:368:in `execute'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/2.6.0/forwardable.rb:230:in `execute'",
      "/private/var/sites/clients/army_of_bees/finsync/ap-backend-temp/app/controllers/graphql_controller.rb:12:in `execute'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/base.rb:196:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/rendering.rb:30:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/callbacks.rb:42:in `block in process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/callbacks.rb:41:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/rescue.rb:22:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:180:in `block in instrument'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:180:in `instrument'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/instrumentation.rb:32:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-6.0.0/lib/active_record/railties/controller_runtime.rb:27:in `process_action'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/base.rb:136:in `process'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionview-6.0.0/lib/action_view/rendering.rb:39:in `process'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal.rb:191:in `dispatch'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal.rb:252:in `dispatch'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:33:in `serve'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:49:in `block in serve'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:32:in `each'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:32:in `serve'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:837:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/etag.rb:25:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:38:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/http/content_security_policy.rb:18:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/cookies.rb:648:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-6.0.0/lib/active_record/migration.rb:567:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:101:in `run_callbacks'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/callbacks.rb:26:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/executor.rb:14:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/web-console-4.0.1/lib/web_console/middleware.rb:132:in `call_app'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/web-console-4.0.1/lib/web_console/middleware.rb:28:in `block in call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/web-console-4.0.1/lib/web_console/middleware.rb:17:in `catch'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/web-console-4.0.1/lib/web_console/middleware.rb:17:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:38:in `call_app'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:26:in `block in call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/tagged_logging.rb:80:in `block in tagged'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/tagged_logging.rb:28:in `tagged'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/tagged_logging.rb:80:in `tagged'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:26:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/quiet_assets.rb:13:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/request_id.rb:27:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/runtime.rb:22:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/executor.rb:14:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/static.rb:126:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/host_authorization.rb:83:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-cors-1.0.3/lib/rack/cors.rb:95:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.0/lib/rails/engine.rb:526:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/configuration.rb:227:in `call'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/server.rb:660:in `handle_request'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/server.rb:474:in `process_client'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/server.rb:334:in `block in run'",
      "/Users/xxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/thread_pool.rb:135:in `block in spawn_thread'"

答案 26 :(得分:0)

根据您的逻辑,如果您只想关闭当前片段,则必须传递viewLifecycleOwner,代码如下所示:

   requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            requireActivity().finish()
        }
    })

但是,如果您想关闭backPressed上的应用程序,无论是从哪个片段(可能您都不想要!),都不要传递viewLifecycleOwner。另外,如果要禁用后退按钮,请不要在handleOnBackPressed()内做任何事情,请参见下文:

 requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // do nothing it will disable the back button
        }
    })

答案 27 :(得分:-1)

我的意见 requireActivity()。onBackPressed()

requireActivity().onBackPressed()