Technology more than, the article has material, concern public number nine heart said, a high quality good article every week, and nine hearts in Dachang road side by side.

Last week, my colleague asked if there are multiple Item Switch controls, I think it is not difficult, so many third-party libraries, just pick one. After searching for a long time, although most switches are cool, they only support two items. The only one I found that supports multiple items is for ios, as shown in the figure:The only difficulty in this illustration is that the text changes color when the slider floats over the text, but it’s not that difficult and really not that interesting. Here’s my version:

As can be seen from the figure, the characteristics are as follows:

  • Support for multiple items
  • Supports text and ICONS
  • You can choose from many shapes
  • Overlaid text and ICONS change color as the slider slides

Github address: github.com/mCyp/Orient…

A, thinking

Making the Switch is pretty simple. The process is as follows:

  1. Draw the underlying background
  2. Draw the underlying text or Icon
  3. Draw the slider
  4. If the slider overlays a text or Icon, draw the text or Icon that the slider overlays

This is the difficulty of this Switch, how to draw part of the text and icon, the answer is shown in the title, use the Canvas clipping method Canvas. ClipRect (Rect Rect), if I cut the Canvas to a slider size, then I draw the text covered by the slider to the original position, Anything beyond the slider is not displayed.

Smart students at this point might ask the question, right? Now that you have clipped the Canvas, you can only display the slider, so it is true, but we also have canvas.save () and canvas.restore () methods, which respectively save the current Canvas to the corresponding Canvas stack and retrieve the top Canvas in the stack and restore it.

Two, the core code

I’m going to assume that you’re already familiar with basic custom views, so I’m going to show you the code for drawing a slider:

   / * *

* Draw the Switch slider

* /


    private void drawThumb(Canvas canvas) {

        // The left and right boundaries of the slider

        int left = mItemCoordinate[mThumbState.pos] + mThumbState.offset;

        int right = mItemCoordinate[mThumbState.pos + 1] + mThumbState.offset;

        // 1. Save this layer

        canvas.save();

        Rect rect = new Rect(left + mThumbMargin, top + mThumbMargin, right - mThumbMargin, bottom - mThumbMargin);

        // 2. Trim the canvas according to the slider size

        canvas.clipRect(rect);

        // 3. Draw the slider

        int padding = mThumbMargin + mThumbBorderWidth;

        if (mShape == SwitchShape.RECT) {

            drawRoundRect(canvas, left + padding, top + padding

                    , right - padding, bottom - padding, CORNER_RADIUS, mThumbColorPaint);

            if(mThumbBorderWidth ! =0)

                drawRoundRect(canvas, left + mThumbMargin, top + mThumbMargin

                        , right - mThumbMargin, bottom - mThumbMargin, CORNER_RADIUS, mThumbBorderPaint);



        } else {

            drawRoundRect(canvas, left + padding, top + padding

                    , right - padding, bottom - padding, (bottom - top) / 2 - padding, mThumbColorPaint);

            if(mThumbBorderWidth ! =0)

                drawRoundRect(canvas, left + mThumbMargin, top + mThumbMargin

                        , right - mThumbMargin, bottom - mThumbMargin, (bottom - top) / 2 - mThumbMargin, mThumbBorderPaint);

        }



        int first, second;

        / /... Omit fetching position



        // 4. Draw the text orIcon

        if (mType == SwitchType.TEXT) {

            drawText(canvas, mItems[first], mItemCoordinate[first], top, mItemCoordinate[first + 1], bottom, mThumbTextPaint);

            if(second ! = -1 && second <= mItemCount - 1) {

                drawText(canvas, mItems[second], mItemCoordinate[second], top, mItemCoordinate[second + 1], bottom, mThumbTextPaint);

            }

        } else {

            drawIcon(canvas, mIconRes[first], mItemCoordinate[first], top, mItemCoordinate[first + 1], bottom, mThumbTextPaint);

            if (second >= 0) {

                drawIcon(canvas, mIconRes[second], mItemCoordinate[second], top, mItemCoordinate[second + 1], bottom, mThumbTextPaint);

            }

        }

        

        // 5. The underlying canvas is restored

        canvas.restore();

    }

Copy the code

Comments are also in the above, interested in the source of students can directly look at Github, the control code is only 600 lines, handle the touch events and use good animation properties.

Three, use,

Maybe some students don’t want to focus on the principle, just want to know how to use it.

start

Implementation 'com. Received: received a Ui: 2.1.1'Copy the code

The first step is to add the XML layout file

<com.orient.me.widget.sw.MultiSwitch

    android:id="@+id/ms_weak"

    android:layout_width="match_parent"

    android:layout_marginStart="@dimen/len_10"

    android:layout_marginEnd="@dimen/len_10"

    android:layout_height="60dp"

    android:layout_gravity="center"

    android:layout_marginTop="@dimen/len_20"

    app:msBackgroundColor="@color/teal_300"

    app:msTextSize="@dimen/font_18"

    app:msNormalTextColor="@color/white_alpha_192"

    app:msShape="rect"

    app:msThumbColor="@color/white"

    app:msThumbMargin="@dimen/len_6"

    app:msThumbTextColor="@color/teal_300"

    app:msType="text" />


Copy the code

Explain the use of each attribute:

attribute instructions type
msBackgroundColor The background color reference|color
msNormalTextColor Unselected status text or Icon color reference|color
msThumbTextColor Slider text or Icon color reference|color
msTextSize Text size reference|dimension
msIconSize Size of the icon reference|dimension
msThumbMargin The margin of the slider reference|dimension
msShape Selected shape rect or oval
msType Selected type text or icon
msThumbColor Slider background color reference

Step 2 Get the MultiSwitch

Get the MultiSwitch object using findViewById

Step 3 Set the option content

Set the string array or Icon array

mHead.setItemsArray(new String[]{"Dark"."Light"});

// or

mIconSwitch.setIconArray(new int[]{R.drawable.grid_ic_play,R.drawable.ic_camera,R.drawable.common_ic_back});

Copy the code

Step 4 Set up the listener

Provides a callback for position selection and slider movement percentage, as in my renderings, when setting the background in night mode and day mode, using the percentage callback can be used to set the gradient effect of the background color.

mHead.setMultiSwitchListener(new MultiSwitchListener() {

    @Override

    public void onPositionSelected(int pos) {

        // when pos selected, it will call back

    }



    @Override

    public void onPositionOffsetPercent(int pos, float percent) {

        // current page move offset percent when drag

    }

});

Copy the code

In addition, you can also set the default location:

// Set the default location

mHead.setCurrentItem(2);

Copy the code

Four,

Custom View, you don’t have to smell custom View color change, sometimes, a custom View difficulty may be we are not commonly used to that one or two Api, at this time, you need to be familiar with the official Api provided.

Personal elucidation

If you are interested in other oreint-UI controls, check out:

Form: “received a Ui | single RecyclerView fancy can form” timeline: the fancy implementation timeline, style is up to you to decide!”