GridView拖动效果实现

  1. 1.    重新GridView控件

package com.whbs.drag.widget;

import com.whbs.drag.DragGridActivity.DragGridAdapter;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.PixelFormat;

import android.util.AttributeSet;

import android.util.Log;

import android.view.Gravity;

import android.view.MotionEvent;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.AdapterView;

import android.widget.GridView;

import android.widget.ImageView;

public class GragGridView extends GridView{

private static final String TAG = "GragGridView";

//定义基本的成员变量

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 GragGridView(Context context) {

super(context);

}

public GragGridView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

}

public GragGridView(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

}

//触控拦截事件

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

}

Log.i(TAG, "[onInterceptTouchEvent] dragSrcPosition:"+dragSrcPosition+",getFirstVisiblePosition():"+getFirstVisiblePosition());

//getFirstVisiblePosition()返回第一个dispaly在界面的view在adapter的位置  可能是0,也可能是4

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

//计算按下的坐标相对当前项的位置

dragPointX = x - itemView.getLeft();//在当前项的X位置

dragPointY = y - itemView.getTop();

//当前窗体和屏幕的距离

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

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

Log.i(TAG, "[onInterceptTouchEvent] [x:"+x+",y:"+y+"],[rawX:"+ev.getRawX()+",rawY:"+ev.getRawY()+"]");

Log.i(TAG, "[onInterceptTouchEvent] [dragPointX:"+dragPointX+",dragPointY:"+dragPointY+"],[dragOffsetX:"+dragOffsetX+",dragOffsetY:"+dragOffsetY+"]");

//

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

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

upScrollBounce = Math.min(y, getHeight()/4);//向上可以滚动的距离

downScrollBounce = Math.max(y, getHeight()*3/4);//向下可以滚动的距离

itemView.setDrawingCacheEnabled(true);

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

startDrag(bm,x,y);

}

return super.onInterceptTouchEvent(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;//计算当前项Left离窗体的距离

windowParams.y = y - dragPointY + dragOffsetY;//计算当前项Top离窗体的距离

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(getContext().WINDOW_SERVICE);

windowManager.addView(imageView, windowParams);

dragImageView = imageView;

}

//停止拖到

public void stopDrag(){

if(dragImageView != null){

windowManager.removeView(dragImageView);

dragImageView = null;

}

}

//拖动

public void onDrag(int x,int y){

if(dragImageView != null){

windowParams.alpha = 0.9f;

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

}

}

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

}

return true;

}

return super.onTouchEvent(ev);

}

//拖到落下

public void onDrop(int x,int y){

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 dragSrcItem = adapter.getItem(dragSrcPosition);

String dragTargetItem = adapter.getItem(dragPosition);

adapter.remove(dragSrcItem);

adapter.insert(dragSrcItem, dragPosition);

adapter.remove(dragTargetItem);

adapter.insert(dragTargetItem, dragSrcPosition);

System.out.println("srcPosition="+dragSrcPosition+"  dragPosition="+dragPosition);

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

}

}

}

 

  1. 2.    Activity调用实现

package com.whbs.drag;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.List;

import android.app.Activity;

import android.content.Context;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.view.Window;

import android.view.WindowManager;

import android.widget.ArrayAdapter;

import android.widget.ImageView;

import com.whbs.drag.widget.GragGridView;

public class DragGridActivity extends Activity {

private static List<String> list = null;

//  private static List<Integer> res = null;

//自定义适配器

private DragGridAdapter adapter = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.drag_grid_activity);

initData();

//

GragGridView dragView = (GragGridView)findViewById(R.id.drag_grid);

//        System.out.println("dragView"+dragView);

adapter = new DragGridAdapter(this, list);

dragView.setAdapter(adapter);

}

public void initData(){

list = new ArrayList<String>();

//     res = new ArrayList<Integer>();

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

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

//res.add(0x7f020000+i);

}

}

public  class DragGridAdapter extends ArrayAdapter<String>{

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

super(context, 0, objects);

}

@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 {

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

Field f = 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) {

// TODO Auto-generated catch block

e.printStackTrace();

//         }

} catch (NoSuchFieldException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalAccessException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return view;

}

}

}

  1. 3.    Xml文件
    1. 1.    drag_grid_activity.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="@drawable/bg"

android:padding="10dip"

>

<com.whbs.drag.widget.GragGridView

android:id="@+id/drag_grid"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:cacheColorHint="#4682B4"

android:numColumns="4"

android:stretchMode="columnWidth"

android:verticalSpacing="5dip"

android:horizontalSpacing="5dip">

</com.whbs.drag.widget.GragGridView>

</LinearLayout>

 

  1. 2.    drag_grid_item.xml

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

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

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:paddingLeft="5dip"

android:paddingRight="5dip"

>

<ImageView

android:id="@+id/drag_grid_item_image"

android:padding="5dip"

android:background="@drawable/grid_bg"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

/>

</RelativeLayout>

 

  1. 4.    AndroidManifest.xml

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

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

package="com.whbs.drag"

android:versionCode="1"

android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name="DragGridActivity"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

</manifest>

GridView拖动效果实现的更多相关文章

  1. vc++ mfc中拖动效果的实现 借助于CImageList

    拖动是界面编程频繁使用的一个效果,在windows系统下可谓大行其道.纵观时下的应用软件几乎各个都支持各种各样拖动的效果,windows7更是把拖动做到了极致.其实说起来拖动的实现也很简单,对于有句柄 ...

  2. js实现一个可以兼容PC端和移动端的div拖动效果

    前段时间写了一个简单的div拖动效果,不料昨天项目上正好需要一个相差不多的需求,就正好用上了,但是在移动端的时候却碰到了问题,拖动时候用到的三个事件:mousedown.mousemove.mouse ...

  3. 使用jquery实现简单的拖动效果,分享源码

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkEAAAERCAIAAADzAOSQAAALRklEQVR4nO3dW5LaaAKEUfa/NkfMGu

  4. jquery div拖动效果示例代码

    div拖动效果想必大家都有见到过吧,实现的方法也是有很多的,下面为大家将介绍使用jquery是如何实现的,感兴趣的朋友不要错过 复制代码代码如下: <%@ page language=" ...

  5. 使用jQuery实现简单的拖动效果

    转自:http://www.muzilei.com/archives/136 如何实现拖动效果? 浏览DEMO 首先分析下拖动效果原理: 1.当鼠标在被拖动对象上按下鼠标(触发onmousedown事 ...

  6. Web的鼠标拖动效果

    以前写过一个拖动效果的Demo,拖拽元素新位置的计算是放在拖拽元素的mousemove事件中进行的.计算效率差,而且效果不好.所以一直有想怎样才能做出jquery-ui那种顺滑的拖拽效果. 其实顺滑的 ...

  7. js 实现win7任务栏拖动效果

    前言 在某个时刻, 我认识了一个朋友. 此人在我的教唆下, 踏上了js的不归路. 前天他问我, Win7任务栏拖动效果怎么实现. 我随口就跟他说, 这简单的一逼. 在我一晚上的折腾之后, 一份潦草的代 ...

  8. Swift - 禁用UIWebView和WKWebView的下拉拖动效果

    使用UIWebView或WKWebView加载网页时,如果页面处于最顶端时,用户用手指往下拖动,会露出灰色空背景.同样页面在最底部的时候,继续向上拖动,下方也会露出空背景. 要禁止这个拖动效果,可进行 ...

  9. Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源码

    在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现.下面要说的就是上次Scroller ...

随机推荐

  1. 在“BindingNavigator”删除数据前弹出确认框的实现

    1)先设置DeleteItem为空,不让它调用自动生成的删除代码. 2)然后自己写代码实现,如下: private void bindingNavigatorDeleteItem_Click(obje ...

  2. 通过移动的Mas接口发送短信

    1. 首先,需要移动公司提供的用户名.密码.服务ID.接口Url等信息. 2. 将短信信息整理成XML格式的字符串,再转为byte数组,通过POST的方式,将短信发往Mas接口.需要引用"M ...

  3. [LOJ 1248] Dice (III)

    G - Dice (III) Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Descri ...

  4. redis作为mysql的缓存服务器(读写分离,通过mysql触发器实现数据同步)

    一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录 ...

  5. ♫【jQuery插件】图片放大镜

    JQZoom

  6. mysql_insert_id 为什么会返回空值

    如果同时打开了一个以上的数据库资源,如果其中一个资源,没有使用insert语句或没有auto_increment类型的数据,或返回结果恰好为空值时,会导致mysql_insert_id()返回空值. ...

  7. 理解dojo.require机制

    转自:http://blog.csdn.net/dojotoolkit/article/details/5935844 Dojo 提供了一个非常强大的javascript控件库. 在使用dojo之前, ...

  8. VTL说明文档

    关于这个指南 这个指南是针对Velocity模版语言(VTL)的说明.更多其它的信息,请参考Velocity用户指南(http://velocity.apache.org/engine/release ...

  9. How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu

    sudo apt-get update sudo apt-get install nginxsudo mkdir -p /var/www/example.com/html sudo chown -R ...

  10. 430单片机之定时器A功能的大致介绍

    总的来说,430单片机一共有三个定时器,定时器A,定时器B,还有就是看门狗定时器,这里我们主要是讨论430单片机的定时器A的功能,定时器A的功能是我目前见过最厉害的定时器,视频上说用好定时器A的话,对 ...