Search code examples
androidandroid-5.0-lollipopandroid-toolbar

Android - Change Hamburger/Back icons color programmatically during runtime


I'm trying to change the style attribute "colorControlNormal" of my app programmatically and during runtime, but I didn't have any results.

This property is the color that will tint the hamburger & back icons of the new Toolbar viewGroup. Beside, I'm using the v7 compatibility library.

I heard that we cannot change app theme during runtime, but I'm looking for an answer, even if it's not so clean way.

Edit:

I just figured that gmail is doing what i want, when you click on the search icon, the white hamburger icon turn into grey back.

Waiting for more.


Solution

  • I spent one day, played with different implementation. So my opinion, the best way todo that it copy paste DrawerArrowDrawable from AppCompat v7 library.

    https://gist.github.com/IstiN/5d542355935fd7f0f357 - take a look on the code with some optimization

    than you can use it in your main activity with code below

            DrawerArrowDrawable drawable = new DrawerArrowDrawable(this, this);
            ImageView menuButton = (ImageView) findViewById(R.id.arrow);
            menuButton.setImageDrawable(drawable);
            menuButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((DrawerLayout)findViewById(R.id.drawer)).openDrawer(Gravity.START);
                }
            });
    

    when you start new fragment, you need to create one more view on the same place and add second code to your fragment

        private DrawerArrowDrawable mArrowDrawable;
    
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            mArrowDrawable = new DrawerArrowDrawable(getActivity(), getActivity());
            ImageView topButton = (ImageView) view.findViewById(R.id.arrow);
            topButton.setImageDrawable(mArrowDrawable);
            topButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    closeSearch();
                }
            });
    
            //run animation from hamburger to arrow
            animate(0, 1, null);
            ....
    
        private void animate(int startValue, int endvalue, Animator.AnimatorListener listener) {
            ValueAnimator anim = ValueAnimator.ofFloat(startValue, endvalue);
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float slideOffset = (Float) valueAnimator.getAnimatedValue();
                    mArrowDrawable.setProgress(slideOffset);
                }
            });
            anim.setInterpolator(new DecelerateInterpolator());
            anim.setDuration(300);
            if (listener != null) {
                anim.addListener(listener);
            }
            anim.start();
        }
    

    to make animation from arrow to hamburger handle back button and execute code

    animate(1, 0, null);
    

    you also need to wait in your fragment while animation will not finish, but it another questions.

    If you have any questions ask in comments.