forked from wdullaer/SwipeActionAdapter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSwipeViewGroup.java
217 lines (190 loc) · 6.6 KB
/
SwipeViewGroup.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
* Copyright 2014 Wouter Dullaert
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wdullaer.swipeactionadapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Checkable;
import android.widget.FrameLayout;
/**
* Class to hold a ListView item and the swipe backgrounds
*
* Created by wdullaer on 22.06.14.
*/
public class SwipeViewGroup extends FrameLayout implements Checkable {
private View contentView = null;
private int visibleView = SwipeDirections.DIRECTION_NEUTRAL;
private SparseArray<View> mBackgroundMap = new SparseArray<>();
private OnTouchListener swipeTouchListener;
private boolean checked;
/**
* Standard android View constructor
*
* @param context
*/
public SwipeViewGroup(Context context) {
super(context);
initialize();
}
/**
* Standard android View constructor
*
* @param context
* @param attrs
*/
public SwipeViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
/**
* Standard android View constructor
*
* @param context
* @param attrs
* @param defStyle
*/
public SwipeViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
/**
* Common code for all the constructors
*/
private void initialize() {
// Allows click events to reach the ListView in case the row has a clickable View like a Button
// FIXME: probably messes with accessibility. Doesn't fix root cause (see onTouchEvent)
setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
}
/**
* Add a View to the background of the Layout. The background should have the same height
* as the contentView
*
* @param background The View to be added to the Layout
* @param direction The key to be used to find it again
* @return A reference to the a layout so commands can be chained
*/
public SwipeViewGroup addBackground(View background, int direction){
if(mBackgroundMap.get(direction) != null) removeView(mBackgroundMap.get(direction));
background.setVisibility(View.INVISIBLE);
mBackgroundMap.put(direction, background);
addView(background);
return this;
}
/**
* Show the View linked to a key. Don't do anything if the key is not found
*
* @param direction The key of the View to be shown
* @param dimBackground Indicates whether the background should be dimmed
*/
public void showBackground(int direction, boolean dimBackground){
if(SwipeDirections.DIRECTION_NEUTRAL != direction && mBackgroundMap.get(direction) == null) return;
if(SwipeDirections.DIRECTION_NEUTRAL != visibleView)
mBackgroundMap.get(visibleView).setVisibility(View.INVISIBLE);
if(SwipeDirections.DIRECTION_NEUTRAL != direction) {
mBackgroundMap.get(direction).setVisibility(View.VISIBLE);
mBackgroundMap.get(direction).setAlpha(dimBackground ? 0.4f : 1);
}
visibleView = direction;
}
/**
* Add a contentView to the Layout
*
* @param contentView The View to be added
* @return A reference to the layout so commands can be chained
*/
public SwipeViewGroup setContentView(View contentView){
if(this.contentView != null) removeView(contentView);
addView(contentView);
this.contentView = contentView;
return this;
}
/**
* Returns the current contentView of the Layout
*
* @return contentView of the Layout
*/
public View getContentView(){
return contentView;
}
/**
* Move all backgrounds to the edge of the Layout so they can be swiped in
*/
public void translateBackgrounds(){
this.setClipChildren(false);
for(int i=0;i<mBackgroundMap.size();i++){
int key = mBackgroundMap.keyAt(i);
View value = mBackgroundMap.valueAt(i);
value.setTranslationX(-Integer.signum(key)*value.getWidth());
}
}
/**
* Set a touch listener the SwipeViewGroup will watch: once the OnTouchListener is interested in
* events, the SwipeViewGroup will stop propagating touch events to its children
*
* @param swipeTouchListener The OnTouchListener to watch
* @return A reference to the layout so commands can be chained
*/
public SwipeViewGroup setSwipeTouchListener(OnTouchListener swipeTouchListener) {
this.swipeTouchListener = swipeTouchListener;
return this;
}
@Override
public Object getTag() {
if(contentView != null) return contentView.getTag();
else return null;
}
@Override
public void setTag(Object tag) {
if(contentView != null) contentView.setTag(tag);
}
@Override
public Object getTag(int key) {
if(contentView != null) return contentView.getTag(key);
else return null;
}
@Override
public void setTag(int key, Object tag) {
if(contentView != null) contentView.setTag(key, tag);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Start tracking the touch when a child is processing it
return super.onInterceptTouchEvent(ev) || swipeTouchListener.onTouch(this, ev);
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent ev) {
// Finish the swipe gesture: our parent will no longer do it if this function is called
return swipeTouchListener.onTouch(this, ev);
}
@Override
public void setChecked(boolean checked) {
this.checked = checked;
if ( contentView != null && contentView instanceof Checkable ) {
((Checkable)contentView).setChecked(checked);
}
}
@Override
public boolean isChecked() {
return checked;
}
@Override
public void toggle() {
this.setChecked( ! checked );
}
}