Skip to content

Commit a958b0f

Browse files
committed
Added a callback after the dismiss animation was finished. This solves some redraw issues.
1 parent 6b30e20 commit a958b0f

File tree

4 files changed

+165
-101
lines changed

4 files changed

+165
-101
lines changed

README.md

+67-45
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
SwipeActionAdapter - The Mailbox-like Swipe gesture library
22
===========================================================
33

4-
SwipeActionAdapter is a library that provides a simple API to create Mailbox-like action when swiping in a ListView. The idea is to make it simple enough to implement while still providing sufficient options to allow you to integrate it with the design of your application.
4+
SwipeActionAdapter is a library that provides a simple API to create Mailbox-like action when swiping in a ListView.
5+
The idea is to make it simple enough to implement while still providing sufficient options to allow you to
6+
integrate it with the design of your application.
57

6-
Support for Android 4.0 and up. It might work on lower API versions, but I haven't tested it and I don't intend to make any effort in that direction.
8+
Support for Android 4.0 and up. It might work on lower API versions, but I haven't tested it and I don't intend to
9+
make any effort in that direction.
710

811
Feel free to fork or issue pull requests on github. Issues can be reported on the github issue tracker.
912

@@ -16,7 +19,8 @@ Setup
1619

1720
* [Download the jar file](https://github.com/wdullaer/SwipeActionAdapter/releases) and add it to your project
1821

19-
If you would like to get the most recent code in a jar, clone the project and run ```./gradlew jar``` from the root folder. This will build a swipeactionadapter.jar in ```library/build/libs/```.
22+
If you would like to get the most recent code in a jar, clone the project and run ```./gradlew jar``` from
23+
the root folder. This will build a swipeactionadapter.jar in ```library/build/libs/```.
2024

2125
You may also add the library as an Android Library to your project. All the library files live in ```library```.
2226

@@ -33,7 +37,11 @@ For a basic implementation, you'll need to
3337

3438
### Wrap the adapter of you ListView
3539

36-
The majority of this libraries functionality is provided through an adapter which wraps around the content ```Adapter``` of your ```ListView```. You will need to set the SwipeActionAdapter to your ListView and because we need to set some properties of the ListView, you will also need to give a reference of the ```ListView``` to the ```SwipeActionAdapter```. This is typically done in your ```Activity```'s or ```Fragments``` onCreate/onActivityCreated callbacks.
40+
The majority of this libraries functionality is provided through an adapter which wraps around the content ```Adapter```
41+
of your ```ListView```. You will need to set the SwipeActionAdapter to your ListView and because
42+
we need to set some properties of the ListView, you will also need to give a reference of the ```ListView```
43+
to the ```SwipeActionAdapter```.
44+
This is typically done in your ```Activity```'s or ```Fragments``` onCreate/onActivityCreated callbacks.
3745

3846
```java
3947
protected void onCreate(Bundle savedInstanceState) {
@@ -48,13 +56,13 @@ protected void onCreate(Bundle savedInstanceState) {
4856
R.id.text,
4957
new ArrayList<String>(Arrays.asList(content))
5058
);
51-
59+
5260
// Wrap your content in a SwipeActionAdapter
5361
mAdapter = new SwipeActionAdapter(stringAdapter);
54-
62+
5563
// Pass a reference of your ListView to the SwipeActionAdapter
5664
mAdapter.setListView(getListView());
57-
65+
5866
// Set the SwipeActionAdapter as the Adapter for your ListView
5967
setListAdapter(mAdapter);
6068
}
@@ -63,7 +71,8 @@ protected void onCreate(Bundle savedInstanceState) {
6371
### Create a background layout for each swipe direction
6472

6573
I'm just supplying an empty layout with a background for each direction.
66-
You should have a layout for at least ```SwipeDirections.DIRECTION_NORMAL_LEFT``` and ```SwipeDirections.DIRECTION_NORMAL_RIGHT```. The other directions are optional.
74+
You should have a layout for at least ```SwipeDirections.DIRECTION_NORMAL_LEFT``` and ```SwipeDirections.DIRECTION_NORMAL_RIGHT```.
75+
The other directions are optional.
6776
It is important that the background layouts have the same height as the normal row layout.
6877
The ```onCreate``` callback from the previous section now becomes:
6978

@@ -80,16 +89,16 @@ protected void onCreate(Bundle savedInstanceState) {
8089
R.id.text,
8190
new ArrayList<String>(Arrays.asList(content))
8291
);
83-
92+
8493
// Wrap your content in a SwipeActionAdapter
8594
mAdapter = new SwipeActionAdapter(stringAdapter);
86-
95+
8796
// Pass a reference of your ListView to the SwipeActionAdapter
8897
mAdapter.setListView(getListView());
8998

9099
// Set the SwipeActionAdapter as the Adapter for your ListView
91100
setListAdapter(mAdapter);
92-
101+
93102
// Set backgrounds for the swipe directions
94103
mAdapter.addBackground(SwipeDirections.DIRECTION_FAR_LEFT,R.layout.row_bg_left_far)
95104
.addBackground(SwipeDirections.DIRECTION_NORMAL_LEFT,R.layout.row_bg_left)
@@ -111,9 +120,15 @@ Layout code
111120

112121
### Implement the SwipeActionListener
113122

114-
The final thing to do is listen to swipe gestures. This is done by implementing the ```SwipeActionListener```. This interface has two methods:
123+
The final thing to do is listen to swipe gestures. This is done by implementing the ```SwipeActionListener```.
124+
This interface has three methods:
115125
* ```boolean hasActions(int position)```: return true if you want this item to be swipeable
116-
* ```boolean onSwipe(int position, int direction)```: triggered when an item is swiped. Return true if you want the item to be dismissed, return false if it should stay visible. This method runs on the interface thread so perform any heavy logic in an ASyncThread
126+
* ```boolean shouldDismiss(int position, int direction)```: return true if you want the item to be dismissed,
127+
return false if it should stay visible. This method runs on the interface thread so if you want to trigger any
128+
heavy actions here, put them on an ```ASyncThread```
129+
* ```void onSwipe(int[] position, int[] direction)```: triggered when all animations on the swiped items have finished.
130+
You will receive an array of all swiped items, sorted in descending order with their corresponding directions.
131+
117132
You should pass a reference of your ```SwipeActionListener``` to the ```SwipeActionAdapter```
118133

119134
Here's the final implementation of our example's ```onCreate``` method:
@@ -130,22 +145,22 @@ protected void onCreate(Bundle savedInstanceState) {
130145
R.id.text,
131146
new ArrayList<String>(Arrays.asList(content))
132147
);
133-
148+
134149
// Wrap your content in a SwipeActionAdapter
135150
mAdapter = new SwipeActionAdapter(stringAdapter);
136-
151+
137152
// Pass a reference of your ListView to the SwipeActionAdapter
138153
mAdapter.setListView(getListView());
139154

140155
// Set the SwipeActionAdapter as the Adapter for your ListView
141156
setListAdapter(mAdapter);
142-
157+
143158
// Set backgrounds for the swipe directions
144159
mAdapter.addBackground(SwipeDirections.DIRECTION_FAR_LEFT,R.layout.row_bg_left_far)
145160
.addBackground(SwipeDirections.DIRECTION_NORMAL_LEFT,R.layout.row_bg_left)
146161
.addBackground(SwipeDirections.DIRECTION_FAR_RIGHT,R.layout.row_bg_right_far)
147162
.addBackground(SwipeDirections.DIRECTION_NORMAL_RIGHT,R.layout.row_bg_right);
148-
163+
149164
// Listen to swipes
150165
mAdapter.setSwipeActionListener(new SwipeActionListener(){
151166
@Override
@@ -155,35 +170,42 @@ protected void onCreate(Bundle savedInstanceState) {
155170
}
156171

157172
@Override
158-
public boolean onSwipe(int position, int direction){
159-
String dir = "";
160-
boolean output = false;
161-
switch(direction) {
162-
case SwipeDirections.DIRECTION_FAR_LEFT:
163-
dir = "Far left";
164-
break;
165-
case SwipeDirections.DIRECTION_NORMAL_LEFT:
166-
dir = "Left";
167-
output = true;
168-
break;
169-
case SwipeDirections.DIRECTION_FAR_RIGHT:
170-
dir = "Far right";
171-
break;
172-
case SwipeDirections.DIRECTION_NORMAL_RIGHT:
173-
AlertDialog.Builder builder = new AlertDialog.Builder(this);
174-
builder.setTitle("Test Dialog").setMessage("You swiped right").create().show();
175-
dir = "Right";
176-
break;
173+
public boolean shouldDismiss(int position, int direction){
174+
// Only dismiss an item when swiping normal left
175+
return direction == SwipeDirections.DIRECTION_NORMAL_LEFT;
176+
}
177+
178+
@Override
179+
public void onSwipe(int[] positionList, int[] directionList){
180+
for(int i=0;i<positionList.length;i++) {
181+
int direction = directionList[i];
182+
int position = positionList[i];
183+
String dir = "";
184+
185+
switch (direction) {
186+
case SwipeDirections.DIRECTION_FAR_LEFT:
187+
dir = "Far left";
188+
break;
189+
case SwipeDirections.DIRECTION_NORMAL_LEFT:
190+
dir = "Left";
191+
break;
192+
case SwipeDirections.DIRECTION_FAR_RIGHT:
193+
dir = "Far right";
194+
break;
195+
case SwipeDirections.DIRECTION_NORMAL_RIGHT:
196+
AlertDialog.Builder builder = new AlertDialog.Builder(this);
197+
builder.setTitle("Test Dialog").setMessage("You swiped right").create().show();
198+
dir = "Right";
199+
break;
200+
}
201+
Toast.makeText(
202+
this,
203+
dir + " swipe Action triggered on " + mAdapter.getItem(position),
204+
Toast.LENGTH_SHORT
205+
).show();
206+
mAdapter.notifyDataSetChanged();
177207
}
178-
Toast.makeText(
179-
this,
180-
dir + " swipe Action triggered on "+mAdapter.getItem(position),
181-
Toast.LENGTH_SHORT
182-
).show();
183-
mAdapter.notifyDataSetChanged();
184-
185-
return output;
186-
}
208+
}
187209
});
188210
}
189211
```

example/src/main/java/com/wdullaer/swipeactionexample/MainActivity.java

+33-27
Original file line numberDiff line numberDiff line change
@@ -96,33 +96,39 @@ public boolean hasActions(int position){
9696
}
9797

9898
@Override
99-
public boolean onSwipe(int position, int direction){
100-
String dir = "";
101-
boolean output = false;
102-
switch(direction) {
103-
case SwipeDirections.DIRECTION_FAR_LEFT:
104-
dir = "Far left";
105-
break;
106-
case SwipeDirections.DIRECTION_NORMAL_LEFT:
107-
dir = "Left";
108-
output = true;
109-
break;
110-
case SwipeDirections.DIRECTION_FAR_RIGHT:
111-
dir = "Far right";
112-
break;
113-
case SwipeDirections.DIRECTION_NORMAL_RIGHT:
114-
AlertDialog.Builder builder = new AlertDialog.Builder(this);
115-
builder.setTitle("Test Dialog").setMessage("You swiped right").create().show();
116-
dir = "Right";
117-
break;
118-
}
119-
Toast.makeText(
120-
this,
121-
dir + " swipe Action triggered on "+mAdapter.getItem(position),
122-
Toast.LENGTH_SHORT
123-
).show();
124-
mAdapter.notifyDataSetChanged();
99+
public boolean shouldDismiss(int position, int direction){
100+
return direction == SwipeDirections.DIRECTION_NORMAL_LEFT;
101+
}
125102

126-
return output;
103+
@Override
104+
public void onSwipe(int[] positionList, int[] directionList){
105+
for(int i=0;i<positionList.length;i++) {
106+
int direction = directionList[i];
107+
int position = positionList[i];
108+
String dir = "";
109+
110+
switch (direction) {
111+
case SwipeDirections.DIRECTION_FAR_LEFT:
112+
dir = "Far left";
113+
break;
114+
case SwipeDirections.DIRECTION_NORMAL_LEFT:
115+
dir = "Left";
116+
break;
117+
case SwipeDirections.DIRECTION_FAR_RIGHT:
118+
dir = "Far right";
119+
break;
120+
case SwipeDirections.DIRECTION_NORMAL_RIGHT:
121+
AlertDialog.Builder builder = new AlertDialog.Builder(this);
122+
builder.setTitle("Test Dialog").setMessage("You swiped right").create().show();
123+
dir = "Right";
124+
break;
125+
}
126+
Toast.makeText(
127+
this,
128+
dir + " swipe Action triggered on " + mAdapter.getItem(position),
129+
Toast.LENGTH_SHORT
130+
).show();
131+
mAdapter.notifyDataSetChanged();
132+
}
127133
}
128134
}

library/src/main/java/com/wdullaer/swipeactionadapter/SwipeActionAdapter.java

+19-4
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,25 @@ public boolean hasActions(int position){
8080
* @param position The position to perform the action on, sorted in descending order
8181
* for convenience.
8282
* @param direction The type of swipe that triggered the action
83-
* @return boolean indicating whether the item should be dismissed afterwards or not
83+
* @return boolean that indicates whether the list item should be dismissed or shown again.
8484
*/
8585
@Override
86-
public boolean onAction(ListView listView, int position, int direction){
87-
return mSwipeActionListener != null && mSwipeActionListener.onSwipe(position,direction);
86+
public boolean onPreAction(ListView listView, int position, int direction){
87+
return mSwipeActionListener != null && mSwipeActionListener.shouldDismiss(position, direction);
88+
}
89+
90+
/**
91+
* SwipeActionTouchListener.ActionCallbacks callback
92+
* We just link it through to our own interface
93+
*
94+
* @param listView The originating {@link ListView}.
95+
* @param position The positions to perform the action on, sorted in descending order
96+
* for convenience.
97+
* @param direction The type of swipe that triggered the action.
98+
*/
99+
@Override
100+
public void onAction(ListView listView, int[] position, int[] direction){
101+
if(mSwipeActionListener != null) mSwipeActionListener.onSwipe(position,direction);
88102
}
89103

90104
/**
@@ -166,6 +180,7 @@ public SwipeActionAdapter setSwipeActionListener(SwipeActionListener mSwipeActio
166180
*/
167181
public interface SwipeActionListener{
168182
public boolean hasActions(int position);
169-
public boolean onSwipe(int position, int direction);
183+
public boolean shouldDismiss(int position, int direction);
184+
public void onSwipe(int[] position, int[] direction);
170185
}
171186
}

0 commit comments

Comments
 (0)