Bläddra i källkod

Add saved list frame -- 添加保存列表框架 resolve: #39
Crash on tab switch -- 切换标签页闪退 resolve: #26

Ray Zhang 5 år sedan
förälder
incheckning
d7e34d1bfe
18 ändrade filer med 2305 tillägg och 7 borttagningar
  1. 6 6
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/RootActivity.java
  2. 188 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/CheckSavedActivity.java
  3. 380 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/SavedDetailFragment.java
  4. 388 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/SavedSearchFragment.java
  5. 100 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/TFListFragment.java
  6. 41 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/BaseSwipListAdapter.java
  7. 53 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenu.java
  8. 149 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuAdapter.java
  9. 13 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuCreator.java
  10. 96 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuItem.java
  11. 348 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuLayout.java
  12. 339 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuListView.java
  13. 104 0
      ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuView.java
  14. 19 0
      ApexDrivers/ratradefiling/src/main/res/layout/activity_check_saved.xml
  15. 55 0
      ApexDrivers/ratradefiling/src/main/res/layout/saved_cell.xml
  16. 15 0
      ApexDrivers/ratradefiling/src/main/res/menu/checksaved.xml
  17. 5 1
      ApexDrivers/ratradefiling/src/main/res/values-zh/strings.xml
  18. 6 0
      ApexDrivers/ratradefiling/src/main/res/values/strings.xml

+ 6 - 6
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/RootActivity.java

@@ -56,12 +56,12 @@ public class RootActivity extends BasicActivity {
     Menu actionbutton;
 
 
-//    @Override
-//    public boolean onCreateOptionsMenu(Menu menu) {
-//        actionbutton = menu;
-//        getMenuInflater().inflate(R.menu.quick_search,menu);
-//        return  true;
-//    }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        actionbutton = menu;
+        getMenuInflater().inflate(R.menu.quick_search,menu);
+        return  true;
+    }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {

+ 188 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/CheckSavedActivity.java

@@ -0,0 +1,188 @@
+package com.usai.ratradefiling.my;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+
+import com.usai.ratradefiling.R;
+
+//import com.usai.apex.ApexTrackingApplication;
+//import com.usai.apex.R;
+//import com.usai.util.dbUtil;
+
+public class CheckSavedActivity extends AppCompatActivity {
+    Fragment f=null;
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item)
+    {
+        Intent intent = new Intent();
+        switch (item.getItemId())
+        {
+            case android.R.id.home:
+                finish();
+                break;
+            case R.id.action_deleteall:
+            {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setMessage(getString(R.string.str_deletemessage));
+
+                builder.setTitle(getString(R.string.str_confirmdelete));
+
+                builder.setPositiveButton(getString(R.string.str_del),
+                        new Dialog.OnClickListener()
+                        {
+
+                            @Override
+                            public void onClick(DialogInterface dialog,
+                                                int which)
+                            {
+//                                SQLiteDatabase db = dbUtil.OpenDB(
+//                                        CheckSavedActivity.this, null, false);
+//                                String function_name = getIntent().getStringExtra("function_name");
+//                                if(function_name.equals("Saved Detail"))
+//                                {
+//
+//                                    db.execSQL(String.format("delete from favorites where user = '%s'", ApexTrackingApplication.get_user()));
+////                                    getSupportFragmentManager().get
+////                                    SavedSearchFragment f = (SavedSearchFragment)getSupportFragmentManager().findFragmentById(R.id.tab1);
+//                                    SavedDetailFragment detail =(SavedDetailFragment) f;
+//                                    detail.clear_result();
+//                                    detail.reload_adapter();
+//                                }
+//                                else if(function_name.equals("Saved Search"))
+//                                {
+//                                    db.execSQL(String.format("delete from history where user = '%s'",ApexTrackingApplication.get_user()));
+////                                    SavedDetailFragment f = (SavedDetailFragment)getSupportFragmentManager().findFragmentById(R.id.tab2);
+//
+//                                    SavedSearchFragment search =(SavedSearchFragment) f;
+//                                    search.clear_result();
+//                                    search.reload_adapter();
+//                                }
+////                                else if(function_name.equals("Saved Documents"))
+////                                {
+//////                                    db.execSQL("delete from favorites");
+////////                                    SavedDetailFragment f = (SavedDetailFragment)getSupportFragmentManager().findFragmentById(R.id.tab2);
+//////
+//////                                    SavedSearchFragment search =(SavedSearchFragment) f;
+//////                                    search.clear_result();
+//////                                    search.reload_adapter();
+////                                    SavedDocumentsFragment search =(SavedDocumentsFragment) f;
+////                                    ((SavedDocumentsFragment) f).clear();
+////                                }
+//
+//
+//                                dbUtil.CloseDB(db);
+//                                dialog.dismiss();
+
+                            }
+                        });
+
+                builder.setNegativeButton(getString(R.string.str_cancel),
+                        new Dialog.OnClickListener()
+                        {
+
+                            @Override
+                            public void onClick(DialogInterface dialog,
+                                                int which)
+                            {
+                                dialog.dismiss();
+                            }
+                        });
+
+                builder.create().show();
+
+                break;
+            }
+            default:
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.checksaved, menu);
+        return true;
+    }
+    private void setCustomActionBar() {
+        ActionBar.LayoutParams lp =new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
+        View mActionBarView = LayoutInflater.from(this).inflate(R.layout.actionbar_customtitle, null);
+
+        TextView titleview = mActionBarView.findViewById(R.id.title);
+        titleview.setText(getIntent().getStringExtra("function_name"));
+
+        setTitle(getIntent().getStringExtra("function_name"));
+//
+//        mActionBarView.setBackgroundColor(Color.YELLOW);
+//        titleview.setBackgroundColor(Color.BLUE);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setCustomView(mActionBarView, lp);
+//        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+//        actionBar.setDisplayShowCustomEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+
+//        actionBar.setIcon(getNumberDrawable());
+//        actionBar.setDisplayShowHomeEnabled(true);
+        actionBar.setDisplayShowTitleEnabled(true);
+    }
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_check_saved);
+
+
+
+        if (savedInstanceState == null)
+        {
+
+
+            String function_name = getIntent().getStringExtra("function_name");
+            if(function_name.equals("Saved Detail"))
+            {
+               f = new SavedDetailFragment();
+//                ToolsFragment f = new ToolsFragment();
+//                Bundle b = new Bundle();
+//                b.putBoolean("Login", true);
+//                favorites.setArguments(b);
+                getSupportFragmentManager().beginTransaction()
+                        .add(R.id.container, f).commit();
+            }
+            else if (function_name.equals("Saved Search"))
+            {
+                f = new SavedSearchFragment();
+//                Bundle b = new Bundle();
+//                b.putBoolean("Login", true);
+//                history.setArguments(b);
+                getSupportFragmentManager().beginTransaction()
+                        .add(R.id.container, f).commit();
+            }
+//            else if (function_name.equals("Saved Documents"))
+//            {
+//                f = new SavedDocumentsFragment();
+////                Bundle b = new Bundle();
+////                b.putBoolean("Login", true);
+////                history.setArguments(b);
+//                getSupportFragmentManager().beginTransaction()
+//                        .add(R.id.container, f).commit();
+//            }
+
+
+        }
+        setCustomActionBar();
+    }
+}

+ 380 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/SavedDetailFragment.java

@@ -0,0 +1,380 @@
+package com.usai.ratradefiling.my;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+//import com.usai.apex.ApexTrackingApplication;
+//import com.usai.apex.R;
+//import com.usai.apex.swipemenulistview.BaseSwipListAdapter;
+//import com.usai.apex.swipemenulistview.SwipeMenu;
+//import com.usai.apex.swipemenulistview.SwipeMenuCreator;
+//import com.usai.apex.swipemenulistview.SwipeMenuItem;
+//import com.usai.apex.swipemenulistview.SwipeMenuListView;
+//import com.usai.util.commonUtil;
+//import com.usai.util.dbUtil;
+
+import com.usai.ratradefiling.R;
+import com.usai.ratradefiling.swipemenulistview.BaseSwipListAdapter;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenu;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuCreator;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuItem;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuListView;
+import com.usai.redant.rautils.utils.RAUtil;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SavedDetailFragment extends TFListFragment
+{
+
+	SearchResult	searchresult	= new SearchResult();
+	BaseAdapter		adapter			= null;
+	private int		pointX, pointY, endX, endY;
+	private int		position, newpos;
+	private Button	curDel_btn;
+
+
+	public void clear_result()
+	{
+		searchresult.getData().clear();
+	}
+	public void reload_adapter()
+	{
+		adapter.notifyDataSetChanged();
+	}
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+		super.onActivityCreated(savedInstanceState);
+		adapter = new FavoritesAdapter(searchresult, getActivity());
+
+//		getListView().setOnTouchListener(this);
+		setListAdapter(adapter);
+		// this.getListView().setBackgroundColor(Color.WHITE);
+
+		// step 1. create a MenuCreator
+		SwipeMenuCreator creator = new SwipeMenuCreator() {
+
+			@Override
+			public void create(SwipeMenu menu) {
+
+				// create "delete" item
+				SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
+				// set item background
+				deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,0x3F, 0x25)));
+				// set item width
+				deleteItem.setWidth(dp2px(90));
+				// set a icon
+				deleteItem.setTitle("Delete");
+				// set item title fontsize
+				deleteItem.setTitleSize(18);
+				// set item title font color
+				deleteItem.setTitleColor(Color.WHITE);
+				// add to menu
+				menu.addMenuItem(deleteItem);
+			}
+		};
+		// set creator
+		mSwipeMenuListView.setMenuCreator(creator);
+
+		// step 2. listener item click event
+		mSwipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
+			@Override
+			public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
+
+
+				switch (index) {
+					case 0:
+						// delete
+//						SQLiteDatabase db = dbUtil.OpenDB(getActivity(),
+//								null, false);
+//						db.execSQL("delete from favorites where _id="
+//								+ (Long) searchresult.getData()
+//								.get(position).get("_id"));
+//
+//						dbUtil.CloseDB(db);
+//						searchresult.getData().remove(position);
+//						adapter.notifyDataSetChanged();
+
+						break;
+				}
+				return false;
+			}
+		});
+
+		// set SwipeListener
+		mSwipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
+
+			@Override
+			public void onSwipeStart(int position) {
+				// swipe start
+			}
+
+			@Override
+			public void onSwipeEnd(int position) {
+				// swipe end
+			}
+		});
+
+		// set MenuStateChangeListener
+		mSwipeMenuListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
+			@Override
+			public void onMenuOpen(int position) {
+			}
+
+			@Override
+			public void onMenuClose(int position) {
+			}
+		});
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+
+		Intent intent = new Intent();
+		// SQLiteDatabase db = dbUtil.OpenDB(getActivity(), null, false);
+		// Cursor c = db.query("favorites", new String[]
+		// {"params"},"_id="+searchresult.getData().get(position).get("_id"),null,
+		// null, null, null);
+		// if(c.moveToNext())
+		// {
+		String uri = (String) searchresult.getData().get(position)
+				.get("params");
+		try
+		{
+			intent = Intent.parseUri(uri, 0);
+
+			startActivity(intent);
+		}
+		catch (URISyntaxException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+
+
+	}
+
+	private class FavoritesAdapter extends BaseSwipListAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+											// private SearchResult result;
+
+		class Holder {
+			TextView message,time;
+			ImageView icon;
+
+			Holder(View cell) {
+				message = (TextView) cell.findViewById(R.id.tv_title);// 找某个控件
+				time = (TextView) cell.findViewById(R.id.tv_detail);
+				icon = (ImageView)cell.findViewById(R.id.iv_thumb);
+				cell.setTag(this);
+			}
+
+		}
+
+		// private Context context;
+		// private int i = 0;
+		public FavoritesAdapter(SearchResult result, Context context)
+		{
+
+//			this.mInflater = LayoutInflater.from(context);
+//			SQLiteDatabase db = dbUtil.OpenDB(getActivity(), null, false);
+//			Cursor cursor = db.query("favorites", new String[] { "_id",
+//					"create_time", "name", "params","module_name" }, "user='"
+//					+ ApexTrackingApplication.get_user() + "'", null, null,
+//					null, "_id desc", null);
+//
+//			result.add_records(cursor);
+//			dbUtil.CloseCursor(cursor);
+//			dbUtil.CloseDB(db);
+
+		}
+
+		Holder holder = null;
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			if (convertView == null) {
+				convertView = mInflater.inflate(R.layout.saved_cell, null);// 根据布局文件实例化view
+				holder = new Holder(convertView);
+			} else {
+				holder = (Holder) convertView.getTag();
+			}
+
+
+			String module_name = (String) searchresult.getData().get(position).get("module_name");
+			int rid= RAUtil.iconName2Rid(getActivity(),module_name);
+
+			holder.message.setText(searchresult.getData().get(position).get("name")
+					.toString());// 给该控件设置数据(数据从集合类中来)
+			holder.time.setText(DateFormat.format(
+					getString(R.string.time_format),
+					(Long) searchresult.getData().get(position)
+							.get("create_time")));
+			holder.icon.setImageResource(rid);
+
+
+			return convertView;
+		}
+
+		@Override
+		public int getCount()
+		{
+			return searchresult.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return searchresult.getData().get(position);
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return position;
+		}
+
+		@Override
+		public boolean getSwipEnableByPosition(int position) {
+			return true;
+		}
+	}
+
+	class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(Cursor c)
+		{
+			while (c.moveToNext())
+			{
+				long _id = c.getInt(0);
+				long create_time = c.getLong(1);
+				String name = c.getString(2);
+				String params = c.getString(3);
+				String module_name = c.getString(4);
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("_id", _id);
+
+				map.put("create_time", create_time);
+				map.put("name", name);
+
+				map.put("params", params);
+				map.put("module_name", module_name);
+
+				datalist.add(map);
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+//	@Override
+//	public boolean onTouch(View v, MotionEvent event)
+//	{
+//		switch (event.getAction())
+//		{
+//			case MotionEvent.ACTION_DOWN:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_DOWN"
+//						+ MotionEvent.ACTION_DOWN);
+//				// 手指按下,计算焦点位于ListView的那个条目
+//				pointX = (int) event.getX();
+//				pointY = (int) event.getY();
+//				// 备注1
+//				position = getListView().pointToPosition(pointX, pointY);
+//				if (curDel_btn != null)
+//				{
+//					curDel_btn.setVisibility(View.GONE);
+//				}
+//				break;
+//			case MotionEvent.ACTION_MOVE:
+//
+//				break;
+//			case MotionEvent.ACTION_UP:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_UP"
+//						+ MotionEvent.ACTION_UP);
+//				endX = (int) event.getX();
+//				endY = (int) event.getY();
+//				newpos = getListView().pointToPosition(endX, endY);
+//				// 原本想着加上这个条件(newpos==position)是不是更精确些,
+//				// 经过实践发现,其实我们在滑动listView的列表的时候有时候更渴望有滑动就ok
+//				if (Math.abs(endX - pointX) > 100 && newpos == position
+//						&& Math.abs(endY - pointY) < 100)
+//				{
+//					// 获取到ListView第一个可见条目的position
+//					int firstVisiblePosition = getListView()
+//							.getFirstVisiblePosition();
+//
+//					// --------------备注2
+//					View view = getListView().getChildAt(
+//							position - firstVisiblePosition);
+//					Button delbtn = (Button) view.findViewById(R.id.btn_del);
+//					delbtn.setVisibility(View.VISIBLE);
+//					curDel_btn = delbtn;
+//					delbtn.setOnClickListener(new View.OnClickListener()
+//					{
+//
+//						@Override
+//						public void onClick(View v)
+//						{
+//							// TODO Auto-generated method stub
+//
+//							SQLiteDatabase db = dbUtil.OpenDB(getActivity(),
+//									null, false);
+//							db.execSQL("delete from favorites where _id="
+//									+ (Long) searchresult.getData()
+//											.get(position).get("_id"));
+//							Log.d("sql delete" + position,
+//									"delete from push_message where _id="
+//											+ (Long) searchresult.getData()
+//													.get(position).get("_id"));
+//
+//							dbUtil.CloseDB(db);
+//							searchresult.getData().remove(position);
+//							adapter.notifyDataSetChanged();
+//						}
+//					});
+//
+//				}
+//				break;
+//
+//			default:
+//				break;
+//		}
+//		return false;
+//	}
+}

+ 388 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/SavedSearchFragment.java

@@ -0,0 +1,388 @@
+package com.usai.ratradefiling.my;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+
+import com.usai.ratradefiling.R;
+import com.usai.ratradefiling.swipemenulistview.BaseSwipListAdapter;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenu;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuCreator;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuItem;
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuListView;
+import com.usai.redant.rautils.utils.RAUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class SavedSearchFragment extends TFListFragment
+{
+	SearchResult	searchresult	= new SearchResult();
+	BaseAdapter		adapter			= null;
+	private int		pointX, pointY, endX, endY;
+	private int		position, newpos;
+	private Button	curDel_btn;
+	public void clear_result()
+	{
+		searchresult.getData().clear();
+	}
+	public void reload_adapter()
+	{
+		adapter.notifyDataSetChanged();
+	}
+	@Override
+	public void onActivityCreated(Bundle savedInstanceState)
+	{
+		super.onActivityCreated(savedInstanceState);
+		adapter = new HistoryAdapter(searchresult, getActivity());
+
+//		getListView().setOnTouchListener(this);
+		setListAdapter(adapter);
+//		this.getListView().setBackgroundColor(Color.WHITE);
+
+
+		// step 1. create a MenuCreator
+		SwipeMenuCreator creator = new SwipeMenuCreator() {
+
+			@Override
+			public void create(SwipeMenu menu) {
+
+				// create "delete" item
+				SwipeMenuItem deleteItem = new SwipeMenuItem(mContext);
+				// set item background
+				deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,0x3F, 0x25)));
+				// set item width
+				deleteItem.setWidth(dp2px(90));
+				// set a icon
+				deleteItem.setTitle("Delete");
+				// set item title fontsize
+				deleteItem.setTitleSize(18);
+				// set item title font color
+				deleteItem.setTitleColor(Color.WHITE);
+				// add to menu
+				menu.addMenuItem(deleteItem);
+			}
+		};
+		// set creator
+		mSwipeMenuListView.setMenuCreator(creator);
+
+		// step 2. listener item click event
+		mSwipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
+			@Override
+			public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
+
+
+				switch (index) {
+					case 0:
+						// delete
+//						SQLiteDatabase db = dbUtil.OpenDB(getActivity(), null, false);
+//							db.execSQL("delete from history where _id=" + (Long) searchresult.getData().get(position).get("_id"));
+//							dbUtil.CloseDB(db);
+//							searchresult.getData().remove(position);
+//							adapter.notifyDataSetChanged();
+//
+//						break;
+				}
+				return false;
+			}
+		});
+
+		// set SwipeListener
+		mSwipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
+
+			@Override
+			public void onSwipeStart(int position) {
+				// swipe start
+			}
+
+			@Override
+			public void onSwipeEnd(int position) {
+				// swipe end
+			}
+		});
+
+		// set MenuStateChangeListener
+		mSwipeMenuListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
+			@Override
+			public void onMenuOpen(int position) {
+			}
+
+			@Override
+			public void onMenuClose(int position) {
+			}
+		});
+	}
+
+	@Override
+	public void onListItemClick(ListView l, View v, int position, long id)
+	{
+
+		Intent intent = new Intent();
+		String uri = (String) searchresult.getData().get(position).get("params");
+		String searchParms = (String) searchresult.getData().get(position).get("criterion");
+		try
+		{
+//
+//			intent = Intent.parseUri(uri, 0);
+//			Bundle parms = new Bundle();
+////			parms.writeToParcel(parcel, flags)
+//			JSONObject obj = new JSONObject(searchParms);
+//			Iterator<?> it = obj.keys();
+//			while (it.hasNext())
+//			{
+//
+//				String key = (String) it.next();
+//				parms.putString(key, obj.getString(key));
+//
+////					obj.put(key, searchParms.get(key).toString());
+//
+//
+//
+//			}
+//
+//			parms.putString("columns",dbUtil.get_fields(ApexTrackingApplication.get_user(), (String) searchresult.getData().get(position).get("module_name")));
+//
+//
+//			ApexResultActivity.startResultActivity(getActivity(), parms);
+
+		}
+		catch (Exception e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	
+
+		
+
+	}
+	
+	private class HistoryAdapter extends BaseSwipListAdapter
+	{
+		private LayoutInflater	mInflater;	// 动态布局映射
+											// private SearchResult result;
+
+		class Holder {
+			TextView message,time;
+			ImageView icon;
+
+			Holder(View cell) {
+				message = (TextView) cell.findViewById(R.id.tv_title);// 找某个控件
+				time = (TextView) cell.findViewById(R.id.tv_detail);
+				icon = (ImageView)cell.findViewById(R.id.iv_thumb);
+				cell.setTag(this);
+			}
+
+		}
+		// private Context context;
+		// private int i = 0;
+		public HistoryAdapter(SearchResult result, Context context)
+		{
+//
+//			this.mInflater = LayoutInflater.from(context);
+//			SQLiteDatabase db = dbUtil
+//					.OpenDB(getActivity(), null, false);
+//			Cursor cursor = db.query("history",
+//					new String[] { "_id", "create_time", "criterion",
+//							"params","module_name" ,"name"}, "user='"
+//							+ ApexTrackingApplication.get_user() + "'", null,
+//					null, null, "_id desc", null);
+//
+//			result.add_records(cursor);
+//			dbUtil.CloseCursor(cursor);
+//			dbUtil.CloseDB(db);
+//
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent)
+		{
+			// TODO Auto-generated method stub
+			Holder holder = null;
+			if (convertView == null) {
+				convertView = mInflater.inflate(R.layout.saved_cell, null);// 根据布局文件实例化view
+				holder = new Holder(convertView);
+			} else {
+				holder = (Holder) convertView.getTag();
+			}
+
+
+			String name = (String) searchresult.getData().get(position).get("name");
+			if(TextUtils.isEmpty(name))
+			{
+				name = "";
+			}
+
+			String module_name = (String) searchresult.getData().get(position).get("module_name");
+			int rid= RAUtil.iconName2Rid(getActivity(),module_name);
+
+			holder.message.setText(name);// 给该控件设置数据(数据从集合类中来)
+			holder.time.setText(DateFormat.format(getString(R.string.time_format),(Long) searchresult.getData().get(position).get("create_time")));
+			holder.icon.setImageResource(rid);
+
+			return convertView;
+		}
+
+		@Override
+		public int getCount()
+		{
+			return searchresult.get_count();
+		}
+
+		@Override
+		public Object getItem(int position)
+		{
+			// TODO Auto-generated method stub
+			return searchresult.getData().get(position);
+		}
+
+		@Override
+		public long getItemId(int position)
+		{
+			// TODO Auto-generated method stub
+			return position;
+		}
+
+		@Override
+		public boolean getSwipEnableByPosition(int position) {
+			return true;
+		}
+	}
+	class SearchResult
+	{
+		List<Map<String, Object>>	datalist	= new ArrayList<Map<String, Object>>();
+
+		public int get_count()
+		{
+			return datalist.size();
+		}
+
+		public void add_records(Cursor c)
+		{
+			while (c.moveToNext())
+			{
+				long _id = c.getInt(0);
+				long create_time = c.getLong(1);
+				String criterion = c.getString(2);
+				String params = c.getString(3);
+				String module_name = c.getString(4);
+				String name = c.getString(5);
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("_id", _id);
+				
+				map.put("create_time", create_time);
+				map.put("criterion", criterion);
+				
+				map.put("params", params);
+				map.put("module_name", module_name);
+				map.put("name", name);
+
+				datalist.add(map);
+			}
+
+		}
+
+		public List<Map<String, Object>> getData()
+		{
+
+			return datalist;
+		}
+	}
+
+//	@Override
+//	public boolean onTouch(View v, MotionEvent event)
+//	{
+//		switch (event.getAction())
+//		{
+//			case MotionEvent.ACTION_DOWN:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_DOWN"
+//						+ MotionEvent.ACTION_DOWN);
+//				// 手指按下,计算焦点位于ListView的那个条目
+//				pointX = (int) event.getX();
+//				pointY = (int) event.getY();
+//				// 备注1
+//				position = getListView().pointToPosition(pointX, pointY);
+//				if (curDel_btn != null)
+//				{
+//					curDel_btn.setVisibility(View.GONE);
+//				}
+//				break;
+//			case MotionEvent.ACTION_MOVE:
+//
+//				break;
+//			case MotionEvent.ACTION_UP:
+//				System.out.println("====>>>>>>>>>>>>>>ACTION_UP"
+//						+ MotionEvent.ACTION_UP);
+//				endX = (int) event.getX();
+//				endY = (int) event.getY();
+//				newpos = getListView().pointToPosition(endX, endY);
+//				// 原本想着加上这个条件(newpos==position)是不是更精确些,
+//				// 经过实践发现,其实我们在滑动listView的列表的时候有时候更渴望有滑动就ok
+//				if (Math.abs(endX - pointX) > 100 && newpos == position
+//						&& Math.abs(endY - pointY) < 100)
+//				{
+//					// 获取到ListView第一个可见条目的position
+//					int firstVisiblePosition = getListView()
+//							.getFirstVisiblePosition();
+//
+//					// --------------备注2
+//					View view = getListView().getChildAt(
+//							position - firstVisiblePosition);
+//					Button delbtn = (Button) view.findViewById(R.id.btn_del);
+//					delbtn.setVisibility(View.VISIBLE);
+//					curDel_btn = delbtn;
+//					delbtn.setOnClickListener(new View.OnClickListener()
+//					{
+//
+//						@Override
+//						public void onClick(View v)
+//						{
+//							// TODO Auto-generated method stub
+//
+//							SQLiteDatabase db = dbUtil.OpenDB(
+//									getActivity(), null, false);
+//							db.execSQL("delete from history where _id="
+//									+ (Long) searchresult.getData()
+//											.get(position).get("_id"));
+//							Log.d("sql delete" + position,
+//									"delete from push_message where _id="
+//											+ (Long) searchresult.getData()
+//													.get(position).get("_id"));
+//
+//							dbUtil.CloseDB(db);
+//							searchresult.getData().remove(position);
+//							adapter.notifyDataSetChanged();
+//						}
+//					});
+//
+//				}
+//				break;
+//
+//			default:
+//				break;
+//		}
+//		return false;
+//	}
+}

+ 100 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/my/TFListFragment.java

@@ -0,0 +1,100 @@
+package com.usai.ratradefiling.my;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.fragment.app.ListFragment;
+
+import com.usai.ratradefiling.swipemenulistview.SwipeMenuListView;
+
+//import com.usai.apex.swipemenulistview.SwipeMenuListView;
+
+/**
+ * Created by macmini1 on 2018/2/28.
+ */
+
+public class TFListFragment extends ListFragment
+{
+
+
+    static final int INTERNAL_EMPTY_ID = 0x00ff0001;
+    static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
+    static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
+
+    public SwipeMenuListView mSwipeMenuListView;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        final Context context = getContext();
+
+        FrameLayout root = new FrameLayout(context);
+
+        // ------------------------------------------------------------------
+
+        LinearLayout pframe = new LinearLayout(context);
+        pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
+        pframe.setOrientation(LinearLayout.VERTICAL);
+        pframe.setVisibility(View.GONE);
+        pframe.setGravity(Gravity.CENTER);
+
+        ProgressBar progress = new ProgressBar(context, null,
+                android.R.attr.progressBarStyleLarge);
+        pframe.addView(progress, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+        root.addView(pframe, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // ------------------------------------------------------------------
+
+        FrameLayout lframe = new FrameLayout(context);
+        lframe.setId(INTERNAL_LIST_CONTAINER_ID);
+
+        TextView tv = new TextView(context);
+        tv.setId(INTERNAL_EMPTY_ID);
+        tv.setGravity(Gravity.CENTER);
+        lframe.addView(tv, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+
+        SwipeMenuListView lv = new SwipeMenuListView(context);
+        mSwipeMenuListView = lv;
+        lv.setId(android.R.id.list);
+        lv.setDrawSelectorOnTop(false);
+
+        lframe.addView(lv, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        root.addView(lframe, new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // ------------------------------------------------------------------
+
+        root.setLayoutParams(new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+
+        return root;
+    }
+
+    public Context mContext;
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mContext = context;
+    }
+
+    public int dp2px(int dp) {
+        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
+                getResources().getDisplayMetrics());
+    }
+}

+ 41 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/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.ratradefiling.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
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenu.java

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

+ 149 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuAdapter.java

@@ -0,0 +1,149 @@
+package com.usai.ratradefiling.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);
+        }
+        layout.closeMenu();
+        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
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuCreator.java

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

+ 96 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuItem.java

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

+ 348 - 0
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuLayout.java

@@ -0,0 +1,348 @@
+package com.usai.ratradefiling.swipemenulistview;
+
+import android.content.Context;
+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;
+
+import androidx.core.view.GestureDetectorCompat;
+import androidx.core.widget.ScrollerCompat;
+
+/**
+ * 
+ * @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 ((int)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
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuListView.java

@@ -0,0 +1,339 @@
+package com.usai.ratradefiling.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
ApexDrivers/ratradefiling/src/main/java/com/usai/ratradefiling/swipemenulistview/SwipeMenuView.java

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

+ 19 - 0
ApexDrivers/ratradefiling/src/main/res/layout/activity_check_saved.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".my.CheckSavedActivity">
+
+    <FrameLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+    </FrameLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 55 - 0
ApexDrivers/ratradefiling/src/main/res/layout/saved_cell.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/list_bg"
+    android:orientation="vertical">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="56dp">
+
+        <TextView
+            android:id="@+id/tv_title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginEnd="16dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginTop="4dp"
+            android:layout_weight="1"
+            android:text="Tool name"
+            android:textAlignment="viewStart"
+            android:gravity="start"
+            android:textColor="@android:color/black"
+            android:textSize="14sp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/iv_thumb"
+            app:layout_constraintTop_toTopOf="@+id/iv_thumb" />
+
+        <ImageView
+            android:id="@+id/iv_thumb"
+            android:layout_width="42dp"
+            android:layout_height="42dp"
+            android:layout_marginStart="16dp"
+            android:contentDescription="TODO" android:src="@mipmap/ic_launcher"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tv_detail"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:lines="1"
+            android:text="TextView"
+            android:textSize="9.7sp"
+            app:layout_constraintStart_toEndOf="@+id/iv_thumb"
+            app:layout_constraintTop_toBottomOf="@+id/tv_title" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</LinearLayout>

+ 15 - 0
ApexDrivers/ratradefiling/src/main/res/menu/checksaved.xml

@@ -0,0 +1,15 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+ >
+
+    
+    <item
+        android:id="@+id/action_deleteall"
+        android:orderInCategory="200"
+
+
+        android:visible="true"
+        app:showAsAction="always"
+        android:title="@string/action_deleteall"/>
+
+</menu>

+ 5 - 1
ApexDrivers/ratradefiling/src/main/res/values-zh/strings.xml

@@ -37,6 +37,8 @@
     <string name="str_false">false</string>
     <string name="action_help">Help</string>
     <string name="str_ok">Ok</string>
+    <string name="action_deleteall">Delete all</string>
+    <string name="time_format">MM/dd/yyyy kk:mm:ss</string>
 
     <!--Fields-->
     <string name="prompt_search_criterion">Enter criterion</string>
@@ -49,7 +51,9 @@
 
     <!--Save-->
     <string name="str_createname">Create a tag to save</string>
-
+    <string name="str_deletemessage">Click delete button to begin delete</string>
+    <string name="str_confirmdelete">Confirm delete</string>
+    <string name="str_del">Del</string>
 
     <!--Login-->
     <string name="login_progress_signing_in">Login&#8230;</string>

+ 6 - 0
ApexDrivers/ratradefiling/src/main/res/values/strings.xml

@@ -37,6 +37,9 @@
     <string name="str_false">false</string>
     <string name="action_help">Help</string>
     <string name="str_ok">Ok</string>
+    <string name="action_deleteall">Delete all</string>
+    <string name="time_format">MM/dd/yyyy kk:mm:ss</string>
+
     <!--Fields-->
     <string name="prompt_search_criterion">Enter criterion</string>
     <string name="str_clear">Clear</string>
@@ -48,6 +51,9 @@
 
     <!--Save-->
     <string name="str_createname">Create a tag to save</string>
+    <string name="str_deletemessage">Click delete button to begin delete</string>
+    <string name="str_confirmdelete">Confirm delete</string>
+    <string name="str_del">Del</string>
 
     <!--Login-->
     <string name="login_progress_signing_in">Login&#8230;</string>