- 浏览: 132033 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
memoryisking:
可以看看这篇文章,构建一个简单的线程池,这个是struts教程 ...
java 线程池示例(自己实现的参考别人的代码) -
zwq194:
坑爹啊,误导人,代码有问题
java 线程池示例(自己实现的参考别人的代码) -
zhouming4455:
貌似你传错了哦
java 线程池示例(自己实现的参考别人的代码)
通过继承 ListView 实现可拖拽的 ListView ,先说说实现拖拽的原理吧,实现拖拽需要考虑三个问题:第一怎么确定你在拖拽 listview 里面的 item 的时候就是你手指当前选中的 item ;第二实现拖拽的效果,就是有一个浮动的层跟随你的手指在移动;第三你放开手指时怎么把你拖拽的这个 item 放到当前 listView 的位置(也就是说改变 item 的位置)。 明白了这三个问题就比较好实现了。
里面会涉及到一些比较重要的方法调用,首先是 pointToPosition(int x, int y) 这方方法 Android 官方的解释是 ” Maps a point to a position in the list” ,我把它理解为通过 x 和 y 的位置来确定这个 listView 里面这个 item 的位置。 有了这个方法就解决了第一和第三个问题了。接下来我们可以通过 WindowManager 来解决第二个问题,然后通过 pointToPosition 方法就可以获取你手指按下时的 item ,这个 item 其实就是你 listview 里面的 item 了 ,这样的就可以把这个 item 设置为是 WindowManager 的 view ,这样的话拖动的层的效果就模拟出来了,接下来是怎么让这个 WindowManager 跟随你的手指在移动。这个时候会涉及到 WindowManager 里面的 updateViewLayout(view, layoutparams) 来刷新 WindowManager 的位置,这样就实现了 WindowManager 会跟随你的手指在移动。最后就剩下你放下手指的时候怎么让你拖拽的 item 插入到 listview 里面,这个插入的动作其实包含了移除和插 入这两个动作。这个时候你可能会问在某个位置插入这个 item 需要 ”position” 和 ”item” 两个参数, position 我们可以通过 pointToPosition 方法来获取,然后要插入的“ item ”其实是你 adapter 里面数据。因为我们上面的一系列动作都是在 listview 里面完成的,但是在我们重写 listview 的时候是还没有给 listview 设置 adapter 是吧,这个问题的我们通过在重写 listview 的类中自定义一个接口,然后你在 activity 里面初始化 listview 数据的时候实现这个接口。接口里面只有一个方法,方法里面的两个参数一个是你开始拖拽的的 item 的位置,另一个是你拖拽移动之后之后的 item 的位置。下面我们看看效果吧:
private final float mAlpha = 0.9f; //拖动的view private ImageView mDragView; private Context mContext; private WindowManager mWindowManager; private WindowManager.LayoutParams mLayoutParams; //开始拖动时的位置 private int mDragStartPosition; //当前的位置 private int mDragCurrentPostion; //在滑动的时候,手的移动要大于这个返回的距离值才开始移动控件 private int mScaledTouchSlop; //当前位置距离边界的位置 private int mDragOffsetX; private int mDragOffSetY; //移动的位置 private int mDragPointX; private int mDragPointY; //边界 private int mUpperBound; private int mLowerBound; private DropViewListener mDropViewListener; public DragListView(Context context) { super(context); mContext = context; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mScaledTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); } public DragListView(Context context, AttributeSet attr) { super(context, attr); mContext = context; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mScaledTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); }
我们在onInterceptTouchEvent方法里面作初始化动作:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//ev.getX()相对于控件本身左上角,ev.getRawX()相对于容器圆点位置
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
final int x = (int) ev.getX();//相对于空间本身
final int y = (int) ev.getY();
final int itemNum = pointToPosition(x, y);
if(itemNum == AdapterView.INVALID_POSITION){
break;
}
final ViewGroup item = (ViewGroup) getChildAt(itemNum - getFirstVisiblePosition());
mDragPointX = x - item.getLeft();
mDragPointY = y - item.getTop();
mDragOffsetX = ((int) ev.getRawX()) - x;
mDragOffSetY = ((int) ev.getRawY()) - y;
//长按
item.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//计算边界
final int height = getHeight();
mUpperBound = Math.min(y - mScaledTouchSlop, height / 3);
mLowerBound = Math.max(y + mScaledTouchSlop, height * 2 / 3);
mDragCurrentPostion = mDragStartPosition = itemNum;
item.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
startDragging(bitmap, x, y);
return true;
}
});
break;
}
return super.onInterceptTouchEvent(ev);
}
这里面我们就记录了拖拽的当前和开始时位置mDragCurrentPostion和 mDragStartPosition,并通过startDragging来初始化mWindowManager,在startDragging方法里面调用的stopDragging方法其实是一个内存释放的过程,这个方法做的事情就是释放内存空间。
private void startDragging(Bitmap bitm, int x, int y){
stopDragging();
mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
mLayoutParams.x = x - mDragPointX + mDragOffsetX;
mLayoutParams.y = y - mDragPointY + mDragOffSetY;
mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
mLayoutParams.format = PixelFormat.TRANSLUCENT;
mLayoutParams.windowAnimations = 0;
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitm);
imageView.setBackgroundResource(R.drawable.tab_item_bg);
imageView.setPadding(0, 0, 0, 0);
mWindowManager.addView(imageView, mLayoutParams);
mDragView = imageView;
}
private void stopDragging(){
if(mDragView != null){
mWindowManager.removeView(mDragView);
mDragView.setImageDrawable(null);
mDragView = null;
}
}
我们在onInterceptTouchEvent方法记录了拖拽的开始位置和当前位置,并且初始化了windowmanager,接下来我们通过onTouchEvent方法来实现让windowmanager跟随你的手指移动
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(mDragView != null && mDragCurrentPostion != INVALID_POSITION && mDropViewListener != null){
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
//int y = (int) ev.getY();
stopDragging();
//数据交换
if(mDragCurrentPostion >= 0 && mDragCurrentPostion < getCount()){
mDropViewListener.drop(mDragStartPosition, mDragCurrentPostion);
}
break;
case MotionEvent.ACTION_MOVE:
int x = (int) ev.getX();
int y = (int) ev.getY();
dragView(x, y);
if (y >= getHeight() / 3) {
mUpperBound = getHeight() / 3;
}
if (y <= getHeight() * 2 / 3) {
mLowerBound = getHeight() * 2 / 3;
}
int speed = 0;
if (y > mLowerBound) {
if (getLastVisiblePosition() < getCount() - 1) {
speed = y > (getHeight() + mLowerBound) / 2 ? 16 : 4;
} else {
speed = 1;
}
} else if (y < mUpperBound) {
speed = y < mUpperBound / 2 ? -16 : -4;
if (getFirstVisiblePosition() == 0
&& getChildAt(0).getTop() >= getPaddingTop()) {
speed = 0;
}
}
if (speed != 0) {
smoothScrollBy(speed, 30);
}
break;
}
return true;
}
return super.onTouchEvent(ev);
}
其中dragView方法就是根据你手指移动来改变windowmanager的位置,在移动的时候我们需要考虑的另外一个问题是你的listview滚动条的时候,这个时候我们需要考虑边界,不然会抛出空指针异常。
private void dragView(int x, int y){
if(mDragView != null){
mLayoutParams.alpha = mAlpha;
mLayoutParams.y = y - mDragPointY + mDragOffSetY;
mLayoutParams.x = x - mDragPointX + mDragOffsetX;
mWindowManager.updateViewLayout(mDragView, mLayoutParams);
}
int tempPosition = pointToPosition(0, y);
if(tempPosition != INVALID_POSITION){
mDragCurrentPostion = tempPosition;
}
//滚动
int scrollY = 0;
if(y < mUpperBound){
scrollY = 8;
}else if(y > mLowerBound){
scrollY = -8;
}
if(scrollY != 0){
int top = getChildAt(mDragCurrentPostion - getFirstVisiblePosition()).getTop();
setSelectionFromTop(mDragCurrentPostion, top + scrollY);
}
}
这样的话就完成了拖拽的效果,剩下的是你放开手指,然后把你拖拽的item插入到listview的列表里面,我们定义了一个接口
1 |
public void setDropViewListener(DropViewListener listener){ |
2 |
this .mDropViewListener = listener; |
3 |
} |
4 |
|
5 |
public interface DropViewListener { |
6 |
void drop( int from, int to); |
7 |
} |
这样的话,你在初始化listview给listView设置adapter的时候需要实现DropViewListener接口,from和to两个参数分别是你拖拽时的最初位置和你移动后的位置,这样的话你在activity里面就可以实现数据插入了。 注意:
但是如果你的这listview的item包含了复选框的话,这个时候 listview的onitemclicklistener事件就会失效,也就是说你不能通过你平时处理listview的 onitemclicklistener的方法一样处理,你也可以通过自定义接口来模拟onitemclicklistener事件
return true;http://blog.csdn.net/chenjie19891104/article/details/7031713
发表评论
-
监听HOME键
2013-05-16 12:20 839class HomeKeyEventBroadCastR ... -
调用系统接口发送短信
2013-01-30 18:59 1177String smsContent = getwSMS(mRe ... -
调用android自带的联系人
2013-01-29 19:42 1030在android程序的开发中,经常要实现的一个功能是调用系统 ... -
横竖屏
2013-01-11 13:40 799总结: 1、不设置Activity的android:co ... -
代码调用menu
2013-01-10 09:17 1046<!-- @pa ... -
[转载]Android 浅谈ANR
2013-01-10 09:14 944一:什么是 ANR A ... -
Intent FLAG详解
2012-12-28 21:21 1526Intent FLAG详解 public static f ... -
Android TextView属性详解
2012-11-17 11:23 745android:autoLink设置是否当文本为URL链接/e ... -
[教程] 【转】Android 通过软引用实现图片缓存,防止内存溢出 [复制链接]
2012-09-22 19:18 4112public class BitmapCache { s ... -
Android使用Application总结
2012-09-22 11:56 824Android使用Application总结 ... -
raw文件夹下资源的访问
2012-09-21 16:50 13641: 重命名raw下资源的名字, 规则如下, 在每个资源文件的 ... -
Android自定义组件2转载
2012-09-18 22:10 848原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 ... -
自定义控件
2012-09-18 16:17 962<com.yulin.test.MyView ... -
onNewIntent()与singleTask启动模式
2012-09-18 10:52 3081... -
可以拖动的listview+限制拖动某一图片
2012-09-16 08:43 1053可以拖动的listview+限制拖动某一图片 p ... -
Android自定义属性,format详解
2012-09-14 18:20 6681. reference:参考某一资源ID。 ... -
Application共享全局变量和注册全局broadcast
2012-09-14 09:21 20myApplication extends Appli ... -
onSharedPreferenceChangeListener类
2012-09-13 17:02 2237onSharedPreferenceChangeListe ... -
enum用法
2012-09-13 14:42 855public class timeofdayManager { ... -
Android 4.0 Launcher2源码分析——启动过程分析
2012-09-12 13:43 895http://www.2cto.com/kf/201208/1 ...
相关推荐
要实现“android可拖动listview”,我们需要关注以下几个关键知识点: 1. **Drag and Drop API**:Android系统提供了一套Drag and Drop API,用于处理拖放操作。我们需要在ListView的Item视图上添加OnTouchListener...
这个库允许用户通过手势拖动ListView中的item,以改变它们的顺序,从而提供了一种直观且用户友好的交互体验。 首先,我们需要在项目中引入`DragSortListView`库。如果你使用的是Gradle构建系统,可以在`build....
总结来说,实现Android ListView中可拖拽Item的功能需要对触摸事件、DragEvent和Adapter有深入理解。通过自定义布局、监听器和适配器更新,我们可以创建出具有高度交互性的ListView。同时,别忘了在设计和实现过程中...
"android listview 拖拽效果"是指在ListView上实现的一项高级功能,允许用户通过手势拖动ListView中的每个条目(item)来改变它们的位置,提供了一种直观且交互性强的用户体验。在本篇文章中,我们将深入探讨如何...
要实现ListView的item可拖动效果,可以增强用户体验,让应用更具交互性。本文将详细介绍如何在Android中实现ListView的拖动功能。 首先,我们需要了解ListView的工作原理。ListView通过Adapter来绑定数据,并通过...
android的一个可拖拽ListView,是继承ListView实现的 我是在一个开源项目的基础上修改得来,原开源项目地址: https://github.com/fjtianxia/qianxudetianxia
那么就自己import并add那个appcompat_v7(如果你的项目目录下有这个工程的话就添加你自己的)就正常了,其实Demo报错并不影响,关键是demo里的jar包才是可拖拽控件,你可以自己新建项目仿照demo的代码实现效果。...
在本案例中,我们将深入探讨如何在Android中实现ListView的行拖拽功能,以及如何实现在多级列表间的行拖拽。 首先,要实现ListView的行拖拽,我们需要使用适配器(Adapter)来管理和更新ListView的数据。适配器将...
拖动ListView的子项(Item)并实现删除功能是一项常见的需求,特别是在构建具有交互性较强的界面时。本篇将详细介绍如何在Android中实现在ListView中拖动并删除Item。 首先,我们需要创建一个自定义的ListView,这...
在Android开发中,ListView是一种常用的组件,用于展示可滚动的列表数据。在许多应用中,如QQ消息列表,用户可以通过拖动列表项来实现排序或删除功能,这大大提升了用户体验。"实现可以拖动的listview"就是这样一个...
本篇文章将深入探讨如何在Android中实现ListView的拖拽排序和删除功能。 首先,我们要创建一个可拖动的ListView。这需要我们自定义一个Adapter,例如继承自BaseAdapter,用于填充ListView的数据。在Adapter中,我们...
综上所述,创建一个可横向拖动的ListView需要对Android的基础知识有深入理解,包括自定义视图、事件处理、布局管理以及性能优化等。通过自定义控件或使用第三方库,我们可以实现更加丰富的交互效果,提升应用的用户...
本篇文章将深入探讨如何在Android ListView中实现拖拽功能,并基于提供的"Android listview 拖拽实现源码"进行解析。 首先,要实现ListView的拖拽功能,我们需要自定义一个适配器(Adapter),这个适配器需要继承自...
总的来说,实现一个可拖拽的listview涉及了Android UI组件的编程、触摸事件处理、数据结构操作以及动画效果的添加。熟练掌握这些知识点,不仅能够提升应用的用户体验,也为开发者提供了更多创新设计的可能性。
本文将深入探讨如何在Android中实现ListView和GridView的拖拽移位功能,这在构建可交互的应用界面时非常有用,比如在音乐播放器、文件管理器等场景。 首先,我们需要了解ListView和GridView的基本用法。ListView...
Android 可拖拽排序的ListView
在“Android应用源码ListView 中的item随意拖动.zip”这个压缩包中,包含的源码示例是关于如何实现ListView的item(列表项)的自由拖动功能。这种功能常用于创建具有高度交互性的应用,如待办事项列表、音乐播放器或...
本篇将详细介绍如何在Android中实现一个可拖动的ListView,以及如何实现拖动分组管理。 首先,我们要了解Android中的Drag and Drop API,这是实现拖动功能的基础。Android SDK提供了一套完整的Drag and Drop API,...
在Android开发中,"Android launcher拖动效果"和"listview下拉加载"是两个重要的功能模块,它们分别涉及到用户界面交互和数据加载优化。让我们深入探讨这些知识点。 首先,Android launcher是用户启动应用程序的主...
为了实现这一功能,我们需要自定义一个可拖拽的ListView,使用户可以直观地通过手势调整列表中各个条目的顺序。这个"可拖拽listview,可改变item位置"的功能,正是我们要讨论的知识点。 首先,我们需要创建一个...