Browse Source

侧滑控件库

RaoMeng 9 years ago
parent
commit
2a1bf0824b
20 changed files with 1502 additions and 14 deletions
  1. 16 9
      WeiChat/src/main/java/com/xzjmyk/pm/activity/MySwipeMenuCreator.java
  2. 25 4
      WeiChat/src/main/java/com/xzjmyk/pm/activity/adapter/MySubscriptionAdapter.java
  3. 14 0
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/fragment/SubscriptionMyFragment.java
  4. BIN
      WeiChat/src/main/res/drawable-hdpi/ic_lock.png
  5. BIN
      WeiChat/src/main/res/drawable-hdpi/ic_warning.png
  6. 242 0
      WeiChat/src/main/res/layout/activity_apply_subscribe.xml
  7. 9 0
      WeiChat/src/main/res/layout/layout_my_subscribe_list.xml
  8. 1 1
      WeiChat/src/main/res/values/colors.xml
  9. 1 0
      library-swipemenu_lv/.gitignore
  10. 17 0
      library-swipemenu_lv/proguard-rules.pro
  11. 13 0
      library-swipemenu_lv/src/androidTest/java/com/baoyz/swipemenulistview/ApplicationTest.java
  12. 4 0
      library-swipemenu_lv/src/main/AndroidManifest.xml
  13. 41 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/BaseSwipListAdapter.java
  14. 53 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenu.java
  15. 151 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuAdapter.java
  16. 13 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuCreator.java
  17. 96 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuItem.java
  18. 347 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuLayout.java
  19. 355 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuListView.java
  20. 104 0
      library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuView.java

+ 16 - 9
WeiChat/src/main/java/com/xzjmyk/pm/activity/MySwipeMenuCreator.java

@@ -20,15 +20,22 @@ public class MySwipeMenuCreator implements SwipeMenuCreator {
 
     @Override
     public void create(SwipeMenu menu) {
-        SwipeMenuItem openItem = new SwipeMenuItem(mContext);
-        SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
-        deleteItem.setBackground(new ColorDrawable(mContext.getResources().getColor(R.color.red)));
-        deleteItem.setTitleColor(mContext.getResources().getColor(R.color.white));
-        deleteItem.setTitleSize(15);
-        deleteItem.setTitle("取消订阅");
-        deleteItem.setWidth(dp2px(100));
-
-        menu.addMenuItem(deleteItem);
+        switch (menu.getViewType()){
+            case 0:
+//                menu.removeMenuItem(deleteItem);
+                break;
+            case 1:
+                SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
+                deleteItem.setBackground(new ColorDrawable(mContext.getResources().getColor(R.color.red)));
+                deleteItem.setTitleColor(mContext.getResources().getColor(R.color.white));
+                deleteItem.setTitleSize(15);
+                deleteItem.setTitle("取消订阅");
+                deleteItem.setWidth(dp2px(100));
+
+                menu.addMenuItem(deleteItem);
+                break;
+        }
+
     }
 
     private int dp2px(int dp) {

+ 25 - 4
WeiChat/src/main/java/com/xzjmyk/pm/activity/adapter/MySubscriptionAdapter.java

@@ -4,6 +4,7 @@ import android.content.Context;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
+import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.xzjmyk.pm.activity.R;
@@ -37,24 +38,44 @@ public class MySubscriptionAdapter extends BaseAdapter {
         return i;
     }
 
+    @Override
+    public int getViewTypeCount() {
+        return 2;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return position % 2;
+    }
+
     @Override
     public View getView(int i, View view, ViewGroup viewGroup) {
         ViewHolder viewHolder = null;
         if (view == null){
             view = View.inflate(mContext, R.layout.layout_my_subscribe_list, null);
             viewHolder = new ViewHolder();
-//            viewHolder.textView = (TextView) view.findViewById(android.R.id.text1);
+            viewHolder.subscribeIv = (ImageView) view.findViewById(R.id.my_subscribe_iv);
+            viewHolder.titleTv = (TextView) view.findViewById(R.id.my_subscribe_title_tv);
+            viewHolder.contentTv = (TextView) view.findViewById(R.id.my_subscribe_content_tv);
+            viewHolder.lockIv = (ImageView) view.findViewById(R.id.my_subscribe_lock_iv);
             view.setTag(viewHolder);
 
         }else {
             viewHolder = (ViewHolder) view.getTag();
         }
-
-//        viewHolder.textView.setText(mStrings.get(i));
+        int itemViewType = getItemViewType(i);
+        if (itemViewType == 0){
+            viewHolder.lockIv.setVisibility(View.VISIBLE);
+        }else if (itemViewType == 1){
+            viewHolder.lockIv.setVisibility(View.GONE);
+        }
         return view;
     }
 
     class ViewHolder{
-        TextView textView;
+        ImageView subscribeIv;
+        TextView titleTv;
+        TextView contentTv;
+        ImageView lockIv;
     }
 }

+ 14 - 0
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/fragment/SubscriptionMyFragment.java

@@ -48,6 +48,20 @@ public class SubscriptionMyFragment extends BaseFragment {
         mSwipeMenuListView.setAdapter(mMySubscriptionAdapter);
         mSwipeMenuListView.setMenuCreator(mMySwipeMenuCreator);
         mSwipeMenuListView.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
+
+        mSwipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
+            @Override
+            public void onSwipeStart(int position) {
+            }
+
+            @Override
+            public void onSwipeEnd(int position) {
+                if ((position % 2) == 0){
+                    mSwipeMenuListView.smoothCloseMenu();
+
+                }
+            }
+        });
         mSwipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
             @Override
             public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {

BIN
WeiChat/src/main/res/drawable-hdpi/ic_lock.png


BIN
WeiChat/src/main/res/drawable-hdpi/ic_warning.png


+ 242 - 0
WeiChat/src/main/res/layout/activity_apply_subscribe.xml

@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:whatever="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <RelativeLayout
+        android:id="@+id/ry_business_no"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+
+        <TextView
+            android:id="@+id/apply_subscribe_order_tv"
+            style="@style/form_relative_left_text"
+            android:text="采购单分析"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="10dp"
+            android:layout_toRightOf="@+id/apply_subscribe_order_tv"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_order_et"
+            style="@style/form_relative_right_text"
+            android:hint="请输入"
+            editTextFormExample:testType="nocheck"/>
+    </RelativeLayout>
+
+    <!--<ImageView style="@style/app_comm_list_line_gray" />-->
+
+    <RelativeLayout
+        android:id="@+id/ry_business_name"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+
+        <TextView
+            android:id="@+id/apply_subscribe_data_tv"
+            style="@style/form_relative_left_text"
+            android:text="单据日期"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="10dp"
+            android:layout_toRightOf="@+id/apply_subscribe_data_tv"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_data_et"
+            style="@style/form_relative_right_text"
+            editTextFormExample:testType="nocheck"
+            android:hint="请选择" />
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:id="@+id/ry_leave_type"
+        style="@style/form_relative_customer"
+        android:visibility="gone">
+
+
+        <TextView
+            android:id="@+id/tv_leave_type"
+            style="@style/form_relative_left_text"
+            android:text="请假类型:" />
+
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/et_leave_type"
+            style="@style/form_relative_right_text"
+            android:focusableInTouchMode="false"
+            editTextFormExample:testType="nocheck" />
+    </RelativeLayout>
+
+    <!--<ImageView style="@style/app_comm_list_line_gray" />-->
+
+    <RelativeLayout
+        android:id="@+id/ry_business_source"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+
+        <TextView
+            android:id="@+id/apply_subscribe_status_tv"
+            style="@style/form_relative_left_text"
+            android:text="单据状态"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="10dp"
+            android:layout_toRightOf="@+id/apply_subscribe_status_tv"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_status_et"
+            style="@style/form_relative_right_text"
+            android:drawableRight="@drawable/nav_icon_search_default"
+            editTextFormExample:testType="nocheck"
+            android:hint="请选择" />
+    </RelativeLayout>
+    <RelativeLayout
+        android:id="@+id/ry_business"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+
+        <TextView
+            android:id="@+id/apply_subscribe_person_tv"
+            style="@style/form_relative_left_text"
+            android:text="申请人"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="25dp"
+            android:layout_toRightOf="@+id/apply_subscribe_person_tv"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_person_et"
+            android:drawableRight="@drawable/nav_icon_search_default"
+            style="@style/form_relative_right_text"
+            editTextFormExample:testType="nocheck"
+            android:hint="请选择" />
+    </RelativeLayout>
+    <!--<ImageView style="@style/app_comm_list_line_gray" />-->
+
+    <RelativeLayout
+        android:id="@+id/ry_business_phone"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2"
+        android:visibility="gone">
+
+
+        <TextView
+            android:id="@+id/tv_iv_leave_days"
+            style="@style/form_relative_left_text"
+            android:text="商机类型"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="10dp"
+            android:layout_toRightOf="@+id/tv_iv_leave_days"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/et_business_type"
+            style="@style/form_relative_right_text"
+            android:drawableRight="@drawable/nav_icon_search_default"
+            whatever:customRegexp="^(([0-9])|([0-9]+\\.?[0-9]+))$"
+            whatever:testErrorString="@string/error_only_numeric_digits_allowed"
+            whatever:testType="nocheck"
+            android:hint="请选择" />
+    </RelativeLayout>
+
+    <!--<ImageView style="@style/app_comm_list_line_gray" />-->
+
+    <!--<ImageView style="@style/app_comm_list_line_gray" />-->
+
+
+
+
+    <RelativeLayout
+        android:id="@+id/ry_business_jieDuan"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+
+        <TextView
+            android:id="@+id/apply_subscribe_post_tv"
+            style="@style/form_relative_left_text"
+            android:text="申请人岗位"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="10dp"
+            android:layout_toRightOf="@+id/apply_subscribe_post_tv"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_post_et"
+            style="@style/form_relative_right_text"
+            android:drawableRight="@drawable/nav_icon_search_default"
+            editTextFormExample:customFormat="yyyy-MM-dd HH:mm"
+            editTextFormExample:testType="nocheck"
+            android:hint="请选择" />
+    </RelativeLayout>
+
+
+
+
+    <RelativeLayout
+        android:id="@+id/ry_business_enterMan"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+
+        <TextView
+            android:id="@+id/apply_subscribe_branch_tv"
+            style="@style/form_relative_left_text"
+            android:text="申请部门"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+        <TextView
+            style="@style/form_relative_left_text"
+            android:layout_marginLeft="10dp"
+            android:layout_toRightOf="@+id/apply_subscribe_branch_tv"
+            android:text="*"
+            android:textColor="@color/red" />
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_branch_et"
+            style="@style/form_relative_right_text"
+            android:drawableRight="@drawable/nav_icon_search_default"
+            editTextFormExample:customFormat="yyyy-MM-dd HH:mm"
+            editTextFormExample:testType="nocheck"
+            android:hint="请选择" />
+    </RelativeLayout>
+    <RelativeLayout
+        android:id="@+id/ry_business_enterTime"
+        style="@style/form_relative_customer"
+        android:background="@color/item_color2">
+
+        <TextView
+            style="@style/form_relative_left_text"
+            android:text="申请原因"
+            android:textColor="@color/text_main"
+            android:textSize="@dimen/text_main" />
+
+        <com.andreabaccega.widget.FormEditText xmlns:editTextFormExample="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/apply_subscribe_reason_et"
+            style="@style/form_relative_right_text"
+            editTextFormExample:customFormat="yyyy-MM-dd HH:mm"
+            editTextFormExample:testType="date"
+            android:hint="请输入" />
+    </RelativeLayout>
+</LinearLayout>

+ 9 - 0
WeiChat/src/main/res/layout/layout_my_subscribe_list.xml

@@ -33,4 +33,13 @@
         android:textSize="16sp"
         android:text="YYYYYYYYYYY"/>
 
+    <ImageView
+        android:id="@+id/my_subscribe_lock_iv"
+        android:layout_width="25dp"
+        android:layout_height="25dp"
+        android:layout_alignParentRight="true"
+        android:src="@drawable/ic_lock"
+        android:layout_marginRight="10dp"
+        android:layout_centerVertical="true"/>
+
 </RelativeLayout>

+ 1 - 1
WeiChat/src/main/res/values/colors.xml

@@ -5,7 +5,7 @@
     <color name="oa_outoffice">#39cea7</color>
     <color name="meeting">#d79147</color>
     <color name="subscrip_text">#60a0a0a0</color>
-    <color name="subscrip_text">#809b9797</color>
+    <color name="subscrip_text1">#809b9797</color>
     <color name="item_color1">#30a0a0a0</color>
     <color name="pop_bg">#aeaeae</color>
     <color name="item_color2">@color/white</color>

+ 1 - 0
library-swipemenu_lv/.gitignore

@@ -0,0 +1 @@
+/build

+ 17 - 0
library-swipemenu_lv/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/baoyz/Developer/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 13 - 0
library-swipemenu_lv/src/androidTest/java/com/baoyz/swipemenulistview/ApplicationTest.java

@@ -0,0 +1,13 @@
+package com.baoyz.swipemenulistview;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
+ */
+public class ApplicationTest extends ApplicationTestCase<Application> {
+    public ApplicationTest() {
+        super(Application.class);
+    }
+}

+ 4 - 0
library-swipemenu_lv/src/main/AndroidManifest.xml

@@ -0,0 +1,4 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.baoyz.swipemenulistview">
+
+</manifest>

+ 41 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/BaseSwipListAdapter.java

@@ -0,0 +1,41 @@
+/*
+* The MIT License (MIT)
+*
+* Copyright (c) 2015 nimengbo
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+package com.baoyz.swipemenulistview;
+
+import android.widget.BaseAdapter;
+
+/**
+ * Created by Abner on 15/11/20.
+ * Email nimengbo@gmail.com
+ * github https://github.com/nimengbo
+ */
+public abstract class BaseSwipListAdapter extends BaseAdapter {
+
+    public boolean getSwipEnableByPosition(int position){
+        return true;
+    }
+
+
+
+}

+ 53 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenu.java

@@ -0,0 +1,53 @@
+package com.baoyz.swipemenulistview;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ * @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;
+	}
+
+}

+ 151 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuAdapter.java

@@ -0,0 +1,151 @@
+package com.baoyz.swipemenulistview;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListAdapter;
+import android.widget.WrapperListAdapter;
+import com.baoyz.swipemenulistview.SwipeMenuView.OnSwipeItemClickListener;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-24
+ * 
+ */
+public class SwipeMenuAdapter implements WrapperListAdapter,
+		OnSwipeItemClickListener {
+
+    private ListAdapter mAdapter;
+    private Context mContext;
+    private SwipeMenuListView.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(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);
+        }
+        if (mAdapter instanceof BaseSwipListAdapter) {
+            boolean swipEnable = (((BaseSwipListAdapter) mAdapter).getSwipEnableByPosition(position));
+            layout.setSwipEnable(swipEnable);
+        }
+        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 setOnSwipeItemClickListener(
+            SwipeMenuListView.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;
+    }
+
+}

+ 13 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuCreator.java

@@ -0,0 +1,13 @@
+package com.baoyz.swipemenulistview;
+
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-24
+ *
+ */
+public interface SwipeMenuCreator {
+
+	void create(SwipeMenu menu);
+}

+ 96 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuItem.java

@@ -0,0 +1,96 @@
+package com.baoyz.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;
+	}
+
+}

+ 347 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuLayout.java

@@ -0,0 +1,347 @@
+package com.baoyz.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.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 int mSwipeDirection;
+
+	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;
+
+	private boolean mSwipEnable = true;
+
+	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);
+	}
+
+	public void setSwipeDirection(int swipeDirection) {
+		mSwipeDirection = swipeDirection;
+	}
+
+	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 (Math.abs(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()*mSwipeDirection;;
+			}
+			swipe(dis);
+			break;
+		case MotionEvent.ACTION_UP:
+			if ((isFling || Math.abs(mDownX - event.getX()) > (mMenuView.getWidth() / 2)) &&
+					Math.signum(mDownX - event.getX()) == mSwipeDirection) {
+				// 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(!mSwipEnable){
+			return ;
+		}
+		if (Math.signum(dis) != mSwipeDirection) {
+			dis = 0;
+		} else if (Math.abs(dis) > mMenuView.getWidth()) {
+			dis = mMenuView.getWidth()*mSwipeDirection;
+		}
+
+		mContentView.layout(-dis, mContentView.getTop(),
+				mContentView.getWidth() -dis, getMeasuredHeight());
+
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+
+			mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
+					mContentView.getWidth() + mMenuView.getWidth() - dis,
+					mMenuView.getBottom());
+		} else {
+			mMenuView.layout(-mMenuView.getWidth() - dis, mMenuView.getTop(),
+					- dis, mMenuView.getBottom());
+		}
+	}
+
+	@Override
+	public void computeScroll() {
+		if (state == STATE_OPEN) {
+			if (mOpenScroller.computeScrollOffset()) {
+				swipe(mOpenScroller.getCurrX()*mSwipeDirection);
+				postInvalidate();
+			}
+		} else {
+			if (mCloseScroller.computeScrollOffset()) {
+				swipe((mBaseX - mCloseScroller.getCurrX())*mSwipeDirection);
+				postInvalidate();
+			}
+		}
+	}
+
+	public void smoothCloseMenu() {
+		state = STATE_CLOSE;
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+			mBaseX = -mContentView.getLeft();
+			mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350);
+		} else {
+			mBaseX = mMenuView.getRight();
+			mCloseScroller.startScroll(0, 0, mMenuView.getWidth(), 0, 350);
+		}
+		postInvalidate();
+	}
+
+	public void smoothOpenMenu() {
+		if(!mSwipEnable){
+			return ;
+		}
+		state = STATE_OPEN;
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+			mOpenScroller.startScroll(-mContentView.getLeft(), 0, mMenuView.getWidth(), 0, 350);
+		} else {
+			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(!mSwipEnable){
+			return ;
+		}
+		if (state == STATE_CLOSE) {
+			state = STATE_OPEN;
+			swipe(mMenuView.getWidth() * mSwipeDirection);
+		}
+	}
+
+	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());
+		if (mSwipeDirection == SwipeMenuListView.DIRECTION_LEFT) {
+			mMenuView.layout(getMeasuredWidth(), 0,
+					getMeasuredWidth() + mMenuView.getMeasuredWidth(),
+					mContentView.getMeasuredHeight());
+		} else {
+			mMenuView.layout(-mMenuView.getMeasuredWidth(), 0,
+					0, mContentView.getMeasuredHeight());
+		}
+	}
+
+	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());
+		}
+	}
+
+	public void setSwipEnable(boolean swipEnable){
+		mSwipEnable = swipEnable;
+	}
+
+	public boolean getSwipEnable(){
+		return mSwipEnable;
+	}
+}

+ 355 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuListView.java

@@ -0,0 +1,355 @@
+package com.baoyz.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;
+
+    public static final int DIRECTION_LEFT = 1;
+    public static final int DIRECTION_RIGHT = -1;
+    private int mDirection = 1;//swipe from right to left by default
+
+    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 OnMenuStateChangeListener mOnMenuStateChangeListener;
+    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) {
+                boolean flag = false;
+                if (mOnMenuItemClickListener != null) {
+                    flag = mOnMenuItemClickListener.onMenuItemClick(
+                            view.getPosition(), menu, index);
+                }
+                if (mTouchView != null && !flag) {
+                    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) {
+        //在拦截处处理,在滑动设置了点击事件的地方也能swip,点击时又不能影响原来的点击事件
+        int action = ev.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mDownX = ev.getX();
+                mDownY = ev.getY();
+                boolean handled = super.onInterceptTouchEvent(ev);
+                mTouchState = TOUCH_STATE_NONE;
+                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
+                View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
+
+                //只在空的时候赋值 以免每次触摸都赋值,会有多个open状态
+                if (view instanceof SwipeMenuLayout) {
+                    //如果有打开了 就拦截.
+                    if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
+                        return true;
+                    }
+                    mTouchView = (SwipeMenuLayout) view;
+                    mTouchView.setSwipeDirection(mDirection);
+                }
+                //如果摸在另外个view
+                if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
+                    handled = true;
+                }
+
+                if (mTouchView != null) {
+                    mTouchView.onSwipe(ev);
+                }
+                return handled;
+            case MotionEvent.ACTION_MOVE:
+                float dy = Math.abs((ev.getY() - mDownY));
+                float dx = Math.abs((ev.getX() - mDownX));
+                if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
+                    //每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
+                    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);
+                            }
+                        }
+                    }
+                    return true;
+                }
+        }
+        return super.onInterceptTouchEvent(ev);
+    }
+
+    /*@Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_MOVE){
+            return true;
+        }
+        return super.dispatchTouchEvent(ev);
+    }*/
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
+            return super.onTouchEvent(ev);
+        int 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);
+                    // try to cancel the touch event
+                    MotionEvent cancelEvent = MotionEvent.obtain(ev);
+                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
+                    onTouchEvent(cancelEvent);
+                    if (mOnMenuStateChangeListener != null) {
+                        mOnMenuStateChangeListener.onMenuClose(oldPos);
+                    }
+                    return true;
+                }
+                if (view instanceof SwipeMenuLayout) {
+                    mTouchView = (SwipeMenuLayout) view;
+                    mTouchView.setSwipeDirection(mDirection);
+                }
+                if (mTouchView != null) {
+                    mTouchView.onSwipe(ev);
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                //有些可能有header,要减去header再判断
+                mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount();
+                //如果滑动了一下没完全展现,就收回去,这时候mTouchView已经赋值,再滑动另外一个不可以swip的view
+                //会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view
+                if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) {
+                    break;
+                }
+                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) {
+                        boolean isBeforeOpen = mTouchView.isOpen();
+                        mTouchView.onSwipe(ev);
+                        boolean isAfterOpen = mTouchView.isOpen();
+                        if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) {
+                            if (isAfterOpen) {
+                                mOnMenuStateChangeListener.onMenuOpen(mTouchPosition);
+                            } else {
+                                mOnMenuStateChangeListener.onMenuClose(mTouchPosition);
+                            }
+                        }
+                        if (!isAfterOpen) {
+                            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.setSwipeDirection(mDirection);
+                mTouchView.smoothOpenMenu();
+            }
+        }
+    }
+
+    public void smoothCloseMenu(){
+        if (mTouchView != null && mTouchView.isOpen()) {
+            mTouchView.smoothCloseMenu();
+        }
+    }
+
+    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 void setOnMenuStateChangeListener(OnMenuStateChangeListener onMenuStateChangeListener) {
+        mOnMenuStateChangeListener = onMenuStateChangeListener;
+    }
+
+    public static interface OnMenuItemClickListener {
+        boolean onMenuItemClick(int position, SwipeMenu menu, int index);
+    }
+
+    public static interface OnSwipeListener {
+        void onSwipeStart(int position);
+
+        void onSwipeEnd(int position);
+    }
+
+    public static interface OnMenuStateChangeListener {
+        void onMenuOpen(int position);
+
+        void onMenuClose(int position);
+    }
+
+    public void setSwipeDirection(int direction) {
+        mDirection = direction;
+    }
+
+    /**
+     * 判断点击事件是否在某个view内
+     *
+     * @param view
+     * @param ev
+     * @return
+     */
+    public static boolean inRangeOfView(View view, MotionEvent ev) {
+        int[] location = new int[2];
+        view.getLocationOnScreen(location);
+        int x = location[0];
+        int y = location[1];
+        if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) {
+            return false;
+        }
+        return true;
+    }
+
+    /*@Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
+        super.onMeasure(widthMeasureSpec, expandSpec);
+    }*/
+}

+ 104 - 0
library-swipemenu_lv/src/main/java/com/baoyz/swipemenulistview/SwipeMenuView.java

@@ -0,0 +1,104 @@
+package com.baoyz.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);
+	}
+}