Background Introduction
Recent project requirements, to make a custom viewpager, required to be able to swipe left and right at the same time, the Viewpager item itself is a stacked container and can be sliding up and down to achieve business requirements, such as sliding delete, slipped into the collection, etc., so write a blog record the implementation of the control.
First look at the effect:
Basic Ideas
The outer layer is Viewpager, which allows the left and right sliding of entries
Viewpager's child item is recyclerview, customize the LayoutManager and Itemtouchhelper.simplecallback of the Recyclerview to implement the control stack and up and down sliding implementation process
The first is the layout file:
<android.support.constraint.constraintlayout
xmlns:android= "Http://schemas.android.com/apk/res/android"
xmlns:app= "Http://schemas.android.com/apk/res-auto"
xmlns:tools= "Http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:clipchildren= " False "
tools:context=" com.mapleaf.centerviewpager.MainActivity ">
< Android.support.v4.view.ViewPager
android:id= "@+id/viewpager"
android:layout_width= "Wrap_content"
android:layout_height= "wrap_content"
android:clipchildren= "false"
App:layout_constraintbottom_ tobottomof= "Parent"
app:layout_constraintleft_toleftof= "parent"
App:layout_constraintright_torightof = "Parent"
app:layout_constrainttop_totopof= "parent"/>
</ Android.support.constraint.constraintlayout>
Remember that both the Viewpager and the parent control are added android:clipchildren= "false", meaning that the child control can be displayed more than its own position.
Next Initialize the Viewpager:
private void Initviewpager () {
mpageradapter = new custompageradapter<customrecyclerview<string>> ();
Mviewpager.setadapter (mpageradapter);
Mviewpager.setoffscreenpagelimit (2);
Viewgroup.layoutparams layoutparams = Mviewpager.getlayoutparams ();
Layoutparams.width = (Activity) mviewpager.getcontext ()). Getwindowmanager (). Getdefaultdisplay (). GetWidth ()/21 * 10 ;
Mtransformer = new Scaletransformer ();
Mviewpager.setpagetransformer (False, Mtransformer);
}
Scaletransformer inherits from the Viewpager.pagetransformer, its function is realizes the Viewpager to switch the animation effect, the concrete see code.
Then implement the custom Recyclerview, the core of which is to customize the LayoutManager implementation cascade, and implement Itemtouchhelper.simplecallback to customize the operation of sliding up and down.
The custom LayoutManager code is as follows:
public class Similaritemlayoutmanager extends Recyclerview.layoutmanager {@Override public recyclerview.layoutpa
Rams Generatedefaultlayoutparams () {return new Recyclerview.layoutparams (ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT); } @Override public void Onlayoutchildren (Recyclerview.recycler recycler, recyclerview.state State) {if (g Etitemcount () <= 0 | |
State.isprelayout ()) {return;
} detachandscrapattachedviews (recycler);
int visiblecount = 2;
if (GetItemCount () < Visiblecount) {Visiblecount = GetItemCount ();
} for (int i=visiblecount;i>=1;i--) {View view=recycler.getviewforposition (i-1);
AddView (view);
Measurechildwithmargins (view, 0, 0);
int widthspace = getwidth ()-getdecoratedmeasuredwidth (view); int heightspace = GetHeight ()-GetdecoratedmeasuredheighT (view); layoutdecorated (view, WIDTHSPACE/2, HEIGHTSPACE/2, WIDTHSP
ACE/2 + getdecoratedmeasuredwidth (view), HEIGHTSPACE/2 + getdecoratedmeasuredheight (view)); }
}
}
Because our recyclerview is stacked, we only need to display the top 2 view, and finally put the view in the middle of the recyclerview.
The last is to achieve itemtouchhelper.simplecallback
public class Itemswipecallback extends Itemtouchhelper.simplecallback {private Customrecyclerviewadapter madapter;
Private Viewpager Mviewpager; Public Itemswipecallback (Customrecyclerviewadapter adapter, Viewpager Viewpager) {super (0, Itemtouchhelper.up | I
Temtouchhelper.down);
Madapter = adapter;
Mviewpager = Viewpager; } @Override public boolean onMove (Recyclerview recyclerview, Recyclerview.viewholder Viewholder, Recyclerview.vie
Wholder target) {return false; } @Override public void onswiped (Recyclerview.viewholder viewholder, int direction) {if (direction== Item
Touchhelper.up) {//Slide up the page into the last Madapter.moveitemtobottom (Viewholder.getadapterposition ()); }else if (direction== itemtouchhelper.down) {viewHolder.itemView.animate (). Translationyby ( ScaleX (0). ScaleY (0). Rotation (720)
. setduration. Setlistener (New Animatorlisteneradapter () { @Override public void Onanimationend (Animator animation) {Super
. Onanimationend (animation);
Mviewpager.setcurrentitem (Mviewpager.getcurrentitem () + 1, true);
}
}); }} @Override public void Onchilddraw (Canvas C, Recyclerview Recyclerview, Recyclerview.viewholder viewholder , float DX, float dY, int actionstate, Boolean iscurrentlyactive) {if (DY < 0) {VIEWHOLDER.ITEMVI
Ew.settranslationy (DY);
} else if (Dy < viewHolder.itemView.getHeight ()) {ViewHolder.itemView.setTranslationY (dy); }
}
}
Because in my control I just need to swipe up and down, so in the constructor super (0, Itemtouchhelper.up | Itemtouchhelper.down); The first parameter 0 means no drag, and the second parameter indicates support for sliding up and down.
In onswiped, you can monitor up and down, and implement your own logic, I delete the first element and add it to the last when I slide it, animate it during the slide and move the Viewpager to the next entry.
You can customize the animation in Onchilddraw, what do you want to do (~ ̄▽ ̄) ~
The final step, then, is to correlate the two above customizations with our Recyclerview:
Similaritemlayoutmanager LayoutManager = new Similaritemlayoutmanager ();
Setlayoutmanager (LayoutManager);
Itemswipecallback callback=new Itemswipecallback (adapter,viewpager);
Itemtouchhelper helper=new Itemtouchhelper (callback);
Helper.attachtorecyclerview (this);
Okay, here's the code, see Github:https://github.com/xytyl/centerviewpager.