How to implement “Loading images” pattern (Opacity, Exposure and Saturation) from Google's new Material design guidelines

前端 未结 4 1901
礼貌的吻别
礼貌的吻别 2021-01-31 00:03

Has anyone looked into implementing the Loading images pattern from Google\'s latest Material Design guide.

It\'s a recommended way that \"illustrations and photographs

4条回答
  •  孤街浪徒
    2021-01-31 00:23

    Thanks to @mttmllns! Previous Answer.

    Since the previous answer shows an example written in C# and I was curious, I ported it to java. Complete GitHub Example

    It outlines a 3-steps process where a combination of opacity, contrast/luminosity and saturation is used in concert to help salvage our poor users eyesight.

    For a detailed explanation read this article.

    EDIT:

    See, the excellent answer provided by @DavidCrawford.

    BTW: I fixed the linked GitHubProject to support pre-Lollipop devices. (Since API Level 11)

    The Code

    AlphaSatColorMatrixEvaluator.java

    import android.animation.TypeEvaluator;
    import android.graphics.ColorMatrix;
    
    public class AlphaSatColorMatrixEvaluator implements TypeEvaluator {
        private ColorMatrix colorMatrix;
        float[] elements = new float[20];
    
        public AlphaSatColorMatrixEvaluator() {
            colorMatrix = new ColorMatrix ();
        }
    
        public ColorMatrix getColorMatrix() {
            return colorMatrix;
        }
    
        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            // There are 3 phases so we multiply fraction by that amount
            float phase = fraction * 3;
    
            // Compute the alpha change over period [0, 2]
            float alpha = Math.min(phase, 2f) / 2f;
            // elements [19] = (float)Math.round(alpha * 255);
            elements [18] = alpha;
    
            // We substract to make the picture look darker, it will automatically clamp
            // This is spread over period [0, 2.5]
            final int MaxBlacker = 100;
            float blackening = (float)Math.round((1 - Math.min(phase, 2.5f) / 2.5f) * MaxBlacker);
            elements [4] = elements [9] = elements [14] = -blackening;
    
            // Finally we desaturate over [0, 3], taken from ColorMatrix.SetSaturation
            float invSat = 1 - Math.max(0.2f, fraction);
            float R = 0.213f * invSat;
            float G = 0.715f * invSat;
            float B = 0.072f * invSat;
    
            elements[0] = R + fraction; elements[1] = G;            elements[2] = B;
            elements[5] = R;            elements[6] = G + fraction; elements[7] = B;
            elements[10] = R;           elements[11] = G;           elements[12] = B + fraction;
    
            colorMatrix.set(elements);
            return colorMatrix;
        }
    }
    

    Here is how you can set it up:

    ImageView imageView = (ImageView)findViewById(R.id.imageView);
    final BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.drawable.image);
    imageView.setImageDrawable(drawable);
    AlphaSatColorMatrixEvaluator evaluator = new AlphaSatColorMatrixEvaluator ();
    final ColorMatrixColorFilter filter = new ColorMatrixColorFilter(evaluator.getColorMatrix());
    drawable.setColorFilter(filter);
    
    ObjectAnimator animator = ObjectAnimator.ofObject(filter, "colorMatrix", evaluator, evaluator.getColorMatrix());
    
    animator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            drawable.setColorFilter (filter);
        }
    });
    animator.setDuration(1500);
    animator.start();
    

    And here is the result:

    enter image description here

提交回复
热议问题