拖拽GridView

http://www.cnblogs.com/qianxudetianxia/archive/2011/06/20/2084886.html

 

 

根据前面文章中ListView拖拽的实现原理,我们也是很容易实现推拽GridView的,下面我就以相同步骤实现基本的GridView拖拽效果。
     因为GridView不用做分组处理,代码处理起来更简洁,而且原理前面已经讲解清楚了,代码中只是简单的过下,必要的地方简单的注释一下。
 1.主界面DragGridActivity.

01public class DragGridActivity extends Activity {
02     
03    private static List<String> list = null;
04    //自定义适配器
05    private DragGridAdapter adapter = null;
06     
07    @Override
08    public void onCreate(Bundle savedInstanceState) {
09        super.onCreate(savedInstanceState);
10        setContentView(R.layout.drag_grid_activity);
11         
12        initData();
13         
14        //后面用到的自定义GridView
15        DragGridView dragGridView = (DragGridView)findViewById(R.id.drag_grid);
16        adapter = new DragGridAdapter(this, list);
17        dragGridView.setAdapter(adapter);
18    }
19     
20    public void initData(){
21        //数据结果
22        list = new ArrayList<String>();
23         
24        for(int i=0; i<12; i++){
25            list.add("grid_"+i%12);
26        }
27    }
28}

2.主界面UI布局drag_grid_activity.xml.

01<?xml version="1.0" encoding="utf-8"?>
02<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="vertical"
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent"
06    android:background="#ffffff"
07    android:padding="10dip"
08    >
09    <com.fengjian.test.DragGridView
10        android:id="@+id/drag_grid"
11        android:layout_width="fill_parent"
12        android:layout_height="wrap_content"
13        android:cacheColorHint="#00000000"
14        android:numColumns="3"
15        android:stretchMode="columnWidth"
16        android:verticalSpacing="5dip"
17        android:horizontalSpacing="20dip"
18        android:background="#ffffff"/>
19</LinearLayout>

3.列表项布局drag_grid_item.xml.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="5dip"
    android:paddingRight="5dip">
    <ImageView android:id="@+id/drag_grid_item_image"
       android:src="@drawable/grid_icon"
       android:layout_margin="5dip"
       android:layout_alignParentTop="true"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"/>
    <ImageView android:id="@+id/drag_grid_item_drag"
       android:src="@drawable/grid_drag"
       android:layout_alignParentTop="true"
       android:layout_alignParentRight="true"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
</RelativeLayout>

4.自定义适配器DragGridAdapter,继承ArrayAdapter<String>.

01public static class DragGridAdapter extends ArrayAdapter<String>{
02 
03        public DragGridAdapter(Context context, List<String> objects) {
04            super(context, 0, objects);
05        }
06        public List<String> getList(){
07            return list;
08        }
09 
10        @Override
11        public View getView(int position, View convertView, ViewGroup parent) {
12            View view = convertView;
13            if(view==null){
14                view = LayoutInflater.from(getContext()).inflate(R.layout.drag_grid_item,null);
15            }
16             
17            try {
18                //根据文件名获取资源文件夹中的图片资源
19                Field f= (Field)R.drawable.class.getDeclaredField(getItem(position));
20                int i=f.getInt(R.drawable.class);
21                ImageView imageview= (ImageView)view.findViewById(R.id.drag_grid_item_image);
22                imageview.setImageResource(i);
23            catch (SecurityException e) {
24                e.printStackTrace();
25            catch (NoSuchFieldException e) {
26                e.printStackTrace();
27            catch (IllegalArgumentException e) {
28                e.printStackTrace();
29            catch (IllegalAccessException e) {
30                e.printStackTrace();
31            }
32            return view;
33        }
34    }

5.自定义视图类DragGridView,继承GridView.

public class DragGridView extends GridView {
    //定义基本的成员变量
    private ImageView dragImageView;
    private int dragSrcPosition;
    private int dragPosition;
    //x,y坐标的计算
    private int dragPointX;
    private int dragPointY;
    private int dragOffsetX;
    private int dragOffsetY;
     
    private WindowManager windowManager;
    private WindowManager.LayoutParams windowParams;
     
    private int scaledTouchSlop;
    private int upScrollBounce;
    private int downScrollBounce;
     
    public DragGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}
6.  重写触控拦截事件方法onInterceptTouchEvent(). 
01@Override
02public boolean onInterceptTouchEvent(MotionEvent ev) {
03    if(ev.getAction()==MotionEvent.ACTION_DOWN){
04        int x = (int)ev.getX();
05        int y = (int)ev.getY();
06         
07        dragSrcPosition = dragPosition = pointToPosition(x, y);
08        if(dragPosition==AdapterView.INVALID_POSITION){
09            return super.onInterceptTouchEvent(ev);
10        }
11 
12        ViewGroup itemView = (ViewGroup) getChildAt(dragPosition-getFirstVisiblePosition());
13        dragPointX = x - itemView.getLeft();
14        dragPointY = y - itemView.getTop();
15        dragOffsetX = (int) (ev.getRawX() - x);
16        dragOffsetY = (int) (ev.getRawY() - y);
17         
18        View dragger = itemView.findViewById(R.id.drag_grid_item_drag);
19        //如果选中拖动图标
20        if(dragger!=null&&dragPointX>dragger.getLeft()&&dragPointX<dragger.getRight()&&dragPointY>dragger.getTop()&&dragPointY<dragger.getBottom()+20){
21 
22            upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/4);
23            downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*3/4);
24             
25            itemView.setDrawingCacheEnabled(true);
26            Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
27            startDrag(bm, x, y);
28        }
29        return false;
30     }
31     return super.onInterceptTouchEvent(ev);
32}
     startDrag和stopDrag方法如下:
01public void startDrag(Bitmap bm, int x, int y){
02    stopDrag();
03     
04    windowParams = new WindowManager.LayoutParams();
05    windowParams.gravity = Gravity.TOP|Gravity.LEFT;
06    windowParams.x = x - dragPointX + dragOffsetX;
07    windowParams.y = y - dragPointY + dragOffsetY;
08    windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
09    windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
10    windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
12                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
13                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
14    windowParams.format = PixelFormat.TRANSLUCENT;
15    windowParams.windowAnimations = 0;
16 
17    ImageView imageView = new ImageView(getContext());
18    imageView.setImageBitmap(bm);
19    windowManager = (WindowManager)getContext().getSystemService("window");
20    windowManager.addView(imageView, windowParams);
21    dragImageView = imageView;
22}
23 
24public void onDrag(int x, int y){
25    if(dragImageView!=null){
26        windowParams.alpha = 0.8f;
27        windowParams.x = x - dragPointX + dragOffsetX;
28        windowParams.y = y - dragPointY + dragOffsetY;
29        windowManager.updateViewLayout(dragImageView, windowParams);
30    }
31 
32    int tempPosition = pointToPosition(x, y);
33    if(tempPosition!=INVALID_POSITION){
34        dragPosition = tempPosition;
35    }
36     
37    //滚动
38    if(y<upScrollBounce||y>downScrollBounce){
39        //使用setSelection来实现滚动
40        setSelection(dragPosition);
41    }       
42}

7.重写onTouchEvent()方法. 

01@Override
02public boolean onTouchEvent(MotionEvent ev) {
03    if(dragImageView!=null&&dragPosition!=INVALID_POSITION){
04        int action = ev.getAction();
05        switch(action){
06            case MotionEvent.ACTION_UP:
07                int upX = (int)ev.getX();
08                int upY = (int)ev.getY();
09                stopDrag();
10                onDrop(upX,upY);
11                break;
12            case MotionEvent.ACTION_MOVE:
13                int moveX = (int)ev.getX();
14                int moveY = (int)ev.getY();
15                onDrag(moveX,moveY);
16                break;
17            default:break;
18        }
19        return true;
20    }
21    return super.onTouchEvent(ev);
22}
其中onDrag方法如下:
01public void onDrag(int x, int y){
02    if(dragImageView!=null){
03        windowParams.alpha = 0.8f;
04        windowParams.x = x - dragPointX + dragOffsetX;
05        windowParams.y = y - dragPointY + dragOffsetY;
06        windowManager.updateViewLayout(dragImageView, windowParams);
07    }
08 
09    int tempPosition = pointToPosition(x, y);
10    if(tempPosition!=INVALID_POSITION){
11        dragPosition = tempPosition;
12    }
13     
14    //滚动
15    if(y<upScrollBounce||y>downScrollBounce){
16        //使用setSelection来实现滚动
17        setSelection(dragPosition);
18    }       
19}
8.放下影像,数据更新。
 在onDrop方法中实现:
01public void onDrop(int x, int y){
02         
03        //为了避免滑动到分割线的时候,返回-1的问题
04        int tempPosition = pointToPosition(x, y);
05        if(tempPosition!=INVALID_POSITION){
06            dragPosition = tempPosition;
07        }
08         
09        //超出边界处理
10        if(y<getChildAt(0).getTop()){
11            //超出上边界
12            dragPosition = 0;
13        }else if(y>getChildAt(getChildCount()-1).getBottom()||(y>getChildAt(getChildCount()-1).getTop()&&x>getChildAt(getChildCount()-1).getRight())){
14            //超出下边界
15            dragPosition = getAdapter().getCount()-1;
16        }
17         
18        //数据交换
19        if(dragPosition!=dragSrcPosition&&dragPosition>-1&&dragPosition<getAdapter().getCount()){
20            DragGridAdapter adapter = (DragGridAdapter)getAdapter();
21            String dragItem = adapter.getItem(dragSrcPosition);
22            adapter.remove(dragItem);
23            adapter.insert(dragItem, dragPosition);
24            Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show();
25        }
26         
27    }

10.最终效果图如下:

 

图1

 

图2

      这篇文章也算是前面文章的一个补充和扩展。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值