zoukankan      html  css  js  c++  java
  • Android学习系列(12)--App列表之拖拽GridView

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

    1. public class DragGridActivity extends Activity {
    2.     
    3.     private static List<String> list = null;
    4.     //自定义适配器
    5.     private DragGridAdapter adapter = null;
    6.     
    7.     @Override
    8.     public void onCreate(Bundle savedInstanceState) {
    9.         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.

    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.             
    15.             try {
    16.                 //根据文件名获取资源文件夹中的图片资源
    17.                 Field f= (Field)R.drawable.class.getDeclaredField(getItem(position));
    18.                 int i=f.getInt(R.drawable.class);
    19.                 ImageView imageview= (ImageView)view.findViewById(R.id.drag_grid_item_image);
    20.                 imageview.setImageResource(i);
    21.             } catch (SecurityException e) {
    22.                 e.printStackTrace();
    23.             } catch (NoSuchFieldException e) {
    24.                 e.printStackTrace();
    25.             } catch (IllegalArgumentException e) {
    26.                 e.printStackTrace();
    27.             } catch (IllegalAccessException e) {
    28.                 e.printStackTrace();
    29.             }
    30.             return view;
    31.         }
    32.     }
    复制代码

    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.     
    12.     private WindowManager windowManager;
    13.     private WindowManager.LayoutParams windowParams;
    14.     
    15.     private int scaledTouchSlop;
    16.     private int upScrollBounce;
    17.     private int downScrollBounce;
    18.     
    19.     public DragGridView(Context context, AttributeSet attrs) {
    20.         super(context, attrs);
    21.     }
    22. }
    复制代码

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

      startDrag和stopDrag方法如下:

    1. public void startDrag(Bitmap bm, int x, int y){
    2.     stopDrag();
    3.     
    4.     windowParams = new WindowManager.LayoutParams();
    5.     windowParams.gravity = Gravity.TOP|Gravity.LEFT;
    6.     windowParams.x = x - dragPointX + dragOffsetX;
    7.     windowParams.y = y - dragPointY + dragOffsetY;
    8.     windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
    9.     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.     ImageView imageView = new ImageView(getContext());
    17.     imageView.setImageBitmap(bm);
    18.     windowManager = (WindowManager)getContext().getSystemService("window");
    19.     windowManager.addView(imageView, windowParams);
    20.     dragImageView = imageView;
    21. }
    22. public void onDrag(int x, int y){
    23.     if(dragImageView!=null){
    24.         windowParams.alpha = 0.8f;
    25.         windowParams.x = x - dragPointX + dragOffsetX;
    26.         windowParams.y = y - dragPointY + dragOffsetY;
    27.         windowManager.updateViewLayout(dragImageView, windowParams);
    28.     }
    29.     int tempPosition = pointToPosition(x, y);
    30.     if(tempPosition!=INVALID_POSITION){
    31.         dragPosition = tempPosition;
    32.     }
    33.     
    34.     //滚动
    35.     if(y<upScrollBounce||y>downScrollBounce){
    36.         //使用setSelection来实现滚动
    37.         setSelection(dragPosition);
    38.     }        
    39. }
    复制代码

    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.     //滚动
    14.     if(y<upScrollBounce||y>downScrollBounce){
    15.         //使用setSelection来实现滚动
    16.         setSelection(dragPosition);
    17.     }        
    18. }
    复制代码

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

    1. public void onDrop(int x, int y){
    2.         
    3.         //为了避免滑动到分割线的时候,返回-1的问题
    4.         int tempPosition = pointToPosition(x, y);
    5.         if(tempPosition!=INVALID_POSITION){
    6.             dragPosition = tempPosition;
    7.         }
    8.         
    9.         //超出边界处理
    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.     }
    复制代码


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

  • 相关阅读:
    【转】iPython入门技巧
    Python——IPython和NumPy
    Python——类与对象,异常处理
    Python——函数,模块,简单文件读写
    给对象的key 设置成变量
    antd 表单validateFields validateFieldsAndScroll方法不执行
    css 设置禁用
    where与having区别
    重温robotframework--day1
    Linux下查看文件内容的命令
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/3605547.html
Copyright © 2011-2022 走看看