AndroidSwipeLayout
AndroidSwipeLayout copied to clipboard
quick Swipe gesture trigger the onClickListener
Hi, i've configure your library correctly, i used the BaseSwipeAdapter with the onOpen method and an onClickListener method for the surface. But sometimes when i swipe without keeping my finger on the screen, my move trigger the onClickListener of my row (when i swipe to Open and sometimes when i swipe to close). How can i manage to avoid this behavior?
Thanks
Here is a video of the problem
https://mega.nz/#!PAJmXYYY!SkxP83OB04aidyXiu5bQ55QkjGAkwiB-6Uutd12RYEw
just dropping in here to say "same here", I haven't really investigated it yet though.
Think i found something:
in your onClickListener test the swipelayout Status
swipeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// test if the swipe is closed
if(swipeLayout.getOpenStatus() == SwipeLayout.Status.Close){
//DO WHAT YOU WANT
}//if
}
});
Try it and tell me?!
It still triggers the onClickListener when you close (swipe back) the surface view
You may want to try this work-around:
swipeLayout.setOnClickListener(new View.OnClickListener()
{
boolean wasClosed = true;
@Override
public void onClick(View v)
{
if (SwipeLayout.Status.Close == swipeLayout.getOpenStatus())
{
if (wasClosed)
{
//DO WHAT YOU WANT
}
else
{
wasClosed = true;
}
}
else
{
wasClosed = false;
}
}
});
Alrighty, so the problem is (essentially) here: https://github.com/daimajia/AndroidSwipeLayout/blob/cc6a322f745c3f7acfc9b02223e4cb3067e9fdc5/library/src/main/java/com/daimajia/swipe/SwipeLayout.java#L1002-L1013
private void performAdapterViewItemClick() {
if(getOpenStatus()!= Status.Close) return;
ViewParent t = getParent();
if (t instanceof AdapterView) {
AdapterView view = (AdapterView) t;
int p = view.getPositionForView(SwipeLayout.this);
if (p != AdapterView.INVALID_POSITION){
view.performItemClick(view.getChildAt(p - view.getFirstVisiblePosition()), p, view
.getAdapter().getItemId(p));
}
}
}
If you e.g. swipe an open layout closed, and the layout closes before you release your finger (e.g. if the background view is 100dp, and you swiped 110dp before lifting), the getOpenStatus()
will return Close
, because it's only based on the current layout.
Unfortunately I'm not sure what a clean solution would look like. Maybe this is worth special-casing, and adding an "if swiped by this touch" flag?
Hi, I am also getting this in my listview. I am using this latest one com.daimajia.swipelayout:library:1.2.0@aar"
Thanks,
Tested that @Groxx 's commit using jitpack. It's finally working perfectly in my case.
This is the dependency line I'm using: compile 'com.github.Groxx:AndroidSwipeLayout:c8a42d84c1'
, don't forget to add maven { url "https://jitpack.io" }
line to your repositories block.
Going to use this workaround until that fix got into this upstream repo. Hope it will be merged soon.
Any updates? I have to downgrade the library to v1.1.9 to get rid of this problem.
One thing that I did that fix this was instead of putting the onClickListener on the whole layout (itemView of a ViewHolder, for example), I put it only on the SurfaceView. For what I understood, the SwipeLayout get the click first and use it if dragging, don't pass to children. If not dragging, then the click will be used by children.
Using the same layout on the wiki, would be something like this:
<com.daimajia.swipe.SwipeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="80dp"
android:id="@+id/swipe_layout">
<!-- Bottom View Start-->
<LinearLayout
android:id="@+id/bottom_wrapper"
android:layout_width="160dp"
android:layout_height="match_parent">
<!--What you want to show-->
</LinearLayout>
<!-- Bottom View End-->
<!-- Surface View Start -->
<LinearLayout
android:id="@+id/ll_surface_view"
android:layout_width="match_parent"
android:background="?attr/selectableItemBackground"
android:layout_height="match_parent">
<!--What you want to show in SurfaceView-->
</LinearLayout>
<!-- Surface View End -->
</com.daimajia.swipe.SwipeLayout>
And on my ViewHolder
ll_surface_view.setOnClickListener(view -> {
if(swipe_layout.getOpenStatus() == SwipeLayout.Status.Close){
listener.onSubjectClicked(subject);
}
});
Used @tsuharesu solution, worked perfectly, I guess you could close the issue so people will know there a solution when looking at the issue.
Used @tsuharesu solution with Cursor Adaptor and the problem is solved1 Thanks
Not the perfect workaround but it works well for my purposes
public class CSwipeLayout extends SwipeLayout {
public enum SwipeStatus {OPENING, OPENED, CLOSING, CLOSED}
SwipeStatus swipeStatus = SwipeStatus.CLOSED;
OnClickListener onClickListener;
public CSwipeLayout(Context context) {
super(context);
init(context);
}
public CSwipeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CSwipeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
addSwipeListener(new SimpleSwipeListener() {
Handler handler = new Handler();
Runnable closeRunnable = new Runnable() {
@Override
public void run() {
swipeStatus = SwipeStatus.CLOSED;
}
};
Runnable openRunnable = new Runnable() {
@Override
public void run() {
swipeStatus = SwipeStatus.OPENED;
}
};
@Override
public void onStartOpen(SwipeLayout layout) {
swipeStatus = SwipeStatus.OPENING;
handler.removeCallbacks(closeRunnable);
}
@Override
public void onOpen(SwipeLayout layout) {
handler.removeCallbacks(closeRunnable);
handler.postDelayed(openRunnable, 100);
}
@Override
public void onStartClose(SwipeLayout layout) {
swipeStatus = SwipeStatus.CLOSING;
handler.removeCallbacks(closeRunnable);
}
@Override
public void onClose(SwipeLayout layout) {
handler.removeCallbacks(openRunnable);
handler.postDelayed(closeRunnable, 100);
}
});
super.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (getSwipeStatus() == CSwipeLayout.SwipeStatus.CLOSED) {
if (onClickListener != null)
onClickListener.onClick(view);
} else if (getSwipeStatus() == CSwipeLayout.SwipeStatus.OPENED) {
// This will close the layout in case of a click while already opened
close();
}
}
});
}
public SwipeStatus getSwipeStatus() {
return swipeStatus;
}
@Override
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
}
Then
swipeLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// DO WHATEVER YOU WANT
}
});
Think i found something:
in your onClickListener test the swipelayout Status
swipeLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // test if the swipe is closed if(swipeLayout.getOpenStatus() == SwipeLayout.Status.Close){ //DO WHAT YOU WANT }//if } });
Try it and tell me?!
its working for me. thanks a lot. you saved my time