SlideDeleteView.java
public class SlideDeleteView extends FrameLayout {
private View item_content;
private View item_menu;
private int itemContentWidth;
private int itemContentHeight;
private int itemMenuWidth;
private int itemMenuHeight;
private Scroller scroller;
public SlideDeleteView(Context context) {
super(context);
}
public SlideDeleteView(Context context, AttributeSet attrs) {
super(context, attrs);
scroller = new Scroller(context);
}
public SlideDeleteView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
item_content = getChildAt(0);
item_menu = getChildAt(1);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
itemContentWidth = item_content.getMeasuredWidth();
itemContentHeight = item_content.getMeasuredHeight();
itemMenuWidth = item_menu.getMeasuredWidth();
itemMenuHeight = item_menu.getMeasuredHeight();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
item_menu.layout(itemContentWidth,0,itemContentWidth+itemMenuWidth,itemContentHeight);
}
public void closeMenu(){
scroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), -getScrollY());
invalidate();
if(onStatusChangedListner != null){
onStatusChangedListner.onClose(this);
}
}
public void openMenu(){
scroller.startScroll(getScrollX(), getScrollY(), itemMenuWidth - getScrollX(), -getScrollY());
invalidate();
if(onStatusChangedListner != null){
onStatusChangedListner.onOpen(this);
}
}
private int lastX,lastY;
private int downX,downY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean isIntercept = false;
int action = ev.getAction();
int eventX = (int) ev.getRawX();
int eventY = (int) ev.getRawY();
switch (action){
case MotionEvent.ACTION_DOWN:
downX = lastX = eventX;
downY = lastY = eventY;
if(onStatusChangedListner != null){
onStatusChangedListner.onDown(this);
}
break;
case MotionEvent.ACTION_MOVE:
int totalX = Math.abs(eventX - downX);
if(totalX > 8){
isIntercept = true;
}
break;
}
return isIntercept;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int moveX ;
int action = event.getAction();
int eventX = (int) event.getRawX();
int eventY = (int) event.getRawY();
switch (action){
case MotionEvent.ACTION_DOWN:
downX = lastX = eventX;
downY = lastY = eventY;
break;
case MotionEvent.ACTION_MOVE:
int dx = eventX-lastX;
moveX = getScrollX()-dx;
if(moveX>itemMenuWidth){
moveX = itemMenuWidth;
}else if(moveX<0){
moveX = 0;
}
scrollTo(moveX,getScrollY());
lastX = eventX;
lastY = eventY;
//实现子视图对父视图的反拦截
int totalX = Math.abs(eventX - downX);//距离down时,水平移动的距离
int totalY = Math.abs(eventY - downY);//距离down时,垂直方向移动的距离
if(totalX > totalY && totalX > 10){
this.getParent().requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
moveX = getScrollX();
Log.e("TAG", "moveX:"+moveX);
if(moveX >= itemMenuWidth/2){
openMenu();
}else if(moveX<itemMenuWidth/2){
closeMenu();
}
break;
}
return true;
}
@Override
public void computeScroll() {
if(scroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(),scroller.getCurrY());
invalidate();
}
}
public interface OnStatusChangedListener {
public void onOpen(SlideDeleteView sdv);//当打开menu时
public void onClose(SlideDeleteView sdv);//当关闭menu时
public void onDown(SlideDeleteView sdv);//当执行ACTION_DOWN时
}
private OnStatusChangedListener onStatusChangedListner;
public void setOnStatusChangedListner(OnStatusChangedListener onStatusChangedListner) {
this.onStatusChangedListner = onStatusChangedListner;
}
}
MainActivity.java
public class MainActivity extends Activity implements View.OnClickListener {
private ListView listView;
private List<String> data;
private BaseAdapter adapter;
private SlideDeleteView currentSlideLayout;
private SlideDeleteView.OnStatusChangedListener listener = new SlideDeleteView.OnStatusChangedListener(){
@Override
public void onOpen(SlideDeleteView sdv) {
currentSlideLayout = sdv;
}
@Override
public void onClose(SlideDeleteView sdv) {
if(currentSlideLayout==sdv){
currentSlideLayout=null;
}
}
@Override
public void onDown(SlideDeleteView sdv) {
if(currentSlideLayout != sdv && currentSlideLayout != null){
currentSlideLayout.closeMenu();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
initData();
adapter = new CommonBaseAdapter<String>(this,data, R.layout.item_layout) {
@Override
public void convert(ViewHolder holder, int position) {
holder.setText(R.id.item_content,data.get(position));
holder.setOnclickListener(R.id.item_content, MainActivity.this);
holder.setOnclickListener(R.id.item_menu,MainActivity.this);
holder.setTag(R.id.item_content, position);
holder.setTag(R.id.item_menu,position);
SlideDeleteView slideLayout = (SlideDeleteView) holder.getConvertView();
slideLayout.setOnStatusChangedListner(listener);
}
};
listView.setAdapter(adapter);
}
private void initData() {
data = new ArrayList();
for (int i=0;i<100;i++){
data.add("content"+i);
}
}
@Override
public void onClick(View v) {
int position = (int) v.getTag();
String string = data.get(position);
SlideDeleteView sdv = (SlideDeleteView) v.getParent();
switch (v.getId()){
case R.id.item_content:
sdv.closeMenu();
Toast.makeText(MainActivity.this, string, Toast.LENGTH_SHORT).show();
break;
case R.id.item_menu:
data.remove(position);
adapter.notifyDataSetChanged();
//更新界面以后,还需要将删除位置的menu关闭
sdv.closeMenu();
break;
}
}
}