网上ListView横向滑动删除Item这样的介绍也很多,但实用性不强,没有解决横向滑动和item的点击事件的冲突,废话少说,有图有真相,下面直接上代码
1:侧滑
2:侧滑的点击事件
3:iteam的点击事件
package com.zzn.demo;
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.Scroller;
import android.widget.Toast;
/**
* 侧拉删除控件
* @author poplar
*
*/
public class SwipeLayout extends FrameLayout {
private Status status = Status.Close;
private OnSwipeLayoutListener swipeLayoutListener;
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public OnSwipeLayoutListener getSwipeLayoutListener() {
return swipeLayoutListener;
}
public void setSwipeLayoutListener(OnSwipeLayoutListener swipeLayoutListener) {
this.swipeLayoutListener = swipeLayoutListener;
}
public static enum Status{
Close, Open, Draging
}
public static interface OnSwipeLayoutListener {
void onClose(SwipeLayout mSwipeLayout);
void onOpen(SwipeLayout mSwipeLayout);
void onDraging(SwipeLayout mSwipeLayout);
// 要去关闭
void onStartClose(SwipeLayout mSwipeLayout);
// 要去开启
void onStartOpen(SwipeLayout mSwipeLayout);
}
public SwipeLayout(Context context) {
this(context, null);
}
public SwipeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwipeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDragHelper = ViewDragHelper.create(this, 1.0f, mCallback);
}
ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
// c. 重写监听
@Override
public boolean tryCaptureView(View view, int id) {
return true;
}
// 限定移动范围
public int clampViewPositionHorizontal(View child, int left, int dx) {
// left
if(child == mFrontView){
if(left > 0){
return 0;
}else if(left < -mRange){
return -mRange;
}
}else if (child == mBackView) {
if(left > mWidth){
return mWidth;
}else if (left < mWidth - mRange) {
return mWidth - mRange;
}
}
return left;
};
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
// 传递事件
if(changedView == mFrontView){
mBackView.offsetLeftAndRight(dx);
}else if (changedView == mBackView) {
mFrontView.offsetLeftAndRight(dx);
}
dispatchSwipeEvent();
// 兼容老版本
invalidate();
};
public void onViewReleased(View releasedChild, float xvel, float yvel) {
if (xvel == 0 && mFrontView.getLeft() < -mRange / 2.0f) {
open();
}else if (xvel < 0) {
open();
}else {
close();
}
};
};
private ViewDragHelper mDragHelper;
private View mBackView;
private View mFrontView;
private int mHeight;
private int mWidth;
private int mRange;
// b. 传递触摸事件
@Override
public boolean onInterceptTouchEvent(android.view.MotionEvent ev) {
return mDragHelper.shouldInterceptTouchEvent(ev);
};
protected void dispatchSwipeEvent() {
if(swipeLayoutListener != null){
swipeLayoutListener.onDraging(this);
}
// 记录上一次的状态
Status preStatus = status;
// 更新当前状态
status = updateStatus();
if (preStatus != status && swipeLayoutListener != null) {
if (status == Status.Close) {
swipeLayoutListener.onClose(this);
} else if (status == Status.Open) {
swipeLayoutListener.onOpen(this);
} else if (status == Status.Draging) {
if(preStatus == Status.Close){
swipeLayoutListener.onStartOpen(this);
}else if (preStatus == Status.Open) {
swipeLayoutListener.onStartClose(this);
}
}
}
}
private Status updateStatus() {
int left = mFrontView.getLeft();
if(left == 0){
return Status.Close;
}else if (left == -mRange) {
return Status.Open;
}
return Status.Draging;
}
public void close() {
close(true);
}
public void close(boolean isSmooth){
int finalLeft = 0;
if(isSmooth){
//开始动画
if(mDragHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)){
ViewCompat.postInvalidateOnAnimation(this);
}
}else {
layoutContent(false);
}
}
public void open() {
open(true);
}
public void open(boolean isSmooth){
int finalLeft = -mRange;
if(isSmooth){
//开始动画
if(mDragHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)){
ViewCompat.postInvalidateOnAnimation(this);
}
}else {
layoutContent(true);
}
}
@Override
public void computeScroll() {
super.computeScroll();
if(mDragHelper.continueSettling(true)){
ViewCompat.postInvalidateOnAnimation(this);
}
}
// private boolean b = true;
float x;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.i("test", "ACTION_DOWN");
x = event.getX();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
Log.i("test", "ACTION_UP");
float daltX = Math.abs(x - event.getX());
if (daltX < 10) {
Toast.makeText(getContext(), "iteam点击。。。。",
Toast.LENGTH_SHORT).show();
} else {
Log.i("test", "终于进来了");
}
}
try {
mDragHelper.processTouchEvent(event);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
// 摆放位置
layoutContent(false);
}
private void layoutContent(boolean isOpen) {
// 摆放前View
Rect frontRect = computeFrontViewRect(isOpen);
mFrontView.layout(frontRect.left, frontRect.top, frontRect.right, frontRect.bottom);
// 摆放后View
Rect backRect = computeBackViewViaFront(frontRect);
mBackView.layout(backRect.left, backRect.top, backRect.right, backRect.bottom);
// 调整顺序, 把mFrontView前置
bringChildToFront(mFrontView);
}
private Rect computeBackViewViaFront(Rect frontRect) {
int left = frontRect.right;
return new Rect(left, 0, left + mRange, 0 + mHeight);
}
private Rect computeFrontViewRect(boolean isOpen) {
int left = 0;
if(isOpen){
left = -mRange;
}
return new Rect(left, 0, left + mWidth, 0 + mHeight);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// 当xml被填充完毕时调用
mBackView = getChildAt(0);
mFrontView = getChildAt(1);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeight = mFrontView.getMeasuredHeight();
mWidth = mFrontView.getMeasuredWidth();
mRange = mBackView.getMeasuredWidth();
}
}
xml部分
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe"
>
android:layout_height="match_parent"
android:orientation="horizontal" >
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#666666"
android:gravity="center"
android:text="待办"
android:textColor="#000000"
android:onClick="wait"/>
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#ffff00"
android:gravity="center"
android:text="缓办"
android:textColor="#000000" />
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="#ff0000"
android:gravity="center"
android:text="已办"
android:textColor="#000000" />
android:layout_width="match_parent"
android:layout_height="match_parent"
>
android:background="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/rl"
>
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:src="@drawable/ic_publish_chooser_img"
android:onClick="list2"
/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/icon_main"
android:layout_marginLeft="17dp"
android:layout_toRightOf="@+id/icon_main"
android:text="名字" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tv_name_main"
android:layout_below="@+id/tv_name_main"
android:layout_marginTop="10dp"
android:text="内容"
android:textSize="10dp"
android:maxLength="20" />
android:layout_width="1dp"
android:layout_height="15dp"
android:layout_alignBottom="@+id/tv_number_main"
android:layout_centerHorizontal="true"
android:background="#aaaaaa"
/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/view1"
android:layout_marginLeft="16dp"
android:layout_toRightOf="@+id/view1"
android:text="更新数量"
android:textSize="10dp" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/icon_main"
android:layout_alignLeft="@+id/tv_message_main"
android:text="数量"
android:textSize="10dp" />
android:layout_width="60dp"
android:layout_height="40dp"
android:gravity="center"
android:layout_alignBottom="@+id/tv_message_main"
android:layout_alignParentRight="true"
android:shadowColor="#A8A8A8"
android:shadowDx="0"
android:shadowDy="0"
android:shadowRadius="5"
android:text="订阅"
android:textColor="#000000"
android:textSize="20sp" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/tv_name_main"
android:visibility="gone"
/>
adapter
package com.zzn.demo;
import java.util.ArrayList;
import java.util.List;
import com.lidroid.xutils.BitmapUtils;
import com.zzn.demo.Findbean.tieBalb;
import com.zzn.demo.SwipeLayout.OnSwipeLayoutListener;
import android.content.Context;
import android.content.SyncStatusObserver;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class FindAdapter extends ArrayAdapter
private SpannableStringBuilder ssb;
private BitmapUtils bitmapUtils;
private View view;
private ArrayList
/**
* ViewHolder class for layout.
*
* Auto-created on 2015-09-11 13:48:03 by Android Layout Finder
* (http://www.buzzingandroid.com/tools/android-layout-finder)
*/
private static class ViewHolder {
public final com.zzn.demo.SwipeLayout rootView;
public final ImageView iconMain;
public final TextView tvNameMain;
public final TextView tvMessageMain;
public final TextView updaMain;
public final TextView tvNumberMain;
public final TextView butMain;
public final ProgressBar pbDingyue;
public final TextView tvWait;
public final TextView tvLow;
public final TextView tvFinsh;
public final RelativeLayout rl;
private ViewHolder(com.zzn.demo.SwipeLayout rootView,
ImageView iconMain, TextView tvNameMain,
TextView tvMessageMain, TextView updaMain,
TextView tvNumberMain, TextView butMain, ProgressBar pbDingyue,
TextView tvWait, TextView tvLow, TextView tvFinsh, RelativeLayout rl) {
this.rootView = rootView;
this.iconMain = iconMain;
this.tvNameMain = tvNameMain;
this.tvMessageMain = tvMessageMain;
this.updaMain = updaMain;
this.tvNumberMain = tvNumberMain;
this.butMain = butMain;
this.pbDingyue = pbDingyue;
this.tvWait = tvWait;
this.tvLow = tvLow;
this.tvFinsh = tvFinsh;
this.rl = rl;
}
public static ViewHolder create(com.zzn.demo.SwipeLayout rootView) {
RelativeLayout rl = (RelativeLayout)rootView.findViewById( R.id.rl );
TextView tvWait = (TextView) rootView.findViewById(R.id.tv_wait);
TextView tvLow = (TextView) rootView.findViewById(R.id.tv_low);
TextView tvFinsh = (TextView) rootView.findViewById(R.id.tv_finsh);
ImageView iconMain = (ImageView) rootView
.findViewById(R.id.icon_main);
TextView tvNameMain = (TextView) rootView
.findViewById(R.id.tv_name_main);
TextView tvMessageMain = (TextView) rootView
.findViewById(R.id.tv_message_main);
TextView tvNumberMain = (TextView) rootView
.findViewById(R.id.tv_number_main);
TextView updaMain = (TextView) rootView
.findViewById(R.id.upda_main);
TextView butMain = (TextView) rootView.findViewById(R.id.but_main);
ProgressBar pbDingyue = (ProgressBar) rootView
.findViewById(R.id.pb_dingyue);
return new ViewHolder(rootView, iconMain, tvNameMain,
tvMessageMain, updaMain, tvNumberMain, butMain, pbDingyue,
tvWait, tvLow, tvFinsh, rl);
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder vh;
view = convertView;
if (convertView == null) {
view = mInflater.inflate(R.layout.find_iteam, parent, false);
vh = ViewHolder.create((SwipeLayout) view);
view.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
Findbean.tieBalb item = getItem(position);
// TODOBind your data to the views here
bitmapUtils.display(vh.iconMain, item.icon_url);
vh.tvNameMain.setText(item.name);
vh.tvMessageMain.setText(item.placeholder);
vh.tvNumberMain.setText(item.subscribe_count + " 订阅");
/**
* 设置更新的数组颜色
*
*
*/
String text = "今日更新 " + item.today_updates;
ssb = new SpannableStringBuilder(text);
ssb.setSpan(new ForegroundColorSpan(Color.RED), 4, text.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);// 基本使用_1:为指定的区间设置指定的颜色
vh.updaMain.setText(ssb);
vh.tvWait.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getContext(), "待办", 0).show();
}
});
vh.tvLow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getContext(), "缓办", 0).show();
}
});
vh.tvFinsh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getContext(), "已办", 0).show();
}
});
SwipeLayout sl = (SwipeLayout)view;
sl.setSwipeLayoutListener(new OnSwipeLayoutListener() {
@Override
public void onStartOpen(SwipeLayout mSwipeLayout) {
// 要去开启时,先遍历所有已打开条目, 逐个关闭
System.out.println("-----onStartOpen------");
for (SwipeLayout layout : opendItems) {
layout.close();
}
opendItems.clear();
}
@Override
public void onStartClose(SwipeLayout mSwipeLayout) {
}
@Override
public void onOpen(SwipeLayout mSwipeLayout) {
// 添加进集合
opendItems.add(mSwipeLayout);
System.out.println("-----onOpen------");
}
@Override
public void onDraging(SwipeLayout mSwipeLayout) {
System.out.println("-----onDraging------");
}
@Override
public void onClose(SwipeLayout mSwipeLayout) {
// 移除集合
opendItems.remove(mSwipeLayout);
System.out.println("-----onClose------");
}
});
// vh.rl.setOnClickListener(new View.OnClickListener() {
//
// @Override
// public void onClick(View v) {
// // TODO Auto-generated method stub
// Toast.makeText(getContext(), "88888", 0).show();
//
// }
// });
return vh.rootView;
}
private LayoutInflater mInflater;
// Constructors
public FindAdapter(Context context, List
super(context, 0, objects);
this.mInflater = LayoutInflater.from(context);
bitmapUtils = new BitmapUtils(context);
bitmapUtils.configDefaultLoadingImage(R.drawable.munion_user_icon);
opendItems = new ArrayList
}
}
mainactivity,用了xutls和ZrcListView类库,自己下载吧
package com.zzn.demo;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;
import com.lidroid.xutils.view.annotation.event.OnItemClick;
import com.zzn.demo.SwipeLayout.Status;
import zrc.widget.Footable;
import zrc.widget.SimpleFooter;
import zrc.widget.SimpleHeader;
import zrc.widget.ZrcListView;
import zrc.widget.ZrcListView.OnItemClickListener;
import zrc.widget.ZrcListView.OnItemLongClickListener;
import zrc.widget.ZrcListView.OnStartListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.ViewDragHelper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private ZrcListView listView1;
private Handler handler;
protected ArrayAdapter adapter;
private String url;
private List
private float mLastMotionX;// 记住上次触摸屏的位置
private int deltaX;
private int back_width;
private float downX;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
url = ConfigURL.FIND_URL;
listView1 = (ZrcListView) findViewById(R.id.listView1);
handler = new Handler();
// 设置默认偏移量,主要用于实现透明标题栏功能。(可选)
float density = getResources().getDisplayMetrics().density;
listView1.setFirstTopOffset((int) (50 * density));
// 设置下拉刷新的样式(可选,但如果没有Header则无法下拉刷新)
SimpleHeader header = new SimpleHeader(this);
header.setTextColor(0xff0066aa);
header.setCircleColor(0xff33bbee);
listView1.setHeadable(header);
// 设置加载更多的样式(可选)
SimpleFooter header1 = new SimpleFooter(this);
header1.setCircleColor(0xff0066aa);
header1.setCircleColor(0xff33bbee);
listView1.setFootable(header1);
// 设置列表项出现动画(可选)
listView1.setItemAnimForTopIn(R.anim.topitem_in);
listView1.setItemAnimForBottomIn(R.anim.bottomitem_in);
loadMore();
// 加载更多事件回调(可选)
listView1.setOnLoadMoreStartListener(new OnStartListener() {
@Override
public void onStart() {
// TODO Auto-generated method stub
loadMore();
}
});
// 下拉刷新事件回调(可选)
listView1.setOnRefreshStartListener(new OnStartListener() {
@Override
public void onStart() {
refresh();
}
});
}
private void refresh() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
HttpUtils utils = new HttpUtils();
// 使用xUtils发送请求
utils.send(HttpMethod.GET, url, new RequestCallBack
// 访问成功, 在主线程运行
@Override
public void onSuccess(ResponseInfo
String result = responseInfo.result;
processingData(result);
System.out.println("<<<<<<<<<<<<<<<<<" + url);
listView1.setRefreshSuccess("加载成功");
}
// 访问失败, 在主线程运行
@Override
public void onFailure(HttpException error, String msg) {
error.printStackTrace();
}
});
}
}, 2 * 1000);
}
private void loadMore() {
HttpUtils utils = new HttpUtils();
// 使用xUtils发送请求
utils.send(HttpMethod.GET, url, new RequestCallBack
// 访问成功, 在主线程运行
@Override
public void onSuccess(ResponseInfo
String result = responseInfo.result;
processingData(result);
System.out.println("<<<<<<<<<<<<<<<<<" + url);
adapter.notifyDataSetChanged();
listView1.setRefreshSuccess("加载成功"); // 通知加载成功
listView1.startLoadMore(); // 开启LoadingMore功能
}
// 访问失败, 在主线程运行
@Override
public void onFailure(HttpException error, String msg) {
error.printStackTrace();
}
});
// tv_wait.setOnClickListener(this);
}
protected void processingData(String result) {
Gson gson = new Gson();
Findbean fromJson = gson.fromJson(result, Findbean.class);
System.out.println(">>>>>>>>>>>" + url);
category_list1 = fromJson.data.categories.category_list;
System.out.println("--------" + category_list1);
adapter = new FindAdapter(this, category_list1);
listView1.setAdapter(adapter);
}
public void wait(View v) {
Toast.makeText(getApplicationContext(), "待办", 0).show();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.tv_wait:
Toast.makeText(getApplicationContext(), "待办", 0).show();
break;
case R.id.tv_low:
Toast.makeText(getApplicationContext(), "缓办", 0).show();
break;
case R.id.tv_finsh:
Toast.makeText(getApplicationContext(), "已办", 0).show();
break;
default:
break;
}
}
public void list(View v) {
Toast.makeText(getApplicationContext(), "1111111", 0).show();
}
public void list2(View v) {
}
}
bean类
package com.zzn.demo;
import java.util.List;
public class Findbean {
public Find data;
public String message;
public class Find {
public tieBa categories;
public GoodComment god_comment;
public List
public List my_top_category_list;
public Rotate rotate_banner;
}
/**
* 热门吧
* @author lzp_448063828
*/
public class tieBa{
public int category_count;
public List
public int id;
public String intro;
public String name;
public String priority;
}
/**
* 神评论简介
* @author lzp_448063828
*/
public class GoodComment{
public String count;
public String icon;
public String intro;
public String name;
}
public class Rotate{
public List
public int count;
}
public class Banners{
public BannerUrl banner_url;
public String schema_url;
}
public class BannerUrl{
public int height;
public int id;
public String title;
public String uri;
public List
public int width;
}
public class URLList{
public String url;
}
public class Category{
public int allow_gif;
public int allow_multi_image;
public int allow_text;
public int allow_text_and_pic;
public int allow_video;
public int big_category_id;
public String buttons;
public String channels;
public int dedup;
public String extra;
public boolean has_timeliness;
public String icon;
public String icon_url;
public int id;
public String intro;
public int is_recommend;
public boolean is_top;
public List material_bar;
public String mix_weight;
public String name;
public String placeholder;
public int post_rule_id;
public String priority;
public int share_type;
public String share_url;
public String small_icon;
public String small_icon_url;
public int status;
public String subscribe_count;
public String tag;
public int today_updates;
public String top_end_time;
public String top_start_time;
public String total_updates;
public int type;
public boolean visible;
}
public class tieBalb{
public int allow_gif;
public int allow_multi_image;
public int allow_text;
public int allow_text_and_pic;
public int allow_video;
public int big_category_id;
public String buttons;
public String channels;
public int dedup;
public String extra;
public boolean has_timeliness;
public String icon;
public String icon_url;
public int id;
public String intro;
public int is_recommend;
public boolean is_top;
public List material_bar;
public String mix_weight;
public String name;
public String placeholder;
public int post_rule_id;
public String priority;
public int share_type;
public String share_url;
public String small_icon;
public String small_icon_url;
public int status;
public String subscribe_count;
public String tag;
public int today_updates;
public String top_end_time;
public String top_start_time;
public String total_updates;
public int type;
public boolean visible;
}
}
由于用的是截取的接口就不贴上了