版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/79064198
一、实现效果:

二、分析
先看两个图:有一个大体的了解
这是框架中所有的类。
1.下面的图是视图层次:

上面的图中:SwipeMenuLayout是ListView中item的布局,分左右两部分,一部分是正常显示的contentView,一部分是滑出来的menuView;滑出来的SwipeMenuView继承自LinearLayout,添加view时,就是横向添加,可以横向添加多个。
2.下面的图是类图结构:

上面是类之间的调用关系,类旁边注明了类的主要作用。
三、使用
1、从github上下载开源项目SwipeMenuListView的源码:https://github.com/baoyongzhang/SwipeMenuListView
2、在自己项目中新建一个包,名字为:com.baoyz.swipemenulistview(这里我们包的名字最好不要改变,否则里面一些导入的类也要改变路径),然后将目录SwipeMenuListView-master\library\src\main\java\com\baoyz\swipemenulistview\下面的文件复制到我们新建的包里面。
以上两步简便操作:
dependencies {
compile 'com.baoyz.swipemenulistview:library:1.3.0'
}
3、添加布局
在我们需要使用该效果的布局文件中添加如下代码:
<com.baoyz.swipemenulistview.SwipeMenuListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
4、swipeMenuListView使用
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.baoyz.swipemenulistview.BaseSwipListAdapter;
import com.baoyz.swipemenulistview.SwipeMenu;
import com.baoyz.swipemenulistview.SwipeMenuCreator;
import com.baoyz.swipemenulistview.SwipeMenuItem;
import com.baoyz.swipemenulistview.SwipeMenuListView;
import java.util.List;
/**
* SwipeMenuListView
* Created by baoyz on 15/6/29.
*/
public class SimpleActivity extends Activity {
private List<ApplicationInfo> mAppList;
private AppAdapter mAdapter;
private SwipeMenuListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
mAppList = getPackageManager().getInstalledApplications(0);
mListView = (SwipeMenuListView) findViewById(R.id.listView);
mAdapter = new AppAdapter();
mListView.setAdapter(mAdapter);
// 第1步:设置创建器,并且在其中生成我们需要的菜单项,将其添加进菜单中
SwipeMenuCreator creator = new SwipeMenuCreator() {
@Override
public void create(SwipeMenu menu) {
// 创建“打开”项
SwipeMenuItem openItem = new SwipeMenuItem(
getApplicationContext());
openItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
0xCE)));
openItem.setWidth(dp2px(90));
openItem.setTitle("Open");
openItem.setTitleSize(18);
openItem.setTitleColor(Color.WHITE);
// 将创建的菜单项添加进菜单中
menu.addMenuItem(openItem);
// 创建“删除”项
SwipeMenuItem deleteItem = new SwipeMenuItem(
getApplicationContext());
deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,
0x3F, 0x25)));
deleteItem.setWidth(dp2px(90));
deleteItem.setIcon(R.drawable.ic_delete);
// 将创建的菜单项添加进菜单中
menu.addMenuItem(deleteItem);
}
};
// 为ListView设置创建器
mListView.setMenuCreator(creator);
// 第2步:为ListView设置菜单项点击监听器,来监听菜单项的点击事件
mListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
//position:列表项的下标。如:0,1,2,3,4,...
//index:菜单项的下标。如:0,1,2,3,4,...
ApplicationInfo item = mAppList.get(position);
switch (index) {
case 0:
// open
open(item);
break;
case 1:
// delete
// delete(item);
mAppList.remove(position);
//通知监听者数据集发生改变,更新ListView界面
mAdapter.notifyDataSetChanged();
break;
}
// true:其他已打开的列表项的菜单状态将保持原样,不会受到其他列表项的影响而自动收回
// false:已打开的列表项的菜单将自动收回
return false;
}
});
// 设置侧滑监听器,监听侧滑开始和侧滑结束
// 注意:当我们将一个已经侧滑出来的菜单重新收回去的时候并不会调用onSwipeStart方法,
// 但是结束的时候依然会调用onSwipeEnd方法
mListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
@Override
public void onSwipeStart(int position) {
// swipe start
}
@Override
public void onSwipeEnd(int position) {
// swipe end
}
});
// 设置监听Menu状态改变的监听器(Menu的打开和关闭)
mListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
@Override
public void onMenuOpen(int position) {
}
@Override
public void onMenuClose(int position) {
}
});
// other setting
// listView.setCloseInterpolator(new BounceInterpolator());
// 设置列表项长点击的监听器
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(), position + " long click", Toast.LENGTH_SHORT).show();
return false;
}
});
}
//删除一个应用,在这里并没有被调用,因为这会卸载相应的app
private void delete(ApplicationInfo item) {
try {
Intent intent = new Intent(Intent.ACTION_DELETE);
intent.setData(Uri.fromParts("package", item.packageName, null));
startActivity(intent);
} catch (Exception e) {
}
}
// 打开app
private void open(ApplicationInfo item) {
// Intent.ACTION_MAIN:作为主进入点启动,并不期望获得数据
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
//根据传进来的ApplicationInfo item设置要解析的应用的包名
resolveIntent.setPackage(item.packageName);
//根据指定的Intent解析出对应的应用中所有的activity的信息
List<ResolveInfo> resolveInfoList = getPackageManager()
.queryIntentActivities(resolveIntent, 0);
if (resolveInfoList != null && resolveInfoList.size() > 0) {
//ResolveInfo:返回依据IntentFilter解析出来的Intent所返回的信息。
//此部分对应于从AndroidManifest.xml中<意图>标签收集信息。
//解析出来的第一个为主activity的信息
ResolveInfo resolveInfo = resolveInfoList.get(0);
String activityPackageName = resolveInfo.activityInfo.packageName;
String className = resolveInfo.activityInfo.name;
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName componentName = new ComponentName(
activityPackageName, className);
intent.setComponent(componentName);
startActivity(intent);
}
}
class AppAdapter extends BaseSwipListAdapter {
@Override
public int getCount() {
return mAppList.size();
}
@Override
public ApplicationInfo getItem(int position) {
return mAppList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
//夹在金列表项的布局item_list_app.xml
convertView = View.inflate(getApplicationContext(),
R.layout.item_list_app, null);
new ViewHolder(convertView);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
// 获取手机全部应用的信息
ApplicationInfo item = getItem(position);
// 加载应用的图标
holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
// 加载应用的标题
holder.tv_name.setText(item.loadLabel(getPackageManager()));
// 为图标设置点击事件监听器(弹出一个toast)
holder.iv_icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(SimpleActivity.this, "iv_icon_click", Toast.LENGTH_SHORT).show();
}
});
// 为应用名字设置点击监听器(弹出一个toast)
holder.tv_name.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(SimpleActivity.this,"iv_icon_click",Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
class ViewHolder {
ImageView iv_icon;
TextView tv_name;
//根据传进来的convertView创建ViewHolder,并且将其设置为convertView的Tag
public ViewHolder(View view) {
iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
tv_name = (TextView) view.findViewById(R.id.tv_name);
view.setTag(this);
}
}
//这里我们可以根据列表项的位置来设置某项是否允许侧滑
//(此处我们设置的是当下标为偶数项的时候不允许侧滑)
@Override
public boolean getSwipEnableByPosition(int position) {
if(position % 2 == 0){
return false;
}
return true;
}
}
// 将dp转换为px
private int dp2px(int value) {
// 第一个参数为我们待转的数据的单位,此处为 dp(dip)
// 第二个参数为我们待转的数据的值的大小
// 第三个参数为此次转换使用的显示量度(Metrics),它提供屏幕显示密度(density)和缩放信息
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
getResources().getDisplayMetrics());
}
//另一种将dp转换为px的方法
private int dp2px(float value){
final float scale = getResources().getDisplayMetrics().density;
return (int)(value*scale + 0.5f);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_left) {
//这里我们可以通过mListView的setSwipeDirection方法来设置SwipeMenuListView的滑动方向
mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
return true;
}
if (id == R.id.action_right) {
mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_RIGHT);
return true;
}
return super.onOptionsItemSelected(item);
}
}
四、源码分析
源码分析在源码中有备注,需要请下载:http://download.csdn.net/download/chaoyu168/10206429