Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How change ActionBar colour when swiping between fragments (Material Design)?

I have an app i am doing, which has a FragmentPagerAdapter setup with 3 fragments to swipe between on the main page.

I have been trying to get it setup so as you swipe between fragments, the action bar changes color (fades in and out).

However i am not sure how i should do this. What method is called when you swipe between fragments? I.E where should i put the code to change the action bar colour?

And also how would i get the fade in and out effect (so it fades out one colour into another one)?

I would really appreciate anyones help.

Thanks in advance

Cheers Corey :)

like image 868
Fishingfon Avatar asked Nov 08 '14 01:11

Fishingfon


2 Answers

What method is called when you swipe between fragments?

You're looking for ViewPager.OnPageChangeListener.onPageScrolled. This will give you:

  • position Position index of the first page currently being displayed.
  • positionOffset Value from [0, 1) indicating the offset from the page at position.
  • positionOffsetPixels Value in pixels indicating the offset from position.

Although, you'll only need the first two parameters. What you'll want to do is bind a particular color to each of your fragments, retrieve both the current page and next page colors, then blend them together using the positionOffset ratio to create your new ActionBar background.

A useful algorithm for blending two colors based on a ratio can be found in Google's new SlidingTabStrip example. 0.0 will return the second color, 0.5 will return an even blend, and 1.0 will return the first color

static int blendColors(int from, int to, float ratio) {
    final float inverseRation = 1f - ratio;
    final float r = Color.red(from) * ratio + Color.red(to) * inverseRation;
    final float g = Color.green(from) * ratio + Color.green(to) * inverseRation;
    final float b = Color.blue(from) * ratio + Color.blue(to) * inverseRation;
    return Color.rgb((int) r, (int) g, (int) b);
}

Here's a simple example:

ColorFragment

public class ColorFragment extends Fragment {

    private static final String KEY_COLOR = "colorfragment:color";

    /** Empty constructor as per the {@link Fragment} docs */
    public ColorFragment() {
    }

    public static ColorFragment newInstance(int color) {
        final Bundle args = new Bundle();
        args.putInt(KEY_COLOR, color);
        final ColorFragment fragment = new ColorFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final FrameLayout rootView = new FrameLayout(getActivity());
        rootView.setBackgroundColor(getArguments().getInt(KEY_COLOR));
        return rootView;
    }

    public int getColor() {
        return getArguments().getInt(KEY_COLOR);
    }

}

Pulling it all together

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the ActionBar background
    final ColorDrawable actionBarBackground = new ColorDrawable();
    getSupportActionBar().setBackgroundDrawable(actionBarBackground);
    ...
    final PagerAdapter pagerAdapter = ...;
    ...
    // Bind your data to your PagerAdapter
    ...
    final ViewPager pager = ...;
    pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            super.onPageScrolled(position, positionOffset, positionOffsetPixels);
            if (position >= pagerAdapter.getCount() - 1) {
                // Guard against ArrayIndexOutOfBoundsException
                return;
            }
            // Retrieve the current and next ColorFragment
            final ColorFragment from = (ColorFragment) pagerAdapter.getItem(position);
            final ColorFragment to = (ColorFragment) pagerAdapter.getItem(position + 1);
            // Blend the colors and adjust the ActionBar
            final int blended = blendColors(to.getColor(), from.getColor(), positionOffset);
            actionBarBackground.setColor(blended);
        }

    });
    pager.setAdapter(pagerAdapter);
}

Results

http://gfycat.com/CautiousBewitchedJabiru

I hope that helps you out some!

like image 155
adneal Avatar answered Sep 18 '22 17:09

adneal


You could make your FragmentPagerAdapter implements ViewPager.OnPageChangeListener.

Then, override onPageSelected

@Override
public void onPageSelected(int position) {
    // get the action bar here and change color
}

As for the color change animation. I didn't try it, but this is from another stackoverflow issue :

Android objectAnimator animate backgroundColor of Layout

like image 28
Mathbl Avatar answered Sep 22 '22 17:09

Mathbl