簡體   English   中英

帶有 Jetpack 導航組件的自定義工具欄

[英]Custom toolbar with Jetpack Navigation Component

我有一個問題。 我正是需要這個工具欄。

在此處輸入圖片說明

工具欄標題必須居中,向上按鈕的顏色必須與標題顏色不同。 例如,我可以使用這些代碼行實現居中標題。

     <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 時可以將工具欄中的文本居中還是我應該提出自己的自定義解決方案?

我的早期回答建議使用反射,但最好不要反對該框架。 因此,進一步搜索發現您可以按如下方式進行。

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

我像這樣將標題居中

 LiveData<NavController> controller = new NavigationExtensions().setupWithNavController(
  bottomNavigationView
  , navGraphIds
  , getSupportFragmentManager()
  , R.id.nav_host_fragment, getIntent()
);

//listener for destination change
final NavController.OnDestinationChangedListener listener = (controller1, destination, arguments) -> {
  //set text of your text view
  titleTextView.setText(destination.getLabel());
};

// Whenever the selected controller changes, setup the action bar.
controller.observe(this, navController -> {
  //to remove default title which is in left
  Objects.requireNonNull(getSupportActionBar()).setDisplayShowTitleEnabled(false);

  //remove listener if there is any
  Objects.requireNonNull(controller.getValue()).removeOnDestinationChangedListener(listener);
  //listener for getting current label and setting in text view
  controller.getValue().addOnDestinationChangedListener(listener);

  //setup with Actionbar
  NavigationUI.setupActionBarWithNavController(MainActivity.this, navController);
});

刪除工具欄中的當前標題並在我的文本視圖中設置當前標簽。

我遇到了同樣的問題,我能夠以這種方式創建一個標題文本居中的自定義工具欄。 如果您想使用自定義字體和大小,此方法可能會有所幫助。 我認為這可能會幫助某人。 首先,確保您使用的是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)

這是最終結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM