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

  1. public class DragGridActivity extends Activity {
  2. private static List<String> list = null;
  3. //自定义适配器
  4. private DragGridAdapter adapter = null;
  5. @Override
  6. public void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.drag_grid_activity);
  9. initData();
  10. //后面用到的自定义GridView
  11. DragGridView dragGridView = (DragGridView)findViewById(R.id.drag_grid);
  12. adapter = new DragGridAdapter(this, list);
  13. dragGridView.setAdapter(adapter);
  14. }
  15. public void initData(){
  16. //数据结果
  17. list = new ArrayList<String>();
  18. for(int i=0; i<12; i++){
  19. list.add("grid_"+i%12);
  20. }
  21. }
  22. }

复制代码

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="#ffffff"
  7. android:padding="10dip"
  8. >
  9. <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.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="wrap_content"
  5. android:paddingLeft="5dip"
  6. android:paddingRight="5dip">
  7. <ImageView android:id="@+id/drag_grid_item_image"
  8. android:src="@drawable/grid_icon"
  9. android:layout_margin="5dip"
  10. android:layout_alignParentTop="true"
  11. android:layout_width="fill_parent"
  12. android:layout_height="wrap_content"/>
  13. <ImageView android:id="@+id/drag_grid_item_drag"
  14. android:src="@drawable/grid_drag"
  15. android:layout_alignParentTop="true"
  16. android:layout_alignParentRight="true"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"/>
  19. </RelativeLayout>

复制代码

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

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

复制代码

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

  1. public class DragGridView extends GridView {
  2. //定义基本的成员变量
  3. private ImageView dragImageView;
  4. private int dragSrcPosition;
  5. private int dragPosition;
  6. //x,y坐标的计算
  7. private int dragPointX;
  8. private int dragPointY;
  9. private int dragOffsetX;
  10. private int dragOffsetY;
  11. private WindowManager windowManager;
  12. private WindowManager.LayoutParams windowParams;
  13. private int scaledTouchSlop;
  14. private int upScrollBounce;
  15. private int downScrollBounce;
  16. public DragGridView(Context context, AttributeSet attrs) {
  17. super(context, attrs);
  18. }
  19. }

复制代码

6. 重写触控拦截事件方法onInterceptTouchEvent().

  1. @Override
  2. public boolean onInterceptTouchEvent(MotionEvent ev) {
  3. if(ev.getAction()==MotionEvent.ACTION_DOWN){
  4. int x = (int)ev.getX();
  5. int y = (int)ev.getY();
  6. dragSrcPosition = dragPosition = pointToPosition(x, y);
  7. if(dragPosition==AdapterView.INVALID_POSITION){
  8. return super.onInterceptTouchEvent(ev);
  9. }
  10. ViewGroup itemView = (ViewGroup) getChildAt(dragPosition-getFirstVisiblePosition());
  11. dragPointX = x - itemView.getLeft();
  12. dragPointY = y - itemView.getTop();
  13. dragOffsetX = (int) (ev.getRawX() - x);
  14. dragOffsetY = (int) (ev.getRawY() - y);
  15. View dragger = itemView.findViewById(R.id.drag_grid_item_drag);
  16. //如果选中拖动图标
  17. if(dragger!=null&&dragPointX>dragger.getLeft()&&dragPointX<dragger.getRight()&&dragPointY>dragger.getTop()&&dragPointY<dragger.getBottom()+20){
  18. upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/4);
  19. downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*3/4);
  20. itemView.setDrawingCacheEnabled(true);
  21. Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
  22. startDrag(bm, x, y);
  23. }
  24. return false;
  25. }
  26. return super.onInterceptTouchEvent(ev);
  27. }

复制代码

startDrag和stopDrag方法如下:

  1. public void startDrag(Bitmap bm, int x, int y){
  2. stopDrag();
  3. windowParams = new WindowManager.LayoutParams();
  4. windowParams.gravity = Gravity.TOP|Gravity.LEFT;
  5. windowParams.x = x - dragPointX + dragOffsetX;
  6. windowParams.y = y - dragPointY + dragOffsetY;
  7. windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  8. windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  9. windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
  10. | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
  11. | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
  12. | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
  13. windowParams.format = PixelFormat.TRANSLUCENT;
  14. windowParams.windowAnimations = 0;
  15. ImageView imageView = new ImageView(getContext());
  16. imageView.setImageBitmap(bm);
  17. windowManager = (WindowManager)getContext().getSystemService("window");
  18. windowManager.addView(imageView, windowParams);
  19. dragImageView = imageView;
  20. }
  21. public void onDrag(int x, int y){
  22. if(dragImageView!=null){
  23. windowParams.alpha = 0.8f;
  24. windowParams.x = x - dragPointX + dragOffsetX;
  25. windowParams.y = y - dragPointY + dragOffsetY;
  26. windowManager.updateViewLayout(dragImageView, windowParams);
  27. }
  28. int tempPosition = pointToPosition(x, y);
  29. if(tempPosition!=INVALID_POSITION){
  30. dragPosition = tempPosition;
  31. }
  32. //滚动
  33. if(y<upScrollBounce||y>downScrollBounce){
  34. //使用setSelection来实现滚动
  35. setSelection(dragPosition);
  36. }
  37. }

复制代码

7.重写onTouchEvent()方法. 

  1. @Override
  2. public boolean onTouchEvent(MotionEvent ev) {
  3. if(dragImageView!=null&&dragPosition!=INVALID_POSITION){
  4. int action = ev.getAction();
  5. switch(action){
  6. case MotionEvent.ACTION_UP:
  7. int upX = (int)ev.getX();
  8. int upY = (int)ev.getY();
  9. 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方法如下:

  1. public void onDrag(int x, int y){
  2. if(dragImageView!=null){
  3. windowParams.alpha = 0.8f;
  4. windowParams.x = x - dragPointX + dragOffsetX;
  5. windowParams.y = y - dragPointY + dragOffsetY;
  6. windowManager.updateViewLayout(dragImageView, windowParams);
  7. }
  8. int tempPosition = pointToPosition(x, y);
  9. if(tempPosition!=INVALID_POSITION){
  10. dragPosition = tempPosition;
  11. }
  12. //滚动
  13. if(y<upScrollBounce||y>downScrollBounce){
  14. //使用setSelection来实现滚动
  15. setSelection(dragPosition);
  16. }
  17. }

复制代码

8.放下影像,数据更新。
在onDrop方法中实现:

  1. public void onDrop(int x, int y){
  2. //为了避免滑动到分割线的时候,返回-1的问题
  3. int tempPosition = pointToPosition(x, y);
  4. if(tempPosition!=INVALID_POSITION){
  5. dragPosition = tempPosition;
  6. }
  7. //超出边界处理
  8. if(y<getChildAt(0).getTop()){
  9. //超出上边界
  10. dragPosition = 0;
  11. }else if(y>getChildAt(getChildCount()-1).getBottom()||(y>getChildAt(getChildCount()-1).getTop()&&x>getChildAt(getChildCount()-1).getRight())){
  12. //超出下边界
  13. dragPosition = getAdapter().getCount()-1;
  14. }
  15. //数据交换
  16. if(dragPosition!=dragSrcPosition&&dragPosition>-1&&dragPosition<getAdapter().getCount()){
  17. DragGridAdapter adapter = (DragGridAdapter)getAdapter();
  18. String dragItem = adapter.getItem(dragSrcPosition);
  19. adapter.remove(dragItem);
  20. adapter.insert(dragItem, dragPosition);
  21. Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show();
  22. }
  23. }

复制代码


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

Android学习系列(12)--App列表之拖拽GridView的更多相关文章

  1. Android学习系列(11)--App列表之拖拽ListView(下)

    接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法.     在这个方法中我们主要是处理 ...

  2. Android学习系列(10)--App列表之拖拽ListView(上)

     研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨.      鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...

  3. Android学习系列(15)--App列表之游标ListView(索引ListView)

    游标ListView,提供索引标签,使用户能够快速定位列表项.      也可以叫索引ListView,有的人称也为Tweaked ListView,可能更形象些吧.      一看图啥都懂了: 1. ...

  4. Android学习系列(17)--App列表之圆角ListView(续)

    http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html   本来这篇文章想并到上篇Android学习系列(16)- ...

  5. Android学习系列(16)--App列表之圆角ListView

    有些东西看多了,就厌烦了:extjs对我这种感觉最为强烈.甚至,有时觉得设计之殇是审美疲劳.直角看多了,就想看看圆角,不知何时,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,iphone中 ...

  6. Android学习系列(9)--App列表之分组ListView

    吸引用户的眼球,是我们至死不渝的追求:      第一时间呈现最有价值的信息,简明大方,告诉客户,你的选择是多么的明智,这正是你寻觅已久的东西.       分组的应用场合还是很多的,有数据集合的地方 ...

  7. Android学习系列--App列表之拖拽ListView(下)

    接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法.     在这个方法中我们主要是处理 ...

  8. Android学习系列--App列表之拖拽ListView(上)

    研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨.      鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. 一 ...

  9. Android学习系列(7)--App轮询服务器消息

    这篇文章是android开发人员的必备知识. 1.轮询服务器     一般的应用,定时通知消息可以采用轮询的方法从服务器拿取消息,当然实时消息通知的话,建议采用推送服务.    其中需要注意轮询的频率 ...

随机推荐

  1. mac下使用brew安装java等应用

    可以使用brew安装很多应用,比如java,idea,iterms,sublime brew tap caskroom/versions 将会安装新的brew仓库源brew cask install ...

  2. Linux中Shell的执行流程

    Shell执行流程 1.Printthe info of reminding 打印提示信息 2.Waitinguser for input(wait) 等待用户输入 3.Acceptthe comma ...

  3. C++代码文件名标准化处理工具

    工具功能:批量处理C++代码文件,将C++代码文件名中大写字母改为下划线+小写字母. 为了方便代码在不同平台下的移植,代码文件命名规范为:不使用大写字母,单词之间用下划线间隔开.为此写了这个小工具,将 ...

  4. mysql搭建及数据迁移教程

    1.如果jumbo不存在,先安装jumbo 参考  http://hetu.baidu.com/api/tool/show?toolId=174: bash -c "$( curl  htt ...

  5. DIV-CSS布局中position属性详解

    本文向大家描述一下DIV CSS布局中的position属性的用法,position属性主要有四种属性值,任何元素的默认position的属性值均是static,静态.这节课主要讲讲relative( ...

  6. ADB用法

    作为android开发人员,adb是常用的工具之一.具体怎么使用了. 1. 安装完ADB后(ADB的安装请参考<Android开发平台搭建及配置.doc>),用电脑USB连接机器,然后使用 ...

  7. MySQL监控、性能分析——工具篇

    https://blog.csdn.net/leamonjxl/article/details/6431444 MySQL越来越被更多企业接受,随着企业发展,MySQL存储数据日益膨胀,MySQL的性 ...

  8. hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载

    本文档主要内容有: 1.hadoop 2.2.0 集群安装与部署 2.HBase 0.96 集群安装与部署 3.Zookeeper 3.4.5集群安装部署 备注:安装文档可能有所遗漏,后续将持续更新. ...

  9. struts2訪问servlet的API

    1.struts作为控制器,正常非常多时候要訪问到servlet的API.经常使用功能:   (1).获取请求參数,控制界面跳转   (2).把共享数据存储于request,session,servl ...

  10. C语言及程序设计[套餐]课程主页

    课程链接:http://edu.csdn.net/combo/detail/30,提供全部的视频和课件下载. 三部分的课程主页.提供了为每一课时配套的自測.演示样例下载,以及程序阅读.程序填空.实践项 ...