如何通过操作栏中的后退按钮转到上一个片段? (科特林)

     2023-04-19     272

关键词:

【中文标题】如何通过操作栏中的后退按钮转到上一个片段? (科特林)【英文标题】:How to go to the previous fragment by back button in action bar? (Kotlin) 【发布时间】:2020-10-18 17:16:57 【问题描述】:

我有两个片段,我想使用操作栏中的后退按钮在它们之间创建交互。理想情况下,我希望保存前一个片段的状态。 我只能找到活动的信息。

对于我找到的片段

private fun setupBackButton() 
        if (activity is AppCompatActivity) 
            (activity as AppCompatActivity?)?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
        
    

但它只显示返回按钮,点击没有任何反应。

编辑

在第一个片段中,我将第二个片段称为:

val fragment = UserContentFragment()
fragment.setUser(item.user)

if (fragmentManager != null) 
    fragmentManager!!
      .beginTransaction()
      .replace(R.id.main_layout, fragment)
      .addToBackStack(null)
      .commit()

这是我的UserContentFragment第二个片段:

class UserContentFragment : Fragment() 

    private lateinit var user: SearchUser

    fun setUser(user: SearchUser) 
        this.user = user
    

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
        val root = inflater.inflate(R.layout.fragment_user_content, container, false)

        val userImage = root.findViewById(R.id.user_img) as ImageView
        if (context != null) 
            Glide.with(context!!)
                .load(user.profile_pic_url)
                .circleCrop()
                .into(userImage)
        

        val userName: TextView = root.findViewById(R.id.user_name)
        userName.text = user.full_name

        val toolbar: Toolbar = root.findViewById(R.id.toolbar)
        toolbar.setNavigationOnClickListener  requireActivity().onBackPressed() 

        setupBackButton()
        
        return root
    

    private fun setupBackButton() 
        if (activity is AppCompatActivity) 
            (activity as AppCompatActivity?)?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
        
    

这是它的 .xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:background="@color/colorBlack">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_
        android:layout_ />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/user_title"
        android:layout_
        android:layout_>

        <ImageView
            android:id="@+id/user_img"
            android:layout_
            android:layout_
            android:layout_marginStart="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="ContentDescription" />

        <TextView
            android:id="@+id/user_name"
            android:layout_
            android:layout_
            android:layout_marginStart="32dp"
            android:layout_marginEnd="16dp"
            android:textColor="@color/colorWhite"
            android:textSize="22sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/user_img"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>

【问题讨论】:

【参考方案1】:

为了在您点击 Home/up 按钮时得到响应,这里有几个选项可以解决这个问题:

第一个选项

在您显示 Home/UP 按钮的片段中,覆盖 onOptionsItemSelected() 方法并调用活动的 onBackPressed() 作为主页按钮 ID

override fun onOptionsItemSelected(item: MenuItem): Boolean 
    // Handle presses on the action bar menu items
    when (item.itemId) 
        android.R.id.home -> 
            activity?.onBackPressed()
            return true
        
    
    return super.onOptionsItemSelected(item)

旁注:

不要在ActionBar 上显示主页/向上按钮,而是使用下面的方法为每个片段设置布尔值,您需要使用以下方法显示主页按钮:

private fun setupBackButton() 
    if (activity is AppCompatActivity) 
        (activity as AppCompatActivity?)?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
    

您可以改为在活动的onCreate() 方法中使用AppBarConfiguration 设置ActionBar,如下所示:

private lateinit var appBarConfiguration: AppBarConfiguration

override fun onCreate(savedInstanceState: Bundle?) 

    val host: NavHostFragment = supportFragmentManager
            .findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return

    val navController = host.navController

    appBarConfiguration = AppBarConfiguration(
            setOf(R.id.second_fragment, R.id.third_fragment)) //  IDs of fragments you want without the ActionBar home/up button

    setupActionBarWithNavController(navController, appBarConfiguration)


通过这样做,向上按钮将显示在所有片段中,但R.id.second_fragment, R.id.third_fragment 并且您不再需要将setDisplayHomeAsUpEnabled() 设置为每个单独的片段以显示主页/向上按钮。但是你仍然需要覆盖上面提到的onOptionsItemSelected

第二个选项

这比第一个选项更整洁。首先,您必须实现上述侧节点以允许NavController 自动控制/配置ActionBar

因此,过去的旁注是此选项的必填部分。

然后在允许NavigationUI支持正确ActionBar向上导航的活动中覆盖onSupportNavigateUp()

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

然后在活动中覆盖 onOptionsItemSelected() 以使导航 UI 处理 OptionsMenu/ActionBar 项目选择

override fun onOptionsItemSelected(item: MenuItem): Boolean 
    return item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment)) 
            || super.onOptionsItemSelected(item)

我会说选项 2 比选项 1 更简洁,因为您将所有代码写在一个地方(活动)而不接触片段,并且它会自动配置所有片段,无需手动 setDisplayHomeAsUpEnabled()activity.onBackPressed()对于您希望 Home/Up 按钮显示的各个片段。

【讨论】:

感谢您的回答!我不完全理解如何识别R.id.my_nav_host_fragment。我应该在哪里做?对于第二个选项,它将是主要活动,而不是片段,对吧? 嗨@MaxB,它只是您的活动布局中占位符片段的ID,它指向您的具有app:navGraph属性的navGraph【参考方案2】:

在带有导航的 Kotlin 片段中。

首先,在 onCreate 中添加setHasOptionsMenu(true)

override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)

然后覆盖onOptionsItemSelected,当R.id.home你可以控制BACK按钮

override fun onOptionsItemSelected(item: MenuItem): Boolean 
        when (item.getItemId()) 
            android.R.id.home ->
                findNavController().navigate(R.id.action_FragmentTwo_to_FragmentOne)
        
        return true

【讨论】:

【参考方案3】:
class StartActivity : FragmentActivity() 
    /**
     * The pager widget, which handles animation and allows swiping horizontally to access previous
     * and next wizard steps.
     */
    private lateinit var mPager: ViewPager

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.start_activity)

        val loginButton = findViewById<Button>(R.id.login_button)
        loginButton.setOnClickListener 
            this.didTapLoginButton()
        
    

    private fun didTapLoginButton() 
        val i = Intent(this, LoginActivity::class.java)
        startActivity(i)
    


class LoginActivity : AppCompatActivity() 
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.login_activity)

        //actionbar
        val actionbar = supportActionBar
        //set actionbar title
        actionbar!!.title = "New Activity"
        //set back button
        actionbar.setDisplayHomeAsUpEnabled(true)
        actionbar.setDisplayHomeAsUpEnabled(true)
    

    override fun onSupportNavigateUp(): Boolean 
        onBackPressed()
        return true
    
    // it is important function, you need to write this function in which class/activity you want to show back arrow
    override fun onOptionsItemSelected(item: MenuItem): Boolean 
        return super.onOptionsItemSelected(item)
    

【讨论】:

【参考方案4】:

您需要将点击侦听器附加到工具栏,例如:

toolbar.setNavigationOnClickListener  requireActivity().onBackPressed() 

【讨论】:

感谢您的回答。我在 xml 中创建了 Toolbar,将其附加在 onCreateView 中并使用了您的代码行。但不幸的是,一切都没有改变。我是否必须更改我的 func setupBackButton 中的某些内容? 能否在问题中添加更多信息和代码,很容易找出问题所在。 编辑过的帖子,可以看【参考方案5】:

在 NavigationClickListener 中添加它。

FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() > 0) 
    Log.i("MainActivity", "popping backstack");
    fm.popBackStack();
 else 
    Log.i("MainActivity", "nothing on backstack, calling super");
    super.onBackPressed();  

【讨论】:

感谢您的帮助。但它仍然不起作用。我认为我的问题出在工具栏声明中,因为您指定的日志均未打印。

以编程方式使后退按钮转到上一个视图

...UIBarButtonItem,并希望以编程方式设置转到前一个控制器的操作(在我的例子中,我以前的视图是一个UITableViewController)。下面是我目前用来制作条形按钮项的代码,尽管按钮还没有转到上一个视图 查看详情

如何摆脱Android应用栏中的后退按钮

】如何摆脱Android应用栏中的后退按钮【英文标题】:HowtogetridofbackbuttoninAndroidappbar【发布时间】:2021-08-0611:02:39【问题描述】:我有一个简单的活动,其中包含用户可以在多个片段之间切换。只有在显示第一个Fragment时,应用栏... 查看详情

后退按钮关闭应用程序而不是转到上一个片段 android 导航组件

】后退按钮关闭应用程序而不是转到上一个片段android导航组件【英文标题】:Backbuttonclosesappinsteadofgoingtopreviousfragmentandroidnavigationcomponent【发布时间】:2020-03-2311:52:45【问题描述】:在创建一个非常简单的示例应用程序时,我无... 查看详情

无法删除 sliver 应用栏中的后退按钮

...一个页面中,该页面反过来嵌套在底部栏导航中。我应该如何移除后退按钮Slive 查看详情

如何使用活动显示的片段转到上一个活动

】如何使用活动显示的片段转到上一个活动【英文标题】:HowcanIgotopreviousactivitywiththefragmenttheactivitywasshowing【发布时间】:2014-10-2023:28:37【问题描述】:我有两个活动,活动A和活动B。现在活动A有3个Fragments,其中一个启动活动B... 查看详情

如何通过按返回返回到上一个片段?

】如何通过按返回返回到上一个片段?【英文标题】:Howtoreturntopreviousfragmentbypressingback?【发布时间】:2020-06-0803:09:21【问题描述】:我正在使用导航抽屉导航到许多不同的片段。在少数情况下,一些片段被放置在其他片段之上... 查看详情

从 SwiftUI 中的导航栏中删除后退按钮文本

...而不会导致应用程序崩溃,但现在我遇到了下一个问题。如何摆脱navbaritem中的“后退”文本?我通过像这样在Sc 查看详情

使用操作栏中的图标按钮导航到另一个活动(代码片段)

我有一个问题,如何在我的活动中编码实际实现onClick事件从该活动到我的主页。为了实现onclick转到另一个活动,我应该添加到mainactivity中?searchmenu.xml:<?xmlversion="1.0"encoding="utf-8"?><menuxmlns:android="http://schemas.android.com/apk/re... 查看详情

如何覆盖android中的操作栏后退按钮?

】如何覆盖android中的操作栏后退按钮?【英文标题】:howtooverrideactionbarbackbuttoninandroid?【发布时间】:2013-01-0410:55:07【问题描述】:我想在操作栏中自定义活动返回按钮,而不是在硬键返回按钮中。我已经覆盖了onBackPressed()方... 查看详情

浏览器后退按钮跳转到最后一个位置(如 maps.google.com)

...【问题描述】:我要做的是转到Google地图中的某个位置(通过搜索或仅通过拖动地图)。现在我在地址栏中输入另一个URL,然后按回车键转到该站点。当我使用浏览器返回按钮时,谷歌地图会自动切换回我 查看详情

如何更改 iOS 13 导航栏中的后退按钮图像?

】如何更改iOS13导航栏中的后退按钮图像?【英文标题】:HowcanIchangethebackbuttonimageinthenavigationbarforiOS13?【发布时间】:2019-09-1108:03:35【问题描述】:Ontheright,thefirsttimeandontheleft,alltheothertimes大家好,我是新人,所以我希望这就是... 查看详情

当应用程序处于固定模式并且我注销时,会显示登录活动。但是,如果我点击后退按钮,它会转到上一个活动

...模式并且我注销时,会显示登录活动。但是,如果我点击后退按钮,它会转到上一个活动【英文标题】:WhentheappisinpinnedmodeandIlogout,thesigninactivityisshown.But,ifIclickbackbutton,itgoestopreviousactivity【发布时间】:2022-01-0622:18:50【问题描述... 查看详情

使用操作栏中的图标按钮导航到另一个活动

...ractivity【发布时间】:2019-08-3010:02:07【问题描述】:关于如何在我的活动中编写代码以实际实现从该活动转到我的主页的onClick事件,我遇到了问题。我应该在我的mainactivity中添加什么来实现onclick以转到另一个Activity?搜索菜单.x... 查看详情

如何更改导航栏中的后退按钮颜色?

】如何更改导航栏中的后退按钮颜色?【英文标题】:Howtochangebackbuttoncolorinnavbar?【发布时间】:2016-04-2304:49:19【问题描述】:有没有办法在带有导航控制器的应用中仅更改左侧后退按钮的颜色?有很多改变导航栏颜色的例子,... 查看详情

Android - 标题栏中的后退按钮

...按钮,但对于我正在制作的应用程序,它不会这样做那。如何让该图标带您回到上一个屏幕?【问题讨论】:在此处的OnCreate示例中尝试getSupportAction 查看详情

在导航栏中的默认“后退”按钮附近添加按钮

...012-09-2913:50:00【问题描述】:我正在构建并使用webView\'s。通过选择一些选项卡,我还显示了一些视图非webView。我的导航控制器有问题我在我的Ncontrolls类中设置我的navigationController有下一个代码:-( 查看详情

IOS - 垂直对齐导航栏中的后退按钮

...垂直对齐到中间。我已经完成了导航栏标题。但我不知道如何将后退按钮垂直对齐到中间。谢谢。【问题讨论】:查看我的答案:***.com/questio 查看详情

如何在 uiviewcontroller 的导航栏中添加后退按钮?

】如何在uiviewcontroller的导航栏中添加后退按钮?【英文标题】:HowdoIaddabackbuttontoanavbarinauiviewcontroller?【发布时间】:2013-05-2916:34:21【问题描述】:我有一个带有uitabbarcontroller的应用程序,带有2个选项卡。第一个选项卡是uiviewcon... 查看详情