Persistent header fragment (disable animation) in Android TV (leanback)
Asked Answered
J

3

7

Anyone knows how to achieve the question in the title? The objective is to avoid the animation that results in the Headers bar disappearing as the Leanback app zooms in on the Row Item once a Header has been clicked.

setHeadersState of BrowseSupportFragment doesn't help. Perhaps something to do with hijacking startHeadersTransitionInternal during OnHeaderClickedListener? If so, any idea how to correctly implement it?

Jordison answered 8/1, 2019 at 23:55 Comment(1)
Same as #51978247 (unanswered)Jordison
A
4

So the problem with this one is that the transition is handled by the method startHeadersTransitionInternal which is package private. Because of this, you can't override it in most situations. However, since it's only package private and not private private, there's a little hack around this that you can do.

First, make a package in your app with the same package name as BrowseSupportFragment. Then make a class in that package that extends BrowseSupportFragment and override the offending method with no implementation. That'd look something like this:

package android.support.v17.leanback.app; // Different for AndroidX

public class HackyBrowseSupportFragment extends BrowseSupportFragment {

    @Override
    void startHeadersTransitionInternal(boolean withHeaders) {
        // Do nothing. This avoids the transition.
    }
}

Then, instead of extending BrowseSupportFragment, you'd extend HackyBrowseSupportFragment.

One thing to note that I found with this is that the back button will no longer refocus the headers from one of the rows, so you'll have to do that manually. Other than that, seems to work just fine.

Agnew answered 20/4, 2019 at 4:21 Comment(3)
I have tried the above solution and its stop an animation of HeaderFragment, But its not getting focus while going back to HeaderItem from ListRow item. Any suggestion how to handle this caseNagano
@Nagano I did note in my solution that this would be a problem. I haven't looked too deeply into the problem but if you post a question and link it here then I'll take a look when I have some time.Agnew
Thanks @MichaelCeley, for quick response. here is the link - #60964364Nagano
A
2

Following @MichaelCeley 's response and based on the original startHeadersTransitionInternal method from BrowseSupportFragment, this implementation that keeps the backstack and listeners works, too.

@Override
void startHeadersTransitionInternal(final boolean withHeaders) {
    if (getFragmentManager().isDestroyed()) {
        return;
    }
    if (!isHeadersDataReady()) {
        return;
    }
    new Runnable() {
        @Override
        public void run() {
            if (mBrowseTransitionListener != null) {
                mBrowseTransitionListener.onHeadersTransitionStart(withHeaders);
            }
            if (mHeadersBackStackEnabled) {
                if (!withHeaders) {
                    getFragmentManager().beginTransaction()
                            .addToBackStack(mWithHeadersBackStackName).commit();
                } else {
                    int index = mBackStackChangedListener.mIndexOfHeadersBackStack;
                    if (index >= 0) {
                        FragmentManager.BackStackEntry entry = getFragmentManager().getBackStackEntryAt(index);
                        getFragmentManager().popBackStackImmediate(entry.getId(),
                                FragmentManager.POP_BACK_STACK_INCLUSIVE);
                    }
                }
            }
        }
    }.run();
}
Apelles answered 7/8, 2020 at 15:18 Comment(0)
P
0

What you can do to "disable" the slide in/out animation is override the BrowseSupportFragment.onCreateView() function and assign the value of mSceneWithHeaders to mSceneWithoutHeaders. This way, the transition will still run, but it won't change the layout, keeping the correct focus behavior.

For that, you still need to override the package of your fragment. The code should look like the following:

@file:Suppress("PackageDirectoryMismatch")

package androidx.leanback.app;


class MyBrowseSupportFragment : BrowseSupportFragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mSceneWithoutHeaders = mSceneWithHeaders
    }
}
Polyester answered 16/3, 2023 at 12:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.