Preface:

WheelView with the same effect as the wheel control (IOS time address selection 3D) was realized through Camera, Matrix 3D rotation +RecyclerView, and the sliding effect like the wheel on Android QQ was realized

Pay attention to more articles:www.jianshu.com/u/b1cff3409…


One: look at the effect map first




Vertical 3D rotation





Horizontal 3D rotation

Two: functional analysis
1:3d rotation effect

WheelView has been implemented in many ways, and there are also good rotation effects on the Internet, but it is only 2D rotation, and it is complicated to handle sliding and clicking item events. The real rotation needs to pass the Matrix. Camera class,Camera is not the Camera API,Camera can realize the rotation of x,y,z axis, unclear can also solve the use of these apis, not detailed here. Cooperate with RecyclerView ItemDecoration, Canvas in each item 3 d rotation and translation, 3 d visual effect

Here is an example of a state of vertical layout

/** * Draw vertical layout item * @param c * @param rect * @param position * @param parentCenterX RecyclerView center X point * @param Void drawVerticalItem(Canvas C, Rect Rect, int Position, float parentCenterX, float parentCenterY) { int realPosition = position - itemCount; Float itemCenterY = rect.exactcentery (); float itemCenterY = rect.exactcentery (); float scrollOffY = itemCenterY - parentCenterY; float rotateDegreeX = scrollOffY * itemDegree / itemSize; Int Alpha = degreeAlpha(rotateDegreeX); if (alpha <= 0) return; float rotateSinX = (float) Math.sin(Math.toRadians(rotateDegreeX)); float rotateOffY = scrollOffY - wheelRadio * rotateSinX; //Log. I ("you", "drawVerticalItem degree "+ rotateDegreeX); Boolean isCenterItem = false; Boolean isCenterItem = false; if (! hasCenterItem) { isCenterItem = Math.abs(scrollOffY) <= halfItemHeight; if (isCenterItem) { centerItemPosition = realPosition; hasCenterItem = true; }} // Here is the core of rotation operation. When each item is rotated into an arc, the visual offset of the center of item after rotation should be calculated. C.t ranslate (0.0 f - rotateOffY); camera.save(); camera.rotateX(-rotateDegreeX); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-parentCenterX, -itemCenterY); matrix.postTranslate(parentCenterX, itemCenterY); c.concat(matrix); drawItem(c, rect, realPosition, alpha, isCenterItem, true); c.restore(); }Copy the code

Up to now, the rotation effect of each item from the center point has been basically realized. Next, the number of empty items displayed by WheelView at the head and tail of RecyclerView is added

2: adapter definition

When sliding, the item must be above or below the center point, so the number of items in the adapter must be changed accordingly, directly to the code

class WheelViewAdapter extends RecyclerView.Adapter<WheelViewHolder> { ... Override public void onBindViewHolder(WheelViewHolder holder, View} @override public int getItemCount() {// Return totalItemCount + (Adapter == null? 0 : adapter.getItemCount()); } @Override public WheelViewHolder onCreateViewHolder(ViewGroup parent, View = new View(parent.getContext()); view.setLayoutParams(WheelUtils.createLayoutParams(orientation, itemSize)); return new WheelViewHolder(view); }}Copy the code

Conclusion:

The specific usage method of WheelView is described in detail in the sample code. Due to busy work, there are appropriate annotations in the source code, and we can also discuss better effects together

After the free time plus item click and left and right offset stereo effect, as well as packaging date selection…


Pay attention to more articles:www.jianshu.com/u/b1cff3409…

Finally, attach the source codeGithub.com/youxiaochen…