As Android continues to mature, many gorgeous effects are also constantly developed by everyone, including the effect of sideslip used a lot of projects, with good is to attract a lot of users. The sideslip of domestic apps like QQ and Kugou is very powerful, so I checked some information and combined with ViewDragHelper to make a relatively simple way to achieve sideslip.
One, the realization of the effect diagram
- The effect is basically similar to the cool dog App, because it is imitation of the cool dog ~~
Two, the implementation principle
-
The SlideLayout control is implemented using the ViewDragHelper class. ViewDragHelper is an implementation of View drag magic, it makes the View drag operation becomes particularly easy, if you are not familiar with ViewDragHelper please first on the portal.
-
To do this, you first need to associate SlideLayout with ViewDragHelper, then hand the SlideLayout event to ViewDragHelper for processing, and then perform various operations on the View in the callback provided by ViewDragHelper. The principle of drag and drop is the same. Move the ViewGroup horizontally or vertically, then redraw it with layout and Invalidate.
-
During the sliding process, in addition to constantly calculating the sliding position and redrawing the interface, different animation operations need to be performed on the child container. Here, the ViewHelper class is used to animate the View for panning, zooming and graditioning.
-
Enumerations are also used to record SlideLayout states, including closed, open, and sliding. And provides a PanelSlideListener to listen to the state of the slide. This allows you to do different things in different states. For example, manually open sideslip, close sideslip and so on.
Logical analysis
The logic of this project is not that hard. You just need to figure out where the ViewGroup slides and then redraw it, and then you need to figure out how much the controls scale and stretch, and so on. Of course, I should be familiar with the operation methods of various views, otherwise I don’t understand some logic to do here.
1. SlideLayout should be a control container containing two child containers, one menu container and one main container. First we need to get the width and height of the SlideLayout container and two child container objects
-
Get the width and height of SlideLayout in the View onSizeChanged() method after the control has been measured
/** * This method is used to measure the width of a control when the width of the control changes@param w * @param h * @param oldw * @param oldh */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mSlideHeight = getMeasuredHeight(); mSlideWidth = getMeasuredWidth(); /** * The initial drag range * defaults to 60% of the screen width */ mSlideRange = (int) (mSlideWidth * mRangePercent); }Copy the code
-
The container object is retrieved in the View’s onFinishInflate() method, where the layout is filled
/** * this method is called when the View is finished populating, to get the child View object */ @Override protected void onFinishInflate(a) { super.onFinishInflate(); if (getChildCount() < 2) { throw new IllegalStateException("The SlideLayout control must have more than 2 child Views."); } if(! ((getChildAt(0) instanceof ViewGroup) && (getChildAt(1) instanceof ViewGroup))) { throw new IllegalArgumentException("The child View of the SlideLayout control must be a ViewGroup."); } mMenuContainer = (ViewGroup) getChildAt(0); mMainContainer = (ViewGroup) getChildAt(1); }Copy the code
2. After obtaining the desired properties and objects, you can bind SlideLayout to ViewDragHelper
-
We create the ViewDragHelper object in the construction of the control, and then we have a callback, and all of our operations on the View are done in the methods of the callback
/** View's sliding helper class, listening for the View's various operations in the callback *@paramForParent The parent control to touch slide@paramSensitivity Control sliding speed, sensitivity, 1.0f normal *@paramCb callback to View events that changed */ mDragHelper = ViewDragHelper.create(this.1.0f, mViewCallback);Copy the code
-
After the object is created, it is useless to operate on the View at this point because you also need to pass the SlideLayout processing event to the ViewDragHelper
/** * forward intercepting events to the helper class **@param ev * @return* / @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { mDragHelper.cancel(); return false; } return mDragHelper.shouldInterceptTouchEvent(ev); } /** * Pass the touch event to the helper class **@param event * @return* / @Override public boolean onTouchEvent(MotionEvent event) { try { mDragHelper.processTouchEvent(event); } catch (Exception e) { e.printStackTrace(); } return true; }Copy the code
-
The most important thing is the ViewDragHelper callback. There are many methods, each of which is important. Here’s an example of the sliding method onViewPositionChanged() for the container. In fact, the logic is relatively simple, is to determine which container is sliding, calculate the left boundary value of the container, and then redraw the container
/** * Callback when the position of the child View changes@paramChangedView changes the child View@paramLeft Distance Left boundary distance *@paramTop Distance from the top distance *@paramDx horizontal slip distance *@paramDy vertical slip distance */ @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { /** * Moves the menu panel to the main panel */ if (changedView == mMenuContainer) { mMenuContainer.layout(0.0, mSlideWidth, mSlideHeight); int newLeft = mMainContainer.getLeft() + dx; newLeft = fixLeft(newLeft); mMainContainer.layout(newLeft, 0, newLeft + mSlideWidth, mSlideHeight); } // Handle movement events performSlideEvent(); }Copy the code
Five, use the tutorial
-
In the layout file
<com.pinger.slide.SlideLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/slideLayout" android:layout_width="match_parent" android:background="@mipmap/icon_bg" android:layout_height="match_parent"> // Menu container <include layout="@layout/layout_menu"/> / / the main container <include layout="@layout/layout_main"/> </com.pinger.slide.SlideLayout>Copy the code
-
Code to get the object, set listening, set to open or close sideslip
Six, summarized
With the ViewDragHelper class, it’s relatively easy to manipulate a ViewGroup. You only need to do the calculation and drawing, and the rest is done. Of course, ViewDragHelper does more than that. If you want to know more about it, you can look at the source code of this class. Here is just a simple implementation of the sideslip function, if you want to do more perfect students please modify.
My home page project download