带有Jetpack导航组件的自定义工具栏

时间:2019-07-23 07:10:38

标签: android

我有一个问题。我正是需要这个工具栏。 https://ibb.co/rH212Z7(这是图片,我没有信誉可以在此处发布...) 工具栏的标题必须居中,向上按钮的颜色必须与标题的颜色不同。例如,我可以使用这些代码行实现居中标题。

     <androidx.appcompat.widget.Toolbar
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:theme="?attr/actionBarTheme"
            android:minHeight="?attr/actionBarSize"
            android:id="@+id/tb_main"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:gravity="center">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:id="@+id/tb_title_main"
                android:textColor="@color/black_80"
                android:textSize="20sp"
                />

    </androidx.appcompat.widget.Toolbar>

这是在我的MainActivity中

    val toolbar = binding.tbMain
    toolbar.tb_title_main.text = "Centered Text "
    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayShowTitleEnabled(false)

但是我想要带有Jetpack导航组件的设置工具栏,以便更好,更轻松地导航。当我在MainActivity中使用这些代码行设置工具栏时,就会发生这种情况。

    val navController = findNavController(R.id.nav_host_fragment)
    val toolbar = binding.tbMain
    setSupportActionBar(toolbar)
    val appBarConfiguration = 
    AppBarConfiguration(navController.graph)
    toolbar.setupWithNavController(navController, 
    appBarConfiguration)

https://ibb.co/6v8PPmR(另一张图片)

我花了将近4个小时。我尝试了很多解决方案,但没有任何效果。

因此,使用setupWithNavController时可以在工具栏中居中放置文本,还是我应该提出自己的自定义解决方案?

3 个答案:

答案 0 :(得分:0)

我的早期答案建议使用反射,但是最好不要使用框架。因此,在进一步搜索中,您可以按照以下步骤进行操作。

navHostFragment.navController.addOnDestinationChangedListener { _, destination, arguments ->
        binding.toolBarHome.setTitle(destination.label, titleTextView, arguments)
    }

setTitle是工具栏上的扩展功能,它将标题设置为空文本,并将标题设置为我们的自定义标题textview(titletextview)

扩展功能代码为

fun Toolbar.setTitle(label: CharSequence?, textView: TextView, arguments: Bundle?) {
if (label != null) {
    // Fill in the data pattern with the args to build a valid URI
    val title = StringBuffer()
    val fillInPattern = Pattern.compile("\\{(.+?)\\}")
    val matcher = fillInPattern.matcher(label)
    while (matcher.find()) {
        val argName = matcher.group(1)
        if (arguments != null && arguments.containsKey(argName)) {
            matcher.appendReplacement(title, "")
            title.append(arguments.get(argName).toString())
        } else {
            return //returning because the argument required is not found
        }
    }
    matcher.appendTail(title)
    setTitle("")
    textView.text = title
}

}

用于生成标题的代码来自androidx.navigation.ui.AbstractAppBarOnDestinationChangedListener

答案 1 :(得分:0)

我的标题居中这样

    controller.observe(this, new Observer<NavController>() {
  @Override
  public void onChanged(NavController navController) {
    //to remove default title which is in left
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    //listener for getting current label and setting in text view
    controller.getValue().addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
      @Override
      public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
        titleTextView.setText(destination.getLabel());
      }
    });
    //setup with Actionbar
    NavigationUI.setupActionBarWithNavController(MainActivity.this, navController);
  }
});

在工具栏中删除了当前标题,并在我的文本视图中设置了当前标签。

答案 2 :(得分:-1)

我遇到了同样的问题,因此能够创建一个自定义工具栏,其标题以文本为中心。如果要使用自定义字体和大小,此方法可能会有所帮助。我认为这可能对某人有帮助。首先,确保您使用NoActionBar主题并将windowActionBar设置为false。最后,在您的onViewCreated()中输入以下代码。

    (activity as AppCompatActivity).supportActionBar?.displayOptions =
        androidx.appcompat.app.ActionBar.DISPLAY_SHOW_CUSTOM

    // inflating your custom view
    // not quite sure what I should put for root so I have put "null". I am guessing we need to put the root view from `onViewCreated()` ?  
    val customView = layoutInflater.inflate(R.layout.custom_toolbar, null)

    // setting the whole layout match parent. For some reason, doing match parent from xml wasn't working 
    val layoutParams = androidx.appcompat.app.ActionBar.LayoutParams(
        androidx.appcompat.app.ActionBar.LayoutParams.MATCH_PARENT,
        androidx.appcompat.app.ActionBar.LayoutParams.MATCH_PARENT
    )

    // applying the customview  
    (activity as AppCompatActivity).supportActionBar?.setCustomView(customView, layoutParams)

    // in case you want to change the text yourself 
    toolBarTitle = customView.findViewById(R.id.customTitle)

Here's the final result