Bläddra i källkod

1.修复RA Image Android上传设置修改后未应用到Manager。
2.修复RA Image Android Upload Manager在初始化时读取设置错误。
3.修改RA Image Android Upload List,增加左滑操作。

Pen Li 8 år sedan
förälder
incheckning
0ef30ec488

+ 9 - 8
RA Image/app/app.iml

@@ -62,13 +62,6 @@
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
@@ -76,6 +69,13 @@
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
@@ -89,6 +89,7 @@
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
@@ -100,7 +101,7 @@
       <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
       <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
     </content>
-    <orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
+    <orderEntry type="jdk" jdkName="Android API 25 Platform (1)" jdkType="Android SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" exported="" name="core-2.3.0" level="project" />
     <orderEntry type="library" exported="" name="constraint-layout-solver-1.0.2" level="project" />

+ 221 - 34
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/UploadListActivity.java

@@ -1,29 +1,37 @@
 package com.usai.redant.raimage.UploadList;
 
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.support.v4.content.LocalBroadcastManager;
 import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
+import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
 import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.usai.redant.raimage.R;
+import com.usai.redant.raimage.UploadList.swipemenulistview.SwipeMenu;
+import com.usai.redant.raimage.UploadList.swipemenulistview.SwipeMenuCreator;
+import com.usai.redant.raimage.UploadList.swipemenulistview.SwipeMenuItem;
+import com.usai.redant.raimage.UploadList.swipemenulistview.SwipeMenuListView;
 import com.usai.redant.raimage.UploadService;
 import com.usai.util.RAUploadManager;
 
@@ -32,13 +40,10 @@ import java.util.List;
 
 public class UploadListActivity extends AppCompatActivity {
 
-    private ListView uploadList;
+    private SwipeMenuListView uploadList;
     private uploadAdapter adapter;
     private ArrayList<Bundle> arr;
 
-    private LocalBroadcastManager broadcastManager;
-    private UploadBroadcastReceiver broadcastReceiver;
-
     private RAUploadManager uploadManager;
     private UploadService.MyBinder binder;
     private UploadService uploadServiceservice;
@@ -142,15 +147,9 @@ public class UploadListActivity extends AppCompatActivity {
         mActionBar.setDisplayHomeAsUpEnabled(true);
         mActionBar.setTitle("RA Image");
 
-        // 注册广播接收
-        broadcastManager = LocalBroadcastManager.getInstance(this);
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction("");
-        broadcastReceiver = new UploadBroadcastReceiver();
-        broadcastManager.registerReceiver(broadcastReceiver,intentFilter);
 
         // 初始化视图
-        uploadList = (ListView)findViewById(R.id.upload_list);
+        uploadList = (SwipeMenuListView)findViewById(R.id.upload_list);
 
         serviceConnection = new ServiceConnection() {
             @Override
@@ -167,7 +166,7 @@ public class UploadListActivity extends AppCompatActivity {
                 runOnUiThread(new Runnable() {
                     @Override
                     public void run() {
-                        adapter = new uploadAdapter(UploadListActivity.this,R.layout.upload_list_cell,arr);
+                        adapter = new uploadAdapter(R.layout.upload_list_cell);
                         uploadList.setAdapter(adapter);
                     }
                 });
@@ -182,7 +181,107 @@ public class UploadListActivity extends AppCompatActivity {
 
         bindService();
 
+        SwipeMenuCreator creator = new SwipeMenuCreator() {
+
+            @Override
+            public void create(SwipeMenu menu) {
+                // Create different menus depending on the view type
+                switch (menu.getViewType()) {
+                    case 0: {
+                        createRemoveMenuItem(menu);
+                    }
+                    break;
+                    case 1: {
+                        createStartMenuItem(menu);
+                        createRemoveMenuItem(menu);
+                    }
+                    break;
+                    case 2: {
+                        createStartMenuItem(menu);
+                    }
+                    break;
+                    case 3: {
+
+                    }
+                    break;
+                }
+            }
+        };
+
+        uploadList.setMenuCreator(creator);
+
+        uploadList.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
+            @Override
+            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
+                // action
+                Bundle item = arr.get(position);
+                int type = taskSwipeType(position);
+                switch (type) {
+                    case 0: {
+                        if (index == 0) {
+                            // remove
+                            uploadManager.removeTask(item);
+                        }
+                    }
+                    break;
+                    case 1: {
+                        if (index == 0) {
+                            // start
+                            uploadManager.startTask(item);
+                        } else if (index == 1) {
+                            // remove
+                            uploadManager.removeTask(item);
+                        }
+                    }
+                    break;
+                    case 2: {
+                        if (index == 0) {
+                            // start
+                            uploadManager.startTask(item);
+                        }
+                    }
+                    break;
+                    case 3: {
+
+                    }
+                    break;
+                }
+
+                return false;
+            }
+        });
+    }
+
+    private void createRemoveMenuItem(SwipeMenu menu) {
+        SwipeMenuItem openItem = new SwipeMenuItem(getApplicationContext());
+        // set item background
+        openItem.setBackground(new ColorDrawable(Color.rgb(0x9b, 0xbf,0x5a)));
+        // set item width
+        openItem.setWidth(dp2px(90));
+        // set item title
+        openItem.setTitle("Remove");
+        // set item title fontsize
+        openItem.setTitleSize(18);
+        // set item title font color
+        openItem.setTitleColor(Color.WHITE);
+        // add to menu
+        menu.addMenuItem(openItem);
+    }
 
+    private void createStartMenuItem(SwipeMenu menu) {
+        SwipeMenuItem openItem = new SwipeMenuItem(getApplicationContext());
+        // set item background
+        openItem.setBackground(new ColorDrawable(Color.rgb(0xff, 0x99,0x33)));
+        // set item width
+        openItem.setWidth(dp2px(90));
+        // set item title
+        openItem.setTitle("Restart");
+        // set item title fontsize
+        openItem.setTitleSize(18);
+        // set item title font color
+        openItem.setTitleColor(Color.WHITE);
+        // add to menu
+        menu.addMenuItem(openItem);
     }
 
     @Override
@@ -193,6 +292,12 @@ public class UploadListActivity extends AppCompatActivity {
         super.onDestroy();
     }
 
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.upload_list_menu,menu);
+        return true;
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
@@ -200,17 +305,110 @@ public class UploadListActivity extends AppCompatActivity {
                 finish();
             }
             break;
+            case R.id.clear_upload_list_btn: {
+                clearUploadList();
+            }
+            break;
         }
         return true;
     }
 
-    private class uploadAdapter extends ArrayAdapter<Bundle> {
+    private void clearUploadList() {
+        if (uploadManager.arr_queue.size() == 0) {
+            new AlertDialog.Builder(this)
+                    .setTitle("Warning")
+                    .setMessage("Upload list is empty.")
+                    .setPositiveButton("OK",null)
+                    .show();
+            return;
+        }
+
+        new AlertDialog.Builder(this)
+                .setTitle("Clear upload list")
+                .setMessage("Are you sure remove all error/finish task?")
+                .setPositiveButton("YES", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        // clear
+                        uploadManager.clearTask();
+                    }
+                })
+                .setNegativeButton("NO", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+
+                    }
+                })
+                .show();
+
+    }
+
+
+    private int taskSwipeType(int position) {
+        Bundle item = arr.get(position);
+        Bundle taskinfo = item.getBundle("params");
+        RAUploadManager.TaskStatus istatus = RAUploadManager.TaskStatus.values()[taskinfo.getInt("status",0)];
+        int type = 3;
+        switch(istatus)
+        {
+            case TaskStatusWait:
+            case TaskStatusStart:
+                type = 3;
+                break;
+            case TaskStatusStop:
+                type = 2;
+                break;
+            case TaskStatusError:
+                type = 1;
+                break;
+            case TaskStatusFinish:
+                type = 0;
+                break;
+            default:
+                type = 3;
+                break;
+        }
+        return type;
+    }
+
+    private class uploadAdapter extends BaseAdapter {
         private int resourceId;
-        public uploadAdapter(Context ctx, int resourceID, List<Bundle> objects) {
-            super(ctx,resourceID,objects);
+        public uploadAdapter(int resourceID) {
+
             resourceId = resourceID;
         }
 
+        @Override
+        public int getCount() {
+            return arr.size();
+        }
+
+        @Override
+        public Bundle getItem(int position) {
+            return arr.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 4;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            /**
+             * 0. <finish>      remove              </finish>
+             * 1. <error>       start  remove       </error>
+             * 2. <stop>        start               </stop>
+             * 3. <start\wait>  none                </start\wait>
+             * */
+            return taskSwipeType(position);
+        }
+
         @NonNull
         @Override
         public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
@@ -255,7 +453,7 @@ public class UploadListActivity extends AppCompatActivity {
                 holder = (ViewHolder)cell.getTag();
 
             } else  {
-                cell = LayoutInflater.from(getContext()).inflate(resourceId,null);
+                cell = LayoutInflater.from(getApplicationContext()).inflate(resourceId,null);
 
                 holder = new ViewHolder();
                 holder.name_tv = (TextView)cell.findViewById(R.id.upload_name_tv);
@@ -285,21 +483,6 @@ public class UploadListActivity extends AppCompatActivity {
         }
     }
 
-    /** Broadcast */
-    private class UploadBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int index = 0;
-            // item: Model数据
-            Object item = uploadList.getItemAtPosition(index);
-            int startShowIndex = uploadList.getFirstVisiblePosition();
-            int lastShowIndex = uploadList.getLastVisiblePosition();
-            if (index >= startShowIndex && index <= lastShowIndex) {
-                View cell = uploadList.getChildAt(index - startShowIndex);
-                uploadAdapter.ViewHolder holder= (uploadAdapter.ViewHolder)cell.getTag();
-            }
-        }
-    }
 
     /** Service */
     private void bindService() {
@@ -307,4 +490,8 @@ public class UploadListActivity extends AppCompatActivity {
 
         bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
     }
+
+    private int dp2px(int dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,getResources().getDisplayMetrics());
+    }
 }

+ 41 - 0
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/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.usai.redant.raimage.UploadList.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
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenu.java

@@ -0,0 +1,53 @@
+package com.usai.redant.raimage.UploadList.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;
+	}
+
+}

+ 148 - 0
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenuAdapter.java

@@ -0,0 +1,148 @@
+package com.usai.redant.raimage.UploadList.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;
+
+/**
+ * 
+ * @author baoyz
+ * @date 2014-8-24
+ * 
+ */
+public class SwipeMenuAdapter implements WrapperListAdapter,
+        SwipeMenuView.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
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenuCreator.java

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

+ 96 - 0
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenuItem.java

@@ -0,0 +1,96 @@
+package com.usai.redant.raimage.UploadList.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
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenuLayout.java

@@ -0,0 +1,347 @@
+package com.usai.redant.raimage.UploadList.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;
+	}
+}

+ 339 - 0
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenuListView.java

@@ -0,0 +1,339 @@
+package com.usai.redant.raimage.UploadList.swipemenulistview;
+
+import android.content.Context;
+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 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;
+    }
+}

+ 104 - 0
RA Image/app/src/main/java/com/usai/redant/raimage/UploadList/swipemenulistview/SwipeMenuView.java

@@ -0,0 +1,104 @@
+package com.usai.redant.raimage.UploadList.swipemenulistview;
+
+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;
+
+import java.util.List;
+
+/**
+ * 
+ * @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);
+	}
+}

+ 21 - 11
RA Image/app/src/main/java/com/usai/redant/raimage/uploadSettingActivity.java

@@ -91,6 +91,21 @@ public class uploadSettingActivity extends AppCompatActivity {
 
         editor.commit();
 
+        if (serviceConnectionFlag == true && uploadServiceservice != null) {
+            RAUploadManager uploadManager = uploadServiceservice.uploadManager;
+            uploadManager.autoStart = auto_upload;
+            uploadManager.removeFinish = auto_rm_fs;
+            uploadManager.removeError = auto_rm_er;
+            uploadManager.maxRetry = retry_count;
+        }
+
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_upload_setting);
+
         // 同时修改 Upload Manager
         serviceConnection = new ServiceConnection() {
             @Override
@@ -100,11 +115,6 @@ public class uploadSettingActivity extends AppCompatActivity {
                 binder = (UploadService.MyBinder)service;
                 uploadServiceservice = binder.getService();
 
-                RAUploadManager uploadManager = uploadServiceservice.uploadManager;
-                uploadManager.autoStart = auto_upload;
-                uploadManager.removeFinish = auto_rm_fs;
-                uploadManager.removeError = auto_rm_er;
-                uploadManager.maxRetry = retry_count;
             }
 
             @Override
@@ -114,12 +124,6 @@ public class uploadSettingActivity extends AppCompatActivity {
         };
 
         bindService();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_upload_setting);
 
         auto_start_swt = (Switch)findViewById(R.id.auto_start_swt);
         auto_rm_fs_swt = (Switch)findViewById(R.id.auto_rm_fs_swt);
@@ -135,6 +139,12 @@ public class uploadSettingActivity extends AppCompatActivity {
         mActionBar.setTitle("RA Image");
     }
 
+    @Override
+    protected void onDestroy() {
+        unbindService(serviceConnection);
+        super.onDestroy();
+    }
+
     @Override
     public boolean onSupportNavigateUp() {
         return super.onSupportNavigateUp();

+ 2 - 2
RA Image/app/src/main/java/com/usai/util/RAUploadManager.java

@@ -95,8 +95,8 @@ public class RAUploadManager {
         if(UMSetting!=null)
         {
             autoStart = UMSetting.getBoolean("auto_upload",true);
-            removeFinish = UMSetting.getBoolean("auto_rm_finish",true);
-            removeError = UMSetting.getBoolean("auto_rm_error",false);
+            removeFinish = UMSetting.getBoolean("auto_rm_fs",true);
+            removeError = UMSetting.getBoolean("auto_rm_er",false);
             maxRetry = UMSetting.getInt("retry_count",2);
             newtaskStatus = TaskStatus.values()[UMSetting.getInt("newtask_status",TaskStatus.TaskStatusWait.ordinal())];
 

+ 2 - 2
RA Image/app/src/main/res/layout/activity_upload_list.xml

@@ -5,12 +5,12 @@
     android:layout_height="match_parent"
     tools:context="com.usai.redant.raimage.UploadList.UploadListActivity">
 
-    <ListView
+    <com.usai.redant.raimage.UploadList.swipemenulistview.SwipeMenuListView
         android:id="@+id/upload_list"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         >
 
-    </ListView>
+    </com.usai.redant.raimage.UploadList.swipemenulistview.SwipeMenuListView>
 
 </RelativeLayout>

+ 11 - 0
RA Image/app/src/main/res/menu/upload_list_menu.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/clear_upload_list_btn"
+        app:showAsAction="always"
+        android:title="Clear"
+        />
+
+</menu>