15

I am trying to apply a specific theme on a Fragment. But for some reason it isn't happening. Can anyone point out mistakes in my code? Or better solutions?

Theme in styles.xml:

<!-- Theme for trans actionbar -->
<style name="TransTheme" parent="@style/AppTheme">
    <item name="android:actionBarStyle">@style/TransActionbar</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="actionBarStyle">@style/TransActionbar</item>
    <item name="windowActionBarOverlay">true</item>
</style>

Where @style/TransActionbar is:

<!-- Actionbar style for trans theme -->
<style name="TransActionbar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@color/first_trans_actionbar</item>
    <item name="background">@color/first_trans_actionbar</item>
</style>

How I want to apply the theme in my fragment in the onCreateView() method:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    //set theme
    final Context contextWrapper = new ContextThemeWrapper(getActivity(), R.style.TransTheme);
    LayoutInflater localInflater = inflater.cloneInContext(contextWrapper);
    contentView = localInflater.inflate(R.layout.fragment_movie_detail,
            container, false);
    return contentView:
}

For some reason the Fragment keeps the old theme..

Edit

So basically the question comes down to: How do you make an Actionbar transparent (and overlay mode) in just one fragment of an activity?

Tim Kranen
  • 4,202
  • 4
  • 26
  • 49

5 Answers5

8

I guess you want to be switching two (or more) Fragments within the same Activity, where each of them could require the ActionBar to either be overlaid or not, and have different backgrounds depending on the current Fragment.

Let's get the most important thing out of the way: as of yet, you can't change an Activity's theme at runtime.

You can still relatively easily accomplish what you are after by doing the following:

  1. Set the Activity theme to use an overlaid ActionBar.
  2. For those Fragments where you don't want the ActionBar to be overlaid, in their layout xml, set a top padding/margin equal to the ActionBar height. Ideally you would just reference the dimension resource for action bar height. For those Fragments where you want the ActionBar to overlay them, you should just have no padding/margin at the top of their layout xml.
  3. When you switch Fragments, change the background color of the ActionBar by calling getActionBar() (or getSupportActionBar if you are using the support library) and then .setBackgroundColor(Color.TRANSPARENT) or whatever color you need from the resources using getResources().getColor(R.colors.some_color). You could go for something more fancy than an abrupt switch, by animating the color change, but that's beyond the scope of this question.
  4. ...

  5. Profit!

EDIT: With Toolbar

If you want to use a Toolbar, the way to do it would be to put it in a separate layout xml that you <include> inside your Activity layout and give it some ID that you can reference through code. Make sure the Activity root layout is something with Z ordering, like RelativeLayout or FrameLayout, and position the toolbar <include> at the top of the Y axis (alignParentTop for RelativeLayout or layout_gravity="top" for FrameLayout), and put the Toolbar <include> after whatever layout you will be putting your Fragments inside, so that it will overlay them.

Inside the Activity onCreate do this:

Toolbar yourToolbar = (Toolbar) findViewById(R.id.your_toolbar);
yourToolbar.setBackgroundColor(<whatever color you want>);
setSupportActionBar(yourToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true/false);
actionBar.setDisplayHomeAsUpEnabled(true/false);
actionBar.setTitle(<whatever title you want>);

Otherwise, everything from my original answer still holds.

Community
  • 1
  • 1
Matej
  • 1,727
  • 2
  • 14
  • 22
6

thanks to Tomask https://stackoverflow.com/a/34686405/5502121 You can change attributes in Activity Theme of a fragment in runtime. Just overwrite them before fragment was inflated with your custom style and apply to a current Theme:

  1. Say, you have some attributes that you want to apply in your fragment, for example ripple color. Make a style with this attribute: in values/styles.xml

    <style name="colorControlHighlight_blue">
       <item name="colorControlHighlight">@color/main_blue_alpha26</item>
    </style>
    
  2. In your fragment before inflation in onCreateView()

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       getContext().getTheme().applyStyle(R.style.colorControlHighlight_blue, true); //blue ripple color
       View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
       return view;
    }
    

This style will work only for this fragment

Community
  • 1
  • 1
Kirill Karmazin
  • 6,256
  • 2
  • 54
  • 42
2

Here is your solution,

If you just want to apply style for specific Fragment of Activity then just add this lines before calling onCreateView() or onAttach() of the Fragment,

getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);

and set transparent status bar then set false to fitsSystemWindows property of your root layout,

android:fitsSystemWindows="false"

It works for me, hope it helps others.

Siddharth Sheth
  • 207
  • 2
  • 6
1

Looking at the changes here of the support library 22.1, I have seen that you can now apply a theme to any view (this also implies that it can be applied to a fragment). So I believe if you use the new appcompat and set the desired theme to your fragment's root view, it will do the trick.

But as I can see that you are trying to change the style of the ActionBar... I don't think this will work, because the ActionBar is created by your Activity and not your fragment, so it takes the style from your Activity. You would need to change the theme in your Activity in order to do that.

Bojan Kseneman
  • 15,488
  • 2
  • 54
  • 59
  • I am trying to change the theme of my activity in the onCreateView() method using the ContextWrapper. But it doesn't work. – Tim Kranen May 02 '15 at 11:43
  • Of course it won't. Activity is already created by the time onCreateView is called as it is the Activity who is creating the fragment (not the way arround) and you cannot change the theme once the activity is already created. You would need to reload the whole activity – Bojan Kseneman May 02 '15 at 11:46
  • http://stackoverflow.com/questions/23635824/change-activity-theme-deppending-on-fragment-in-use-android – Bojan Kseneman May 02 '15 at 11:48
  • 1
    I was under the impression that when you inflate the fragment with a ContextWrapper that wraps a new theme, it would inflate the fragment using that theme. What would be a different way to achieve this then? Basically, if I can make the Actionbar transparent as soon as that specific fragment loads, it would be fine. – Tim Kranen May 02 '15 at 11:48
  • You need it to be transparent or you would like to hide it completely? – Bojan Kseneman May 02 '15 at 11:54
  • I need it transparent. I've tried the other SO question but it doesn't seem to work either. I set my actionbar colors to the same values as in the question and change the window colors to the exact same color (Color.WHITE), and nothing happens. Plus I don't know if that would even work for transparent, because what color combination gives a transparent actionbar? – Tim Kranen May 02 '15 at 11:55
  • Every color gives a transparent color if you set it's opacity bits to 00 -> ActionBar bar = getActivity().getActionBar(); bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00000000"))); does this work? – Bojan Kseneman May 02 '15 at 11:59
  • Nope :/, it changes it to a black actionbar. Even if it would make the actionbar transparent, it wouldn't overlay the view. – Tim Kranen May 02 '15 at 12:02
  • Result it totally white, since the actionbar can't be transparent if it isn't in overlay mode I think... – Tim Kranen May 02 '15 at 12:08
  • You need to enable it. https://developer.android.com/training/basics/actionbar/overlaying.html If that doesn't help, you should be considering in using a Toolbar – Bojan Kseneman May 02 '15 at 12:11
  • The problem with overlay mode is.. It has to be applied in a theme.. I can't switch themes because the activity is already started.. – Tim Kranen May 02 '15 at 12:13
  • I know. Apply it to your activity and you will make it transparent when you need it to be (in your fragment) – Bojan Kseneman May 02 '15 at 12:18
  • But I don't want my actionbar to be in overlay mode in the entire activity.. Just in that one fragment. Oh and btw, thanks for your help! Really appreciate it! – Tim Kranen May 02 '15 at 12:21
-1

I think you should apply theme to your activity instead of fragment.

try setTheme(R.style.TransTheme); above setContentView();

Ketan Ahir
  • 6,678
  • 1
  • 23
  • 45
  • The problem here is that I don't want the Activity theme to be R.style.TransTheme, just one fragment inside that activity. – Tim Kranen May 02 '15 at 11:42