3

I have an activity and a few fragments in it, and I have an action bar that I need to be visible all the time except for the case when I open MyTestFragment, so when I open this fragment I need my action bar to be hidden.

As my Activity is AppCompatActivity, I tried to call this method (from Activity) in order to hide an actionBar

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.main_activity)

        supportActionBar?.hide()
...

and it works, however, I need to make this call from fragment, so I do it like this

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        (activity as AppCompatActivity).supportActionBar!!.hide()

    }

and the result is

enter image description here

The action bar became kind of invisible instead of gone (you see this gray pass right under the clock)

What am I missing here?

UPD

I would like to add explanation to the problem, in order to illustrate this I did such code:

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.main_activity)
        
        Thread {
            Thread.sleep(8000)

            mainExecutor.execute {
                supportActionBar?.show()      <---- 2
            }
        }.start()

        Thread {
            Thread.sleep(12000)

            mainExecutor.execute {
                supportActionBar?.hide()     <---- 3
            }
        }.start()

        supportActionBar?.hide()          <---- 1
...

What is happening here is - the method marked 1 is invoking first and the actionbar hides as expected. The next method #2 invokes show() for the action bar and the action bar appears as expected, however, when it comes to method #3 and tries to hide the actionbar again the bug is here. Instead of hiding the actionbar it kind of makes it invisible and you can see a grey line (like on the screenshot).

So, looks like it is possible to hide the actionbar only immediately in OnCreate() method if you try to do it after you will see a grey line instead of the actionbar.

UPD

My MainActivity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/awl_application_drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/main_activity_layout_bg_color"
    tools:openDrawer="end">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <application.widget.toolbar.BondToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <FrameLayout
            android:id="@+id/errorViewContainer"
            android:layout_below="@id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

        <FrameLayout
            android:id="@+id/fragment_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/toolbar_layout"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            style="@style/AppTabLayout"
            android:layout_width="match_parent"
            android:layout_height="@dimen/bottom_nav_tab_height"
            android:background="@color/deprecated_palette_FF000000"
            android:elevation="6dp"
            android:fillViewport="true"
            android:padding="0dp"
            app:tabPaddingBottom="0dp"
            app:tabPaddingEnd="0dp"
            app:tabPaddingStart="0dp"
            app:tabPaddingTop="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:tabMinWidth="@dimen/bottom_nav_tab_min_width" />

        <CustomView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:visibility="invisible"
            app:layout_constraintBottom_toTopOf="@id/tab_layout"
            app:layout_constraintTop_toTopOf="parent"
            app:theme="@style/ThemeOverlay.AppCompat.Light" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <FrameLayout
        android:id="@+id/navigation_view_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:layout_marginTop="?android:attr/actionBarSize" />

</androidx.drawerlayout.widget.DrawerLayout>

Sirop4ik
  • 4,543
  • 2
  • 54
  • 121
  • Try this https://stackoverflow.com/a/73293015/15754377 – Vivek Gupta Aug 29 '22 at 10:26
  • @VivekGupta this would be ok in case if each fragment has its own action bar implementation (or BaseFragment), however, in my case action bar is part of the Activity – Sirop4ik Aug 29 '22 at 11:46
  • Nope, actionBar is in activity and BaseFragment is calling activity's method to hide actionBar Or Fab. By making a BaseFragment, we remove boilerplate code for each fragment – Vivek Gupta Aug 29 '22 at 12:35
  • @VivekGupta, my bad, you are right, however, what is a diff with my approach `(activity as AppCompatActivity).supportActionBar!!.hide()` (described in the question) where actually I am trying to do the same I just call `hide()` method directly from the fragment... – Sirop4ik Aug 29 '22 at 12:43
  • @Sirop4ik can you show your activity layout.xml? – sergpetrov Aug 30 '22 at 08:48

3 Answers3

2

When navigating to TestFragment, do supportActionBar?.hide() from Activity. Do supportActionBar?.show() from Activity when navigating to the Fragment where the ActionBar should be visible.

1

I've done something like this in a project but on an Activity but you can do the similar thing on Fragments also

Here I've created a method called "setupToolbar" which I call from onCreate right after setContentView(R.layout.___)

private fun setupToolbar() {
    toolbar.title = ""
    setSupportActionBar(toolbar)
    toolbar.navigationIcon = ContextCompat.getDrawable(this, R.drawable.arrow_back_white_24)
    toolbar.setNavigationOnClickListener {
        finish()
    }
    supportActionBar?.hide()
}

Then I added a gesture listener and observing SingleTap

private var gestureListener: GestureDetector.SimpleOnGestureListener =
    object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapUp(e: MotionEvent?): Boolean {
            if (toolbar.visibility == View.VISIBLE) {
                supportActionBar?.hide()
                return true
            } else {
                supportActionBar?.show()
            }
            return false
        }
    }
MabrurChowdhury
  • 375
  • 1
  • 3
  • 13
0

There might be two options here.

  • Defining topbar in each fragment layout and don't include in specific fragment where not required, rather than including in activity.

OR

  • Define some NO ACTION BAR styles in style.xml, then set/unset it in java/kotlin code, when navigating to/from some fragment.

In styles.xml :

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

In kotlin/java code from activity:

Call setTheme method with above defined style and then call recreate()