Android常用组件——定制化的SwipeListView
来源:互联网 发布:淘宝店怎么改名字 编辑:程序博客网 时间:2024/05/22 17:14
1、背景介绍
其实要实现的东西并不算太复杂,类似于QQ那样的ListView横向滑动展现删除控件而已。图示,如下:
2、SwipeListView
介绍一下,我在最开始实现这样的功能的时候,找到的是这样的一个开源控件,名字如标题,地址是:https://github.com/47deg/android-swipelistview
大家可以直接在GitHub上去看,不过这个项目的注释写得可能有些不太清楚,简单列举一些它的属性如下:
swipeFrontView - Required - front view id. 即ListView Item正常显示的控件Id,且必须与Item的布局文件中的控件id一样swipeBackView - Required - back view id. 手指滑动时显示的,隐藏在FrontView后面,且必须与item的布局文件中控件Id一样swipeActionLeft - Optional - left swipe action Default: 'reveal' 左滑的动作,默认reveal,即显示BackView,还有dismiss,choice会触发响应的方法。swipeActionRight - Optional - right swipe action Default: 'reveal' 同上swipeMode - Gestures to enable or 'none'. Default: 'both' 设置左滑、右滑、都支持swipeCloseAllItemsWhenMoveList - Close revealed items on list motion. Default: 'true' 当滚动listview时,关闭所有展开的Item,最好不要设置为false,由于item的复用,false存在一些问题。swipeOpenOnLongPress - Reveal on long press Default: 'true' 长按时触发显示swipeAnimationTime - item drop animation time. Default: android configuration 动画时间长度swipeOffsetLeft - left offset 左偏移量swipeOffsetRight - right offset 右偏移量
使用的代码,XML文件代码如下:
<com.fortysevendeg.swipelistview.SwipeListView xmlns:swipe="http://schemas.android.com/apk/res-auto" android:id="@+id/example_lv_list" android:listSelector="#00000000" android:layout_width="fill_parent" android:layout_height="wrap_content" swipe:swipeFrontView="@+id/front" swipe:swipeBackView="@+id/back" swipe:swipeActionLeft="[reveal | dismiss]" swipe:swipeActionRight="[reveal | dismiss]" swipe:swipeMode="[none | both | right | left]" swipe:swipeCloseAllItemsWhenMoveList="[true | false]" swipe:swipeOpenOnLongPress="[true | false]" swipe:swipeAnimationTime="[miliseconds]" swipe:swipeOffsetLeft="[dimension]" swipe:swipeOffsetRight="[dimension]" />
可能接下来会有一个比较容易出错的地方,这里官方文档也没有提及,就是布局文件是两层覆盖的,菜单那一层在下面,但是写代码的时候,在XML文件的上半部分,我们看一个简单的框架案例:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="60dp" > <LinearLayout android:id="@+id/id_back" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffcccccc" android:gravity="center|right" > <Button android:id="@+id/id_remove" android:layout_width="60dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginRight="4dp" android:background="@drawable/red_button" android:text="Delete" android:textColor="#fff" > </Button> </LinearLayout> <LinearLayout android:id="@+id/id_front" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffffff" > <TextView android:id="@+id/id_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#000" android:textSize="25sp" > </TextView> </LinearLayout></FrameLayout>
如上就是一个item的布局文件,一定要注意两个Layout的id值,不能修改!!!一定要是back和front,不然程序会报错一个无法找到文件的错误。
不过这个代码,无法实现如上图的扁平化的风格。我只好重新试试别的方法。
3、SwipeMenuListView
这个控件没怎么看到有人提及,也可能是这个控件不如上面那一个出来得早的缘故吧。现在也给出github上的地址,如下:https://github.com/baoyongzhang/SwipeMenuListView
这个就不多说了,给一个案例吧,作者自己的代码,代码不多,核心代码也就只有几句话,如下:
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); // step 1. create a MenuCreator SwipeMenuCreator creator = new SwipeMenuCreator() { @Override public void create(SwipeMenu menu) { // create "open" item SwipeMenuItem openItem = new SwipeMenuItem( getApplicationContext()); // set item background openItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9, 0xCE))); // set item width openItem.setWidth(dp2px(90)); // set item title openItem.setTitle("Open"); // set item title fontsize openItem.setTitleSize(18); // set item title font color openItem.setTitleColor(Color.WHITE); // add to menu menu.addMenuItem(openItem); // create "delete" item SwipeMenuItem deleteItem = new SwipeMenuItem( getApplicationContext()); // set item background deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9, 0x3F, 0x25))); // set item width deleteItem.setWidth(dp2px(90)); // set a icon deleteItem.setIcon(R.drawable.ic_delete); // add to menu menu.addMenuItem(deleteItem); } }; // set creator mListView.setMenuCreator(creator); // step 2. listener item click event mListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(int position, SwipeMenu menu, int index) { ApplicationInfo item = mAppList.get(position); switch (index) { case 0: // open open(item); break; case 1: // delete//delete(item); mAppList.remove(position); mAdapter.notifyDataSetChanged(); break; } return false; } }); // set SwipeListener mListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() { @Override public void onSwipeStart(int position) { // swipe start } @Override public void onSwipeEnd(int position) { // swipe end } }); // set MenuStateChangeListener mListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() { @Override public void onMenuOpen(int position) { } @Override public void onMenuClose(int position) { } }); // other setting//listView.setCloseInterpolator(new BounceInterpolator()); // test item long click 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; } }); } private void delete(ApplicationInfo item) { // delete app try { Intent intent = new Intent(Intent.ACTION_DELETE); intent.setData(Uri.fromParts("package", item.packageName, null)); startActivity(intent); } catch (Exception e) { } } private void open(ApplicationInfo item) { // open app Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); resolveIntent.setPackage(item.packageName); List<ResolveInfo> resolveInfoList = getPackageManager() .queryIntentActivities(resolveIntent, 0); if (resolveInfoList != null && resolveInfoList.size() > 0) { 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 BaseAdapter { @Override public int getCount() { return mAppList.size(); } @Override public ApplicationInfo getItem(int position) { return mAppList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = View.inflate(getApplicationContext(), R.layout.item_list_app, null); new ViewHolder(convertView); } ViewHolder holder = (ViewHolder) convertView.getTag(); ApplicationInfo item = getItem(position); holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager())); holder.tv_name.setText(item.loadLabel(getPackageManager())); return convertView; } class ViewHolder { ImageView iv_icon; TextView tv_name; public ViewHolder(View view) { iv_icon = (ImageView) view.findViewById(R.id.iv_icon); tv_name = (TextView) view.findViewById(R.id.tv_name); view.setTag(this); } } } private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); } @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.DIRECTION_LEFT); return true; } if (id == R.id.action_right) { mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_RIGHT); return true; } return super.onOptionsItemSelected(item); }}
4、总结
在3中使用的控件,可以实现我们想要的效果。但是相对来说,2中的控件的设计模式更适合扩展,耦合性更低一些,3中的设计不是那么好用。
将就一下,之后再去更改吧。说个题外话,如果是嵌套使用了ScrollView,那么最好在ListView中重写如下的方法:
// 重写,适应外层嵌套ScrollView protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }
0 0
- Android常用组件——定制化的SwipeListView
- android库SwipeListView的使用
- android开发之SwipeListView的使用
- android 定制组件的三种方式
- Android定制组件的三种方式
- Android中定制组件
- Android SwipeListView用法
- android-swipelistview使用说明
- SwipeListView滑动删除Android
- 创建定制的组件
- 关于android-swipelistview的开源项目的使用
- Android SwipeListView 实现ListView的滑动删除效果
- Android SwipeListView 实现ListView的滑动删除效果
- 可视化组件——iChart.js定制
- 可视化组件——iChart.js定制
- android 常用功能组件——TimerTask
- android常用功能组件——setRequestedOrientation
- Android —定制ListView
- break,continue和return
- 安装android驱动解决device not found
- 算法导论12.2查询二叉搜索树 练习总结
- 网络编程_post_异步-代理_获取网络数据
- 采样频率Hz 采样率KSPS或MSPS,两种单位的换算关系
- Android常用组件——定制化的SwipeListView
- ajax不能跳转页面,需要传递Message来决定结果
- linux定时任务的设置
- 第二十二篇:UITableView练习代码
- 网络编程_post_异步-请求_获取网络数据
- No2地图 MapKit框架
- NDK调试
- 架构之路(一):目标
- showModelessDialog() 详解