本例子实现了滑动删除ListView的Itemdemo的效果、大家都知道、这种创意是来源于IOS的、左滑删除的功能、在Android上面实现比较 麻烦、本例子中不仅实现了左滑删除功能、还实现了左滑赞、左滑分享、左滑收藏等功能、当然大家也可以根据自己项目的需求来修改功能、QQ和微信也实现了相同的功能、大家可以看看。
大神已经把需要的自定义控件都封装成类,我只是做了一下简单的了解,以及使用,时间有限,并没有仔细研究.
工程目录如下leftDelete、diffeentLeftDelete是实现左滑效果的类 ,,swipemenulistview是大神封装好的类,没有太详细的说明,看着有点累,源码已经贴在本文后面了
1.新建leftDelete类,(左滑的功能是封装好了的哈、上面贴出来的只是调用方法、更多使用方法、大家可以下载源代码慢慢研究)
1 package com.example.android_listview;
2
3 import java.util.List;
4
5 import swipemenulistview.SwipeMenu;
6 import swipemenulistview.SwipeMenuCreator;
7 import swipemenulistview.SwipeMenuItem;
8 import swipemenulistview.SwipeMenuListView;
9 import swipemenulistview.SwipeMenuListView.OnMenuItemClickListener;
10 import swipemenulistview.SwipeMenuListView.OnSwipeListener;
11
12 import android.app.Activity;
13 import android.content.ComponentName;
14 import android.content.Intent;
15 import android.content.pm.ApplicationInfo;
16 import android.content.pm.ResolveInfo;
17 import android.graphics.Color;
18 import android.graphics.drawable.ColorDrawable;
19 import android.net.Uri;
20 import android.os.Bundle;
21 import android.util.TypedValue;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.AdapterView;
25 import android.widget.AdapterView.OnItemLongClickListener;
26 import android.widget.BaseAdapter;
27 import android.widget.ImageView;
28 import android.widget.TextView;
29 import android.widget.Toast;
30
31
32
33 public class leftDelete extends Activity{
34 private List<ApplicationInfo> mAppList;
35 private AppAdapter mAdapter;
36 private SwipeMenuListView mListView;
37
38 @Override
39 protected void onCreate(Bundle savedInstanceState) {
40 super.onCreate(savedInstanceState);
41 setContentView(R.layout.activity_list);
42
43 mAppList = getPackageManager().getInstalledApplications(0);
44
45 mListView = (SwipeMenuListView) findViewById(R.id.listView);
46 mAdapter = new AppAdapter();
47 mListView.setAdapter(mAdapter);
48
49 // step 1. create a MenuCreator
50 SwipeMenuCreator creator = new SwipeMenuCreator() {
51
52 @Override
53 public void create(SwipeMenu menu) {
54 // create "open" item
55 SwipeMenuItem openItem = new SwipeMenuItem(
56 getApplicationContext());
57 // set item background
58 openItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
59 0xCE)));
60 // set item width
61 openItem.setWidth(dp2px(90));
62 // set item title
63 openItem.setTitle("Open");
64 // set item title fontsize
65 openItem.setTitleSize(18);
66 // set item title font color
67 openItem.setTitleColor(Color.WHITE);
68 // add to menu
69 menu.addMenuItem(openItem);
70
71 // create "delete" item
72 SwipeMenuItem deleteItem = new SwipeMenuItem(
73 getApplicationContext());
74 // set item background
75 deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,
76 0x3F, 0x25)));
77 // set item width
78 deleteItem.setWidth(dp2px(90));
79 // set a icon
80 deleteItem.setIcon(R.drawable.ic_delete);
81 // add to menu
82 menu.addMenuItem(deleteItem);
83 }
84 };
85 // set creator
86 mListView.setMenuCreator(creator);
87
88 // step 2. listener item click event
89 mListView.setOnMenuItemClickListener(new OnMenuItemClickListener() {
90 @Override
91 public void onMenuItemClick(int position, SwipeMenu menu, int index) {
92 ApplicationInfo item = mAppList.get(position);
93 switch (index) {
94 case 0:
95 // open
96 open(item);
97 break;
98 case 1:
99 // delete
100 //delete(item);
101 mAppList.remove(position);
102 mAdapter.notifyDataSetChanged();
103 break;
104 }
105 }
106 });
107
108 // set SwipeListener
109 mListView.setOnSwipeListener(new OnSwipeListener() {
110
111 @Override
112 public void onSwipeStart(int position) {
113 // swipe start
114 }
115
116 @Override
117 public void onSwipeEnd(int position) {
118 // swipe end
119 }
120 });
121
122 // other setting
123 // listView.setCloseInterpolator(new BounceInterpolator());
124
125 // test item long click
126 mListView.setOnItemLongClickListener(new OnItemLongClickListener() {
127
128 @Override
129 public boolean onItemLongClick(AdapterView<?> parent, View view,
130 int position, long id) {
131 Toast.makeText(getApplicationContext(), position + " long click", 0).show();
132 return false;
133 }
134 });
135
136 }
137
138 private void delete(ApplicationInfo item) {
139 // delete app
140 try {
141 Intent intent = new Intent(Intent.ACTION_DELETE);
142 intent.setData(Uri.fromParts("package", item.packageName, null));
143 startActivity(intent);
144 } catch (Exception e) {
145 }
146 }
147
148 private void open(ApplicationInfo item) {
149 // open app
150 Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
151 resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
152 resolveIntent.setPackage(item.packageName);
153 List<ResolveInfo> resolveInfoList = getPackageManager()
154 .queryIntentActivities(resolveIntent, 0);
155 if (resolveInfoList != null && resolveInfoList.size() > 0) {
156 ResolveInfo resolveInfo = resolveInfoList.get(0);
157 String activityPackageName = resolveInfo.activityInfo.packageName;
158 String className = resolveInfo.activityInfo.name;
159
160 Intent intent = new Intent(Intent.ACTION_MAIN);
161 intent.addCategory(Intent.CATEGORY_LAUNCHER);
162 ComponentName componentName = new ComponentName(
163 activityPackageName, className);
164
165 intent.setComponent(componentName);
166 startActivity(intent);
167 }
168 }
169
170 class AppAdapter extends BaseAdapter {
171
172 @Override
173 public int getCount() {
174 return mAppList.size();
175 }
176
177 @Override
178 public ApplicationInfo getItem(int position) {
179 return mAppList.get(position);
180 }
181
182 @Override
183 public long getItemId(int position) {
184 return position;
185 }
186
187 @Override
188 public View getView(int position, View convertView, ViewGroup parent) {
189 if (convertView == null) {
190 convertView = View.inflate(getApplicationContext(),
191 R.layout.item_list_app, null);
192 new ViewHolder(convertView);
193 }
194 ViewHolder holder = (ViewHolder) convertView.getTag();
195 ApplicationInfo item = getItem(position);
196 holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
197 holder.tv_name.setText(item.loadLabel(getPackageManager()));
198 return convertView;
199 }
200
201 class ViewHolder {
202 ImageView iv_icon;
203 TextView tv_name;
204
205 public ViewHolder(View view) {
206 iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
207 tv_name = (TextView) view.findViewById(R.id.tv_name);
208 view.setTag(this);
209 }
210 }
211 }
212
213 private int dp2px(int dp) {
214 return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
215 getResources().getDisplayMetrics());
216 }
217 }
2.布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<swipemenulistview.SwipeMenuListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
View Code
3.androidMainfest.xml中注册activity
<activity android:name="com.example.android_listview.leftDelete"></activity>
<activity android:name="com.example.android_listview.differentLeftDelete"></activity>
View Code
4.主函数调用,这里的页面跳转一般在点击事件中实现,即button按钮的响应事件
//打开新页面
Intent intent=new Intent(MainActivity.this, leftDelete.class);
MainActivity.this.startActivity(intent);
至此简单的左滑删除就完成了,效果如下
要实现不同的左滑效果,只需把leftDelete类稍作修改就可以了,例如
代码如下
package com.example.android_listview;
import java.util.List;
import swipemenulistview.SwipeMenu;
import swipemenulistview.SwipeMenuCreator;
import swipemenulistview.SwipeMenuItem;
import swipemenulistview.SwipeMenuListView;
import swipemenulistview.SwipeMenuListView.OnMenuItemClickListener;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class differentLeftDelete extends Activity{
private List<ApplicationInfo> mAppList;
private AppAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
mAppList=getPackageManager().getInstalledApplications(0);
SwipeMenuListView listView=(SwipeMenuListView) findViewById(R.id.listView);
mAdapter=new AppAdapter();
listView.setAdapter(mAdapter);
//step1.create a MeunCreator
SwipeMenuCreator creator=new SwipeMenuCreator() {
@Override
public void create(SwipeMenu menu) {
// Create different menus depending on the view type
switch (menu.getViewType()) {
case 0:
createMenu1(menu);
break;
case 1:
createMenu2(menu);
break;
case 2:
createMenu3(menu);
break;
}
}
private void createMenu1(SwipeMenu menu){
SwipeMenuItem item1=new SwipeMenuItem(getApplicationContext());
item1.setBackground(new ColorDrawable(Color.rgb(0xE5, 0x18,
0x5E)));
item1.setWidth(dp2px(90));
item1.setIcon(R.drawable.ic_action_favorite);
menu.addMenuItem(item1);
SwipeMenuItem item2=new SwipeMenuItem(getApplicationContext());
item2.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
0xCE)));
item2.setWidth(dp2px(90));
item2.setIcon(R.drawable.ic_action_good);
menu.addMenuItem(item2);
}
private void createMenu2(SwipeMenu menu){
SwipeMenuItem item1=new SwipeMenuItem(getApplicationContext());
item1.setBackground(new ColorDrawable(Color.rgb(0xE5, 0xE0,
0x3F)));
item1.setWidth(dp2px(90));
item1.setIcon(R.drawable.ic_action_important);
menu.addMenuItem(item1);
SwipeMenuItem item2=new SwipeMenuItem(getApplicationContext());
item2.setBackground(new ColorDrawable(Color.rgb(0xF9,
0x3F, 0x25)));
item2.setWidth(dp2px(90));
item2.setIcon(R.drawable.ic_action_discard);
menu.addMenuItem(item2);
}
private void createMenu3(SwipeMenu menu){
SwipeMenuItem item1 = new SwipeMenuItem(
getApplicationContext());
item1.setBackground(new ColorDrawable(Color.rgb(0x30, 0xB1,
0xF5)));
item1.setWidth(dp2px(90));
item1.setIcon(R.drawable.ic_action_about);
menu.addMenuItem(item1);
SwipeMenuItem item2 = new SwipeMenuItem(
getApplicationContext());
item2.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
0xCE)));
item2.setWidth(dp2px(90));
item2.setIcon(R.drawable.ic_action_share);
menu.addMenuItem(item2);
}
};
//set oreator
listView.setMenuCreator(creator);
//step 2. listener item click event
listView.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public void onMenuItemClick(int position, SwipeMenu menu, int index) {
// TODO Auto-generated method stub
ApplicationInfo item=mAppList.get(position);
switch (index) {
case 0:
// open
break;
case 1:
//delete
//delete(item);
mAppList.remove(position);
mAdapter.notifyDataSetChanged();
break;
}
}
});
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getResources().getDisplayMetrics());
}
class AppAdapter extends BaseAdapter {
@Override
public int getCount() {
return mAppList.size();
}
@Override
public ApplicationInfo getItem(int position) {
return mAppList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
// menu type count
return 3;
}
@Override
public int getItemViewType(int position) {
// current menu type
return position % 3;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(getApplicationContext(),
R.layout.item_list_app, null);
new ViewHolder(convertView);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
ApplicationInfo item = getItem(position);
holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
holder.tv_name.setText(item.loadLabel(getPackageManager()));
return convertView;
}
class ViewHolder {
ImageView iv_icon;
TextView tv_name;
public ViewHolder(View view) {
iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
tv_name = (TextView) view.findViewById(R.id.tv_name);
view.setTag(this);
}
}
}
}
View Code
其他步骤同上。
下面我把大神封装的源码贴出来
新建SwipeMenu类,代码如下
package swipemenulistview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
/**
*
* @author baoyz
* @date 2014-8-23
*
*/
public class SwipeMenu {
private Context mContext;
private List<SwipeMenuItem> mItems;
private int mViewType;
public SwipeMenu(Context context) {
mContext = context;
mItems = new ArrayList<SwipeMenuItem>();
}
public Context getContext() {
return mContext;
}
public void addMenuItem(SwipeMenuItem item) {
mItems.add(item);
}
public void removeMenuItem(SwipeMenuItem item) {
mItems.remove(item);
}
public List<SwipeMenuItem> getMenuItems() {
return mItems;
}
public SwipeMenuItem getMenuItem(int index) {
return mItems.get(index);
}
public int getViewType() {
return mViewType;
}
public void setViewType(int viewType) {
this.mViewType = viewType;
}
}
View Code
新建SwipeMenuAdapter类,代码如下
package swipemenulistview;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.WrapperListAdapter;
import swipemenulistview.SwipeMenuListView.OnMenuItemClickListener;
import swipemenulistview.SwipeMenuView.OnSwipeItemClickListener;
/**
*
* @author baoyz
* @date 2014-8-24
*
*/
public class SwipeMenuAdapter implements WrapperListAdapter,
OnSwipeItemClickListener {
private ListAdapter mAdapter;
private Context mContext;
private OnMenuItemClickListener onMenuItemClickListener;
public SwipeMenuAdapter(Context context, ListAdapter adapter) {
mAdapter = adapter;
mContext = context;
}
@Override
public int getCount() {
return mAdapter.getCount();
}
@Override
public Object getItem(int position) {
return mAdapter.getItem(position);
}
@Override
public long getItemId(int position) {
return mAdapter.getItemId(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SwipeMenuLayout layout = null;
if (convertView == null) {
View contentView = mAdapter.getView(position, convertView, parent);
SwipeMenu menu = new SwipeMenu(mContext);
menu.setViewType(mAdapter.getItemViewType(position));
createMenu(menu);
SwipeMenuView menuView = new SwipeMenuView(menu,
(SwipeMenuListView) parent);
menuView.setOnSwipeItemClickListener(this);
SwipeMenuListView listView = (SwipeMenuListView) parent;
layout = new SwipeMenuLayout(contentView, menuView,
listView.getCloseInterpolator(),
listView.getOpenInterpolator());
layout.setPosition(position);
} else {
layout = (SwipeMenuLayout) convertView;
layout.closeMenu();
layout.setPosition(position);
View view = mAdapter.getView(position, layout.getContentView(),
parent);
}
return layout;
}
public void createMenu(SwipeMenu menu) {
// Test Code
SwipeMenuItem item = new SwipeMenuItem(mContext);
item.setTitle("Item 1");
item.setBackground(new ColorDrawable(Color.GRAY));
item.setWidth(300);
menu.addMenuItem(item);
item = new SwipeMenuItem(mContext);
item.setTitle("Item 2");
item.setBackground(new ColorDrawable(Color.RED));
item.setWidth(300);
menu.addMenuItem(item);
}
@Override
public void onItemClick(SwipeMenuView view, SwipeMenu menu, int index) {
if (onMenuItemClickListener != null) {
onMenuItemClickListener.onMenuItemClick(view.getPosition(), menu,
index);
}
}
public void setOnMenuItemClickListener(
OnMenuItemClickListener onMenuItemClickListener) {
this.onMenuItemClickListener = onMenuItemClickListener;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
mAdapter.registerDataSetObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
mAdapter.unregisterDataSetObserver(observer);
}
@Override
public boolean areAllItemsEnabled() {
return mAdapter.areAllItemsEnabled();
}
@Override
public boolean isEnabled(int position) {
return mAdapter.isEnabled(position);
}
@Override
public boolean hasStableIds() {
return mAdapter.hasStableIds();
}
@Override
public int getItemViewType(int position) {
return mAdapter.getItemViewType(position);
}
@Override
public int getViewTypeCount() {
return mAdapter.getViewTypeCount();
}
@Override
public boolean isEmpty() {
return mAdapter.isEmpty();
}
@Override
public ListAdapter getWrappedAdapter() {
return mAdapter;
}
}
View Code
新建接口SwipeMenuCreator,代码如下
package swipemenulistview;
/**
*
* @author baoyz
* @date 2014-8-24
*
*/
public interface SwipeMenuCreator {
void create(SwipeMenu menu);
}
View Code
新建类SwipeMenuItem,代码如下
package swipemenulistview;
import android.content.Context;
import android.graphics.drawable.Drawable;
/**
*
* @author baoyz
* @date 2014-8-23
*
*/
public class SwipeMenuItem {
private int id;
private Context mContext;
private String title;
private Drawable icon;
private Drawable background;
private int titleColor;
private int titleSize;
private int width;
public SwipeMenuItem(Context context) {
mContext = context;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTitleColor() {
return titleColor;
}
public int getTitleSize() {
return titleSize;
}
public void setTitleSize(int titleSize) {
this.titleSize = titleSize;
}
public void setTitleColor(int titleColor) {
this.titleColor = titleColor;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitle(int resId) {
setTitle(mContext.getString(resId));
}
public Drawable getIcon() {
return icon;
}
public void setIcon(Drawable icon) {
this.icon = icon;
}
public void setIcon(int resId) {
this.icon = mContext.getResources().getDrawable(resId);
}
public Drawable getBackground() {
return background;
}
public void setBackground(Drawable background) {
this.background = background;
}
public void setBackground(int resId) {
this.background = mContext.getResources().getDrawable(resId);
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
}
View Code
新建SwipeMenuLayout类,代码如下
package swipemenulistview;
import android.content.Context;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.widget.ScrollerCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;
/**
*
* @author baoyz
* @date 2014-8-23
*
*/
public class SwipeMenuLayout extends FrameLayout {
private static final int CONTENT_VIEW_ID = 1;
private static final int MENU_VIEW_ID = 2;
private static final int STATE_CLOSE = 0;
private static final int STATE_OPEN = 1;
private View mContentView;
private SwipeMenuView mMenuView;
private int mDownX;
private int state = STATE_CLOSE;
private GestureDetectorCompat mGestureDetector;
private OnGestureListener mGestureListener;
private boolean isFling;
private int MIN_FLING = dp2px(15);
private int MAX_VELOCITYX = -dp2px(500);
private ScrollerCompat mOpenScroller;
private ScrollerCompat mCloseScroller;
private int mBaseX;
private int position;
private Interpolator mCloseInterpolator;
private Interpolator mOpenInterpolator;
public SwipeMenuLayout(View contentView, SwipeMenuView menuView) {
this(contentView, menuView, null, null);
}
public SwipeMenuLayout(View contentView, SwipeMenuView menuView,
Interpolator closeInterpolator, Interpolator openInterpolator) {
super(contentView.getContext());
mCloseInterpolator = closeInterpolator;
mOpenInterpolator = openInterpolator;
mContentView = contentView;
mMenuView = menuView;
mMenuView.setLayout(this);
init();
}
// private SwipeMenuLayout(Context context, AttributeSet attrs, int
// defStyle) {
// super(context, attrs, defStyle);
// }
private SwipeMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
private SwipeMenuLayout(Context context) {
super(context);
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
mMenuView.setPosition(position);
}
private void init() {
setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
mGestureListener = new SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
isFling = false;
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
// TODO
if ((e1.getX() - e2.getX()) > MIN_FLING
&& velocityX < MAX_VELOCITYX) {
isFling = true;
}
// Log.i("byz", MAX_VELOCITYX + ", velocityX = " + velocityX);
return super.onFling(e1, e2, velocityX, velocityY);
}
};
mGestureDetector = new GestureDetectorCompat(getContext(),
mGestureListener);
// mScroller = ScrollerCompat.create(getContext(), new
// BounceInterpolator());
if (mCloseInterpolator != null) {
mCloseScroller = ScrollerCompat.create(getContext(),
mCloseInterpolator);
} else {
mCloseScroller = ScrollerCompat.create(getContext());
}
if (mOpenInterpolator != null) {
mOpenScroller = ScrollerCompat.create(getContext(),
mOpenInterpolator);
} else {
mOpenScroller = ScrollerCompat.create(getContext());
}
LayoutParams contentParams = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
mContentView.setLayoutParams(contentParams);
if (mContentView.getId() < 1) {
mContentView.setId(CONTENT_VIEW_ID);
}
mMenuView.setId(MENU_VIEW_ID);
mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
addView(mContentView);
addView(mMenuView);
// if (mContentView.getBackground() == null) {
// mContentView.setBackgroundColor(Color.WHITE);
// }
// in android 2.x, MenuView height is MATCH_PARENT is not work.
// getViewTreeObserver().addOnGlobalLayoutListener(
// new OnGlobalLayoutListener() {
// @Override
// public void onGlobalLayout() {
// setMenuHeight(mContentView.getHeight());
// // getViewTreeObserver()
// // .removeGlobalOnLayoutListener(this);
// }
// });
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
public boolean onSwipe(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = (int) event.getX();
isFling = false;
break;
case MotionEvent.ACTION_MOVE:
// Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX());
int dis = (int) (mDownX - event.getX());
if (state == STATE_OPEN) {
dis += mMenuView.getWidth();
}
swipe(dis);
break;
case MotionEvent.ACTION_UP:
if (isFling || (mDownX - event.getX()) > (mMenuView.getWidth() / 2)) {
// open
smoothOpenMenu();
} else {
// close
smoothCloseMenu();
return false;
}
break;
}
return true;
}
public boolean isOpen() {
return state == STATE_OPEN;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
private void swipe(int dis) {
if (dis > mMenuView.getWidth()) {
dis = mMenuView.getWidth();
}
if (dis < 0) {
dis = 0;
}
mContentView.layout(-dis, mContentView.getTop(),
mContentView.getWidth() - dis, getMeasuredHeight());
mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
mContentView.getWidth() + mMenuView.getWidth() - dis,
mMenuView.getBottom());
}
@Override
public void computeScroll() {
if (state == STATE_OPEN) {
if (mOpenScroller.computeScrollOffset()) {
swipe(mOpenScroller.getCurrX());
postInvalidate();
}
} else {
if (mCloseScroller.computeScrollOffset()) {
swipe(mBaseX - mCloseScroller.getCurrX());
postInvalidate();
}
}
}
public void smoothCloseMenu() {
state = STATE_CLOSE;
mBaseX = -mContentView.getLeft();
mCloseScroller.startScroll(0, 0, mBaseX, 0, 350);
postInvalidate();
}
public void smoothOpenMenu() {
state = STATE_OPEN;
mOpenScroller.startScroll(-mContentView.getLeft(), 0,
mMenuView.getWidth(), 0, 350);
postInvalidate();
}
public void closeMenu() {
if (mCloseScroller.computeScrollOffset()) {
mCloseScroller.abortAnimation();
}
if (state == STATE_OPEN) {
state = STATE_CLOSE;
swipe(0);
}
}
public void openMenu() {
if (state == STATE_CLOSE) {
state = STATE_OPEN;
swipe(mMenuView.getWidth());
}
}
public View getContentView() {
return mContentView;
}
public SwipeMenuView getMenuView() {
return mMenuView;
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getContext().getResources().getDisplayMetrics());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mMenuView.measure(MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(
getMeasuredHeight(), MeasureSpec.EXACTLY));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mContentView.layout(0, 0, getMeasuredWidth(),
mContentView.getMeasuredHeight());
mMenuView.layout(getMeasuredWidth(), 0,
getMeasuredWidth() + mMenuView.getMeasuredWidth(),
mContentView.getMeasuredHeight());
// setMenuHeight(mContentView.getMeasuredHeight());
// bringChildToFront(mContentView);
}
public void setMenuHeight(int measuredHeight) {
Log.i("byz", "pos = " + position + ", height = " + measuredHeight);
LayoutParams params = (LayoutParams) mMenuView.getLayoutParams();
if (params.height != measuredHeight) {
params.height = measuredHeight;
mMenuView.setLayoutParams(mMenuView.getLayoutParams());
}
}
}
View Code
新建SwipeMenuListView类,代码如下
package swipemenulistview;
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.ListAdapter;
import android.widget.ListView;
/**
*
* @author baoyz
* @date 2014-8-18
*
*/
public class SwipeMenuListView extends ListView {
private static final int TOUCH_STATE_NONE = 0;
private static final int TOUCH_STATE_X = 1;
private static final int TOUCH_STATE_Y = 2;
private int MAX_Y = 5;
private int MAX_X = 3;
private float mDownX;
private float mDownY;
private int mTouchState;
private int mTouchPosition;
private SwipeMenuLayout mTouchView;
private OnSwipeListener mOnSwipeListener;
private SwipeMenuCreator mMenuCreator;
private OnMenuItemClickListener mOnMenuItemClickListener;
private Interpolator mCloseInterpolator;
private Interpolator mOpenInterpolator;
public SwipeMenuListView(Context context) {
super(context);
init();
}
public SwipeMenuListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public SwipeMenuListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
//初始化
private void init() {
MAX_X = dp2px(MAX_X);
MAX_Y = dp2px(MAX_Y);
mTouchState = TOUCH_STATE_NONE;
}
@Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(new SwipeMenuAdapter(getContext(), adapter) {
@Override
public void createMenu(SwipeMenu menu) {
if (mMenuCreator != null) {
mMenuCreator.create(menu);
}
}
@Override
public void onItemClick(SwipeMenuView view, SwipeMenu menu,
int index) {
if (mOnMenuItemClickListener != null) {
mOnMenuItemClickListener.onMenuItemClick(
view.getPosition(), menu, index);
}
if (mTouchView != null) {
mTouchView.smoothCloseMenu();
}
}
});
}
public void setCloseInterpolator(Interpolator interpolator) {
mCloseInterpolator = interpolator;
}
public void setOpenInterpolator(Interpolator interpolator) {
mOpenInterpolator = interpolator;
}
public Interpolator getOpenInterpolator() {
return mOpenInterpolator;
}
public Interpolator getCloseInterpolator() {
return mCloseInterpolator;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
return super.onTouchEvent(ev);
int action = MotionEventCompat.getActionMasked(ev);
action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
int oldPos = mTouchPosition;
mDownX = ev.getX();
mDownY = ev.getY();
mTouchState = TOUCH_STATE_NONE;
mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
if (mTouchPosition == oldPos && mTouchView != null
&& mTouchView.isOpen()) {
mTouchState = TOUCH_STATE_X;
mTouchView.onSwipe(ev);
return true;
}
View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
if (mTouchView != null && mTouchView.isOpen()) {
mTouchView.smoothCloseMenu();
mTouchView = null;
return super.onTouchEvent(ev);
}
if (view instanceof SwipeMenuLayout) {
mTouchView = (SwipeMenuLayout) view;
}
if (mTouchView != null) {
mTouchView.onSwipe(ev);
}
break;
case MotionEvent.ACTION_MOVE:
float dy = Math.abs((ev.getY() - mDownY));
float dx = Math.abs((ev.getX() - mDownX));
if (mTouchState == TOUCH_STATE_X) {
if (mTouchView != null) {
mTouchView.onSwipe(ev);
}
getSelector().setState(new int[] { 0 });
ev.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(ev);
return true;
} else if (mTouchState == TOUCH_STATE_NONE) {
if (Math.abs(dy) > MAX_Y) {
mTouchState = TOUCH_STATE_Y;
} else if (dx > MAX_X) {
mTouchState = TOUCH_STATE_X;
if (mOnSwipeListener != null) {
mOnSwipeListener.onSwipeStart(mTouchPosition);
}
}
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_X) {
if (mTouchView != null) {
mTouchView.onSwipe(ev);
if (!mTouchView.isOpen()) {
mTouchPosition = -1;
mTouchView = null;
}
}
if (mOnSwipeListener != null) {
mOnSwipeListener.onSwipeEnd(mTouchPosition);
}
ev.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(ev);
return true;
}
break;
}
return super.onTouchEvent(ev);
}
public void smoothOpenMenu(int position) {
if (position >= getFirstVisiblePosition()
&& position <= getLastVisiblePosition()) {
View view = getChildAt(position - getFirstVisiblePosition());
if (view instanceof SwipeMenuLayout) {
mTouchPosition = position;
if (mTouchView != null && mTouchView.isOpen()) {
mTouchView.smoothCloseMenu();
}
mTouchView = (SwipeMenuLayout) view;
mTouchView.smoothOpenMenu();
}
}
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getContext().getResources().getDisplayMetrics());
}
public void setMenuCreator(SwipeMenuCreator menuCreator) {
this.mMenuCreator = menuCreator;
}
public void setOnMenuItemClickListener(
OnMenuItemClickListener onMenuItemClickListener) {
this.mOnMenuItemClickListener = onMenuItemClickListener;
}
public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
this.mOnSwipeListener = onSwipeListener;
}
public static interface OnMenuItemClickListener {
void onMenuItemClick(int position, SwipeMenu menu, int index);
}
public static interface OnSwipeListener {
void onSwipeStart(int position);
void onSwipeEnd(int position);
}
}
View Code
新建SwipeMenuView类,代码如下
package swipemenulistview;
import java.util.List;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
*
* @author baoyz
* @date 2014-8-23
*
*/
public class SwipeMenuView extends LinearLayout implements OnClickListener {
private SwipeMenuListView mListView;
private SwipeMenuLayout mLayout;
private SwipeMenu mMenu;
private OnSwipeItemClickListener onItemClickListener;
private int position;
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public SwipeMenuView(SwipeMenu menu, SwipeMenuListView listView) {
super(menu.getContext());
mListView = listView;
mMenu = menu;
List<SwipeMenuItem> items = menu.getMenuItems();
int id = 0;
for (SwipeMenuItem item : items) {
addItem(item, id++);
}
}
private void addItem(SwipeMenuItem item, int id) {
LayoutParams params = new LayoutParams(item.getWidth(),
LayoutParams.MATCH_PARENT);
LinearLayout parent = new LinearLayout(getContext());
parent.setId(id);
parent.setGravity(Gravity.CENTER);
parent.setOrientation(LinearLayout.VERTICAL);
parent.setLayoutParams(params);
parent.setBackgroundDrawable(item.getBackground());
parent.setOnClickListener(this);
addView(parent);
if (item.getIcon() != null) {
parent.addView(createIcon(item));
}
if (!TextUtils.isEmpty(item.getTitle())) {
parent.addView(createTitle(item));
}
}
private ImageView createIcon(SwipeMenuItem item) {
ImageView iv = new ImageView(getContext());
iv.setImageDrawable(item.getIcon());
return iv;
}
private TextView createTitle(SwipeMenuItem item) {
TextView tv = new TextView(getContext());
tv.setText(item.getTitle());
tv.setGravity(Gravity.CENTER);
tv.setTextSize(item.getTitleSize());
tv.setTextColor(item.getTitleColor());
return tv;
}
@Override
public void onClick(View v) {
if (onItemClickListener != null && mLayout.isOpen()) {
onItemClickListener.onItemClick(this, mMenu, v.getId());
}
}
public OnSwipeItemClickListener getOnSwipeItemClickListener() {
return onItemClickListener;
}
public void setOnSwipeItemClickListener(OnSwipeItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void setLayout(SwipeMenuLayout mLayout) {
this.mLayout = mLayout;
}
public static interface OnSwipeItemClickListener {
void onItemClick(SwipeMenuView view, SwipeMenu menu, int index);
}
}
View Code