Babysitting! Teach you to achieve a silky control Q bomb effect (slide + Q bomb + gradient)

Preface

Although there are still many people who say that the user experience of Android is not as good as that of iOS, in recent years, with the efforts of many Android developers, Android now has the strength that is not lost to iOS, and the user experience is also rising.

What I want to share with you today is a silky control Q bomb effect, and I hope to inspire and help you in your study and work.

Let’s not talk too much nonsense, just go to the renderings, let you feel how silky and how good it is.

The animation of this Q bomb and the glamorous color conversion are really different from the ordinary Switch controls on the market. Let's disassemble it one by one, and implement it from 0 to 1.

Design ideas

The SwitchButon provided by the Android system reflects the metiarial design style very well, but it is not coquettish enough. I hope to use two conflicting contrasting colors for the color design of the control, so that when placed on a light-colored background page, the control can achieve a direct eye-piercing effect. Catch people, coquettish, and show off. As long as the overall page is properly matched, the control must be "externally pure and internally pure". The slightly fuzzy halo can make the already bright colors even more glamorous.

In order to increase the scalability of the design, the color can be changed to achieve the purpose of reflecting different styles.

Method to realize

In general, although the appearance of the control is very coquettish, the interaction logic is relatively simple. Do not consider inheriting from the system Switch, because there is no need to understand how to extend the Switch. Therefore, you can directly inherit from View. The entire logic control is implemented in onTouchEvent, and each configurable attribute is declared, such as color, size, and so on.

UI drawing

As you can see, the graph is composed of two parts, one is the blue rounded rectangle (indicator) in the front and the other is the long red rectangle (the background bar) in the back. You can draw these two graphs separately. The code of the onDraw part is as follows:

  • Draw the background bar:
    bkgRect represents the range of the rectangular area to be drawn, height and width are the length and width of the control, bkgBarW, bkgBarH are the length and width of the background bar, because it is a rounded rectangle, call the drawRoundRect method of canvas to draw, and bkgBarPaint controls the color of the background bar
//画背景条
RectF bkgRect = new RectF((width - bkgBarW) / 2f, height / 2 - (bkgBarH / 2), (width - bkgBarW) / 2f + bkgBarW, height / 2 + (bkgBarH / 2));
canvas.drawRoundRect(bkgRect, bkgBarH / 4, bkgBarH / 4, bkgBarPaint);
  • Draw the foreground rounded rectangle:
    Similarly, indicatorRect is the area of ​​the rounded rectangle to be drawn, indicatorW and indicatorH are the width and height of the indicator, and indicatorX and indicatorY are the center coordinates of the indicator. The coordinates will then be dynamically calculated in conjunction with the animator. Finally, call canvas's drawRoundRect to draw
//画指示器
RectF indicatorRect = new RectF(
        indicatorX,
        indicatorY,
        indicatorW + indicatorX,
        (height - indicatorH) / 2 + indicatorH
);
canvas.drawRoundRect(indicatorRect, indicatorH / 6, indicatorH / 6, indicatorPaint);
  • Draw icons or text:
    this part can be drawn after calculating the coordinates of the text or icon. It should be noted that if you want to draw text, you need to calculate the baseline position of the text, so that it can be visually centered with the indicator
//画图标
int baseLineY = (int) (indicatorRect.centerY() - textTop / 2 - textBottom / 2);//基线中间点的y轴计算公式
if (status == false) {
    canvas.drawText("♂", indicatorRect.centerX(), baseLineY, textPaint);
} else {
    canvas.drawText("♀", indicatorRect.centerX(), baseLineY, textPaint);
}
  • Animation implementation
    To facilitate control, define two AnimatorSets, namely animOnSet and animOffSet, animOnSet represents the collection of animations when the switch selector is turned on, and animOffSet represents the collection of animations when the switch selector is turned off. Set to BounceInterpolator to configure the elastic effect.
animatorOn = ValueAnimator.ofFloat(indicatorStartX, indicatorEndX);
animatorOn.setDuration(500);
animatorOn.setInterpolator(new BounceInterpolator());
animatorOn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        indicatorX = (float) animation.getAnimatedValue();
        postInvalidate();
    }
});
animOnSet = new AnimatorSet();
animOnSet.playTogether(animatorOn, animatorColorOn);


animatorOff = ValueAnimator.ofFloat(indicatorEndX, indicatorStartX);
animatorOff.setDuration(500);
animatorOff.setInterpolator(new BounceInterpolator());
animatorOff.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        indicatorX = (float) animation.getAnimatedValue();
        postInvalidate();
    }
});
animOffSet = new AnimatorSet();
animOffSet.playTogether(animatorColorOff, animatorOff);
  • Add 100 million points of detail. If you
    look closely, you can notice that the indicator is shaded with the same color. Here you can use the designed shadow background image to cut the image, but in order to increase the versatility of the control, a tricky method is adopted. By processing the Bitmap, when the indicator color changes, the drawn shadow color also changes. The code is as follows, bmShdow is the shadow picture to be drawn
bmShadow = BitmapFactory.decodeResource(getResources(), R.drawable.img_shadow_rect_blue);
//sex_blue为配置的指示器为“开”状态时的颜色,int值
bmShadow = BitmapUtils.replacePixelColor(bmShadow, sex_blue);

If you look closely, you will find that during the execution of the indicator animation, the indicator color has also completed a gradual transition. There is a dynamic calculation operation for changing the color, and the animator is still used for calculation, and the indicatorPaint controls the indicator color

animatorColorOn = new ValueAnimator();
animatorColorOn.setIntValues(sex_blue, sex_red);
animatorColorOn.setEvaluator(new ArgbEvaluator());
animatorColorOn.setDuration(500);
animatorColorOn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int color = (int) animation.getAnimatedValue();
        indicatorPaint.setColor(color);
    }
});

animatorColorOff = new ValueAnimator();
animatorColorOff.setIntValues(sex_red, sex_blue);
animatorColorOff.setEvaluator(new ArgbEvaluator());
animatorColorOff.setDuration(500);
animatorColorOff.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int color = (int) animation.getAnimatedValue();
        indicatorPaint.setColor(color);
    }
});

At last

Android learning is a long road, and every place is worth learning.

Among them, the point of control design or development embodies the "top-down" idea everywhere. In actual work, we will encounter various needs, but don't panic! As long as we calm down, clarify the requirements, clarify the logic, polish the details , and achieve these three points, most of the problems of control design or development can be solved.

I put the most important and popular learning direction materials on Android that I have compiled during this time on my GitHub: https://github.com/xieyuliang/Android-P7 (click here to view) , there are different directions inside Self-study programming route, interview question collection/face-to-face, and a series of technical articles.

Welcome everyone to study and discuss together.

Guess you like

Origin blog.csdn.net/BUGgogogo/article/details/113249360