自定义GridView并且实现拖拽(附源码)

写在前面的话

本篇blog实现了GridView的拖拽功能。方法和上一篇自定义ListView实现拖拽ListItem项交换位置一个原理。只是在交换位置上记录了X轴的相关坐标,计算了X轴的相关变量。

实现效果图如下

 

说明:

本篇给出实现代码,但是不做任何说明。如需了解请看上一篇blog:自定义ListView实现拖拽ListItem项交换位置

文件代码:

1、MainActivity.java

复制代码 代码如下:

package com.jay.draggridview;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.List;

import android.os.Bundle;

import android.app.Activity;

import android.content.Context;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.Menu;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.ImageView;

public class MainActivity extends Activity {

private static List<String> list = null;

//自定义适配器

private DragGridAdapter adapter = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//初始化数据

initData();

//后面用到的自定义GridView

DragGridView dragGridView = (DragGridView)findViewById(R.id.drag_grid);

adapter = new DragGridAdapter(this, list);

dragGridView.setAdapter(adapter);

}

public void initData(){

list = new ArrayList<String>();

for(int i= 0 ; i < 12 ; i++){

list.add("grid_"+i%12);

}

}

public static class DragGridAdapter extends ArrayAdapter<String>{

public DragGridAdapter(Context context, List<String> objects) {

super(context, 0, objects);

}

public List<String> getList(){

return list;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

View view = convertView;

if(view==null){

view = LayoutInflater.from(getContext()).inflate(R.layout.drag_grid_item, null);

}

try {

Log.v("item", "------"+getItem(position));

//根据文件名获取资源文件夹中的图片资源

Field f= (Field)R.drawable.class.getDeclaredField(getItem(position));

int i=f.getInt(R.drawable.class);

ImageView imageview= (ImageView)view.findViewById(R.id.drag_grid_item_image);

imageview.setImageResource(i);

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return view;

}

}

}

2、DragGridView.java

复制代码 代码如下:

package com.jay.draggridview;

import com.jay.draggridview.MainActivity.DragGridAdapter;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.PixelFormat;

import android.util.AttributeSet;

import android.view.Gravity;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.AdapterView;

import android.widget.GridView;

import android.widget.ImageView;

import android.widget.Toast;

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);

}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

if(ev.getAction()==MotionEvent.ACTION_DOWN){

int x = (int)ev.getX();

int y = (int)ev.getY();

dragSrcPosition = dragPosition = pointToPosition(x, y);

if(dragPosition==AdapterView.INVALID_POSITION){

return super.onInterceptTouchEvent(ev);

}

ViewGroup itemView = (ViewGroup) getChildAt(dragPosition-getFirstVisiblePosition());

dragPointX = x - itemView.getLeft();

dragPointY = y - itemView.getTop();

dragOffsetX = (int) (ev.getRawX() - x);

dragOffsetY = (int) (ev.getRawY() - y);

View dragger = itemView.findViewById(R.id.drag_grid_item_drag);

//如果选中拖动图标

if(dragger!=null&&dragPointX>dragger.getLeft()&&dragPointX<dragger.getRight()&&dragPointY>dragger.getTop()&&dragPointY<dragger.getBottom()+20){

upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/4);

downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*3/4);

itemView.setDrawingCacheEnabled(true);

Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());

startDrag(bm, x, y);

}

return false;

}

return super.onInterceptTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

if(dragImageView!=null&&dragPosition!=INVALID_POSITION){

int action = ev.getAction();

switch(action){

case MotionEvent.ACTION_UP:

int upX = (int)ev.getX();

int upY = (int)ev.getY();

stopDrag();

onDrop(upX,upY);

break;

case MotionEvent.ACTION_MOVE:

int moveX = (int)ev.getX();

int moveY = (int)ev.getY();

onDrag(moveX,moveY);

break;

default:break;

}

return true;

}

return super.onTouchEvent(ev);

}

public void startDrag(Bitmap bm, int x, int y){

stopDrag();

windowParams = new WindowManager.LayoutParams();

windowParams.gravity = Gravity.TOP|Gravity.LEFT;

windowParams.x = x - dragPointX + dragOffsetX;

windowParams.y = y - dragPointY + dragOffsetY;

windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;

windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE

| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON

| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

windowParams.format = PixelFormat.TRANSLUCENT;

windowParams.windowAnimations = 0;

ImageView imageView = new ImageView(getContext());

imageView.setImageBitmap(bm);

windowManager = (WindowManager)getContext().getSystemService("window");

windowManager.addView(imageView, windowParams);

dragImageView = imageView;

}

public void onDrag(int x, int y){

if(dragImageView!=null){

windowParams.alpha = 0.8f;

windowParams.x = x - dragPointX + dragOffsetX;

windowParams.y = y - dragPointY + dragOffsetY;

windowManager.updateViewLayout(dragImageView, windowParams);

}

int tempPosition = pointToPosition(x, y);

if(tempPosition!=INVALID_POSITION){

dragPosition = tempPosition;

}

//滚动

if(y<upScrollBounce||y>downScrollBounce){

//使用setSelection来实现滚动

setSelection(dragPosition);

}

}

public void onDrop(int x, int y){

//为了避免滑动到分割线的时候,返回-1的问题

int tempPosition = pointToPosition(x, y);

if(tempPosition!=INVALID_POSITION){

dragPosition = tempPosition;

}

//超出边界处理

if(y<getChildAt(0).getTop()){

//超出上边界

dragPosition = 0;

}else if(y>getChildAt(getChildCount()-1).getBottom()||(y>getChildAt(getChildCount()-1).getTop()&&x>getChildAt(getChildCount()-1).getRight())){

//超出下边界

dragPosition = getAdapter().getCount()-1;

}

//数据交换

if(dragPosition!=dragSrcPosition&&dragPosition>-1&&dragPosition<getAdapter().getCount()){

DragGridAdapter adapter = (DragGridAdapter)getAdapter();

String dragItem = adapter.getItem(dragSrcPosition);

adapter.remove(dragItem);

adapter.insert(dragItem, dragPosition);

Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show();

}

}

/***

* 停止拖动,去掉拖动时候的影像

*/

public void stopDrag(){

if(dragImageView != null){

windowManager.removeView(dragImageView);

dragImageView = null;

}

}

}

3、activity_main.xml

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ffffff"

android:padding="10dip"

>

<com.jay.draggridview.DragGridView

android:id="@+id/drag_grid"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:cacheColorHint="#00000000"

android:numColumns="3"

android:stretchMode="columnWidth"

android:verticalSpacing="5dip"

android:horizontalSpacing="20dip"

android:background="#ffffff"/>

</LinearLayout>

4、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:layout_margin="5dip"

android:layout_alignParentTop="true"

android:layout_width="fill_parent"

android:layout_height="60dip"/>

<ImageView android:id="@+id/drag_grid_item_drag"

android:src="@drawable/p32_24_1"

android:layout_alignParentTop="true"

android:layout_alignParentRight="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

</RelativeLayout>

源码下载

时间: 2024-07-29 05:02:55

自定义GridView并且实现拖拽(附源码)的相关文章

自定义GridView并且实现拖拽(附源码)_Android

写在前面的话 本篇blog实现了GridView的拖拽功能.方法和上一篇自定义ListView实现拖拽ListItem项交换位置一个原理.只是在交换位置上记录了X轴的相关坐标,计算了X轴的相关变量. 实现效果图如下  说明: 本篇给出实现代码,但是不做任何说明.如需了解请看上一篇blog:自定义ListView实现拖拽ListItem项交换位置 文件代码: 1.MainActivity.java 复制代码 代码如下: package com.jay.draggridview; import ja

FCKEditor 自定义用户目录的修改步骤 (附源码)_网页编辑器

由于我这边的网络原因,没用从FCK的官网下载到源码... 这套源码是FCK2.2版反编译出来的 源码:点此下载 源码中主要修改的地方做了注释 大致的修改如下 : 获取用户目录的源码: FileWorkerBase.cs 这里主要是做了一些注释 在程序中可以直接在用户登录的时候指定 这个方案只是方便多用户使用的时候为用户指定不同的文件目录 Session["FCKeditor:UserFilesPath"]="用户文件相对目录"; 复制代码 代码如下: /// <

jQuery拖拽排序插件制作拖拽排序效果(附源码下载)_jquery

使用jquery拖拽排序插件制作拖拽排序效果是一款非常实用的鼠标拖拽布局插件.效果图如下: 效果演示         源码下载 html代码: <h1>水平拖拽</h1> <div class="demo"> <div class="item item1"><span>1</span></div> <div class="item item2"><

jQuery 自定义下拉框(DropDown)附源码下载_jquery

先给大家展示下效果图,喜欢的朋友可以下载源码哦 效果演示   源码下载 <section class="main"> <div class="wrapper-demo"> <div id="dd" class="wrapper-dropdown-1" tabindex="1"> <span>手册网</span> <ul class="

自定义Android六边形进度条(附源码)_Android

本文实例讲述了Android自定义圆形进度条,分享给大家供大家参考.具体如下: 大家也可以参考这两篇文章进行学习: <自定义Android圆形进度条(附源码)>   <Android带进度的圆形进度条> 运行效果截图如下: 主要代码: package com.sxc.hexagonprogress; import java.util.Random; import android.content.Context; import android.content.res.ColorSta

自定义Android六边形进度条(附源码)

本文实例讲述了Android自定义圆形进度条,分享给大家供大家参考.具体如下: 大家也可以参考这两篇文章进行学习: <自定义Android圆形进度条(附源码)>   <Android带进度的圆形进度条> 运行效果截图如下: 主要代码: package com.sxc.hexagonprogress; import java.util.Random; import android.content.Context; import android.content.res.ColorSta

你可能用到的百度地图效果(附源码)

原文:你可能用到的百度地图效果(附源码)      这段时间需要实现百度地图的一些展示效果,虽然最终效果做出来了,可是这中间也走了很多的弯路,希望有用到的可以直接拿来用,少走一些弯路.百度地图为开发者提供了一系列的接口,点百度接口去百度接口.本文主要用到了以下几个效果: 1.热力图显示 2.自定义图标的聚合显示 3.云麻点显示       热力图显示       百度地图热力图是通过设置热力图半径.颜色.透明度等参数直观展示数据分布情况,而我这段时间所做的,就是通过一段时间内的订单数量,再结合经

wpf 模拟3D效果(和手机浏览图片效果相似)(附源码)

原文 wpf 模拟3D效果(和手机浏览图片效果相似)(附源码) pf的3D是一个很有意思的东西,类似于ps的效果,类似于电影动画的效果,因为动画的效果,(对于3D基础的摄像机,光源,之类不介绍,对于依赖属性也不介绍.),个人认为,依赖属性这个东西,有百分之五十是为了3D而存在.(自己写的类似于demo的东西)先上图,无图无真相这是demo的整个效果图,可以用鼠标移动,触摸屏也可以手指滑动,图片会移动,然后移动结束,会有一个回弹的判断. <Window x:Class="_3Dshow.Wi

聊天系统Demo,增加文件传送功能(附源码)-- ESFramework 4.0 快速上手(14)

      本文我们将介绍在ESFramework 4.0 快速上手(08) -- 入门Demo,一个简单的IM系统(附源码)的基础上,增加文件传送的功能.如果不了解如何使用ESFramework提供的文件传送功能,可以先看看ESFramework 4.0 快速上手(13) -- 文件传送,如此简单一文的详细介绍.       本Demo可演示以下与文件传送相关的特性: (1)发送方请求发送文件,接收方可以同意或拒绝接收文件. (2)文件传送的过程中,收发的任何一方都可以通过事件了解文件传送的实