Rendering:
Im Internet werden zwei Ansichten zusammengefügt. Standardmäßig wird die rechte Ansicht nicht angezeigt. Allerdings ist der Effekt bei der neuesten Version von QQ nicht so, aber er fühlt sich sehr gut an, daher ist es besser, eine hohe Nachahmung zu verwenden.
Wissenspunkte:
1. Verwendung von ViewDragHelper;
3.
1. tryCaptureView(View child, int pointerId): Bestimmen Sie, welche untergeordnete Ansicht verschoben werden kann
public SwipeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { viewDragHelper = ViewDragHelper.create(this, callback); } public boolean onInterceptTouchEvent(MotionEvent ev) { boolean result = viewDragHelper.shouldInterceptTouchEvent(ev); } public boolean onTouchEvent(MotionEvent event) { viewDragHelper.processTouchEvent(event); return true; }
3) abgefangen werden soll, das Ereignis kommt in onTouchEvent heraus
Okay, das am schwierigsten zu verstehende Problem wurde gelöst. Schauen wir uns als nächstes die spezifische Implementierung an:
Schauen wir uns zunächst das Layout an:
Dazu gibt es nichts zu sagen. Eine benutzerdefinierte Ansichtsgruppe enthält zwei Untersteuerelemente. Dann schauen wir uns an, wie SwipeLayout implementiert wird:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <scrollviewgroup.lly.com.swiplayout.SwipeLayout android:id="@+id/swipeLayout" android:layout_width="match_parent" android:layout_height="wrap_content" > <!-- delete区域的布局 --> <include layout="@layout/layout_delete" /> <!-- item内容的布局 --> <include layout="@layout/layout_content" /> </scrollviewgroup.lly.com.swiplayout.SwipeLayout> </LinearLayout>Der obige Code führt einige Initialisierungsvorgänge aus. Hier erben wir zuerst das Framelayout . Und platzieren Sie es auf der rechten Seite und ändern Sie dann eine ContentView-Ebene darüber, sodass bei der Anzeige nur die ContentView angezeigt wird. Als nächstes schauen wir uns die Ontouch-Methode an
@Override protected void onFinishInflate() { super.onFinishInflate(); deleteView = getChildAt(0); contentView = getChildAt(1); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); deleteHeight = deleteView.getMeasuredHeight(); deleteWidth = deleteView.getMeasuredWidth(); contentWidth = contentView.getMeasuredWidth(); screenWidth = getWidth(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { // super.onLayout(changed, left, top, right, bottom); deleteView.layout(screenWidth - deleteWidth, 0, (screenWidth - deleteWidth) + deleteWidth, deleteHeight); contentView.layout(0, 0, contentWidth, deleteHeight); }Beim Obigen geht es hauptsächlich um die Handhabung von Ereigniskonflikten. Wenn es sich horizontal bewegt, fordert es die übergeordnete Ansicht auf, es nicht abzufangen. Jetzt kommt der entscheidende Punkt
public boolean onTouchEvent(MotionEvent event) { //如果当前有打开的,则下面的逻辑不能执行 if(!SwipeLayoutManager.getInstance().isShouldSwipe(this)){ requestDisallowInterceptTouchEvent(true); return true; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); break; case MotionEvent.ACTION_MOVE: //1.获取x和y方向移动的距离 float moveX = event.getX(); float moveY = event.getY(); float delatX = moveX - downX;//x方向移动的距离 float delatY = moveY - downY;//y方向移动的距离 if(Math.abs(delatX)>Math.abs(delatY)){ //表示移动是偏向于水平方向,那么应该SwipeLayout应该处理,请求父view不要拦截 requestDisallowInterceptTouchEvent(true); } //更新downX,downY downX = moveX; downY = moveY; break; case MotionEvent.ACTION_UP: break; } viewDragHelper.processTouchEvent(event); return true; }Wir haben die Methode bereits am Anfang erwähnt. In tryCaptureView machen wir die ContentView verschiebbar , der Schiebebereich ist deleteWidth, die Grenze wird in onViewPositionChanged aktualisiert. Wenn der Finger schließlich angehoben wird, wird die Ansicht automatisch zurückgesetzt Schreiben Sie die Methode „computeScroll“ neu, andernfalls hört der Gleiteffekt auf, sich zu bewegen. Dieses benutzerdefinierte Framelayout ist jetzt fertig
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return child==contentView; } @Override public int getViewHorizontalDragRange(View child) { return deleteWidth; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { if(child==contentView){ if(left>0)left = 0; if(left<-deleteWidth)left = -deleteWidth; } return left; } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { super.onViewPositionChanged(changedView, left, top, dx, dy); //判断开和关闭的逻辑 if(contentView.getLeft()==0 && currentState!=SwipeState.Close){ //说明应该将state更改为关闭 currentState = SwipeState.Close; //回调接口关闭的方法 if(listener!=null){ listener.onClose(getTag()); } //说明当前的SwipeLayout已经关闭,需要让Manager清空一下 SwipeLayoutManager.getInstance().clearCurrentLayout(); }else if (contentView.getLeft()==-deleteWidth && currentState!=SwipeState.Open) { //说明应该将state更改为开 currentState = SwipeState.Open; //回调接口打开的方法 if(listener!=null){ listener.onOpen(getTag()); } //当前的Swipelayout已经打开,需要让Manager记录一下下 SwipeLayoutManager.getInstance().setSwipeLayout(SwipeLayout.this); } } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); if(contentView.getLeft()<-deleteWidth/2){ //应该打开 open(); }else { //应该关闭 close(); } } };
Aber wir haben ein Problem festgestellt, wenn wir in der herausgeschobenen Ansicht nach oben und unten schieben, wird die deleteView dieser Ansicht immer noch angezeigt, also wir Sie müssen es noch zur Aktivität „Verarbeiten“ hinzufügen:
/** * 打开的方法 */ public void open() { viewDragHelper.smoothSlideViewTo(contentView,-deleteWidth,contentView.getTop()); ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); } /** * 关闭的方法 */ public void close() { viewDragHelper.smoothSlideViewTo(contentView,0,contentView.getTop()); ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); }; public void computeScroll() { if(viewDragHelper.continueSettling(true)){ ViewCompat.postInvalidateOnAnimation(this); } }
Wenn diese RecyclerView nach oben und unten gleitet, setzen Sie die Unteransicht zurück.
Machen Sie Schluss. ps: Es wurde ursprünglich in Listview in Eclipse implementiert, aber da Google Eclipse nicht mehr unterstützt und Listview bald durch RecyclerView ersetzt wird, bin ich schließlich auf Android Studio umgestiegen und habe es mit RecyclerView implementiert . Das Obige ist die benutzerdefinierte Ansicht in Android, die Ihnen der Editor vorstellt, um den seitlichen Gleiteffekt zu erzielen. Wenn Sie Fragen haben, hinterlassen Sie mir und dem Editor bitte eine Nachricht werde Ihnen rechtzeitig antworten. Ich möchte mich auch bei Ihnen allen für Ihre Unterstützung der chinesischen PHP-Website bedanken!recyView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if(dy>0 || dy<0){ SwipeLayoutManager.getInstance().closeCurrentLayout(); } } });
Weitere Artikel zum Anpassen von Ansichten in Android, um seitliche Gleiteffekte zu erzielen, finden Sie auf der chinesischen PHP-Website!