2011.06.21——— android GridView的拖拽
参考:
http://www.cnblogs.com/qianxudetianxia/archive/2011/06/19/2084886.html
需求:一个可拖拽的gridview
代码:
拖拽view:
package com.lp;
import com.lp.MainActivity.ImageAdapter;
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.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
public class DragGridView extends GridView {
private int dragPosition;//开始拖拽的位置
private int dropPosition;// 结束拖拽的位置
private int dragPointX; //相对于item的x坐标
private int dragPointY; //相对于item的y坐标
private int dragOffsetX;
private int dragOffsetY;
private ImageView dragImageView; //拖动item的preview
private WindowManager windowManager;
private WindowManager.LayoutParams windowParams;
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();
dragPosition = dropPosition = pointToPosition(x, y);
System.out.println(dragPosition);
if(dragPosition==AdapterView.INVALID_POSITION){
return super.onInterceptTouchEvent(ev);
}
ViewGroup itemView = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition());
//得到当前点在item内部的偏移量 即相对于item左上角的坐标
dragPointX = x - itemView.getLeft();
dragPointY = y - itemView.getTop();
dragOffsetX = (int)(ev.getRawX() - x);
dragOffsetY = (int)(ev.getRawY() - y);
//解决问题3
//每次都销毁一次cache,重新生成一个bitmap
itemView.destroyDrawingCache();
itemView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
//建立item的缩略图
startDrag(bm,x,y);
return false;
}
return super.onInterceptTouchEvent(ev);
}
private void startDrag(Bitmap bm, int x, int y) {
stopDrag();
windowParams = new WindowManager.LayoutParams();
System.out.println("X: "+ x +" dragPointX: " + dragPointX +" dragOffsetX: " +dragOffsetX);
windowParams.gravity = Gravity.TOP|Gravity.LEFT;//这个必须加
//得到preview左上角相对于屏幕的坐标
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
//设置宽和高
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.width = 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 iv = new ImageView(getContext());
iv.setImageBitmap(bm);
windowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);//"window"
windowManager.addView(iv, windowParams);
dragImageView = iv;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(dragImageView!=null && dragPosition!=AdapterView.INVALID_POSITION){
int x = (int)ev.getX();
int y = (int)ev.getY();
switch(ev.getAction()){
case MotionEvent.ACTION_MOVE:
onDrag(x,y);
break;
case MotionEvent.ACTION_UP:
stopDrag();
onDrop(x,y);
break;
}
}
return super.onTouchEvent(ev);
}
private void onDrag(int x, int y) {
if(dragImageView!=null){
windowParams.alpha = 0.6f;
windowParams.x = x - dragPointX + dragOffsetX;
windowParams.y = y - dragPointY + dragOffsetY;
windowManager.updateViewLayout(dragImageView, windowParams);
}
}
private void onDrop(int x,int y) {
int tempPosition = pointToPosition(x, y);
if(tempPosition!=AdapterView.INVALID_POSITION){
dropPosition = tempPosition;
}
if(dropPosition!=dragPosition){
System.out.println("dragPosition: "+dragPosition+" dropPosition: "+dropPosition);
ImageAdapter adapter = (ImageAdapter)this.getAdapter();
adapter.exchange(dragPosition, dropPosition);
//解决问题3
/*
ViewGroup itemView1 = (ViewGroup)getChildAt(dragPosition - getFirstVisiblePosition());
ViewGroup itemView2 = (ViewGroup)getChildAt(dropPosition - getFirstVisiblePosition());
itemView1.destroyDrawingCache();
itemView2.destroyDrawingCache();
*/
}
}
private void stopDrag() {
if(dragImageView!=null){
windowManager.removeView(dragImageView);
dragImageView = null;
}
}
}
MainActivity:
package com.lp;
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.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private GridView gv;
private List<String> list = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initData();
gv = (GridView)findViewById(R.id.drag_grid);
gv.setAdapter(new ImageAdapter(this));
}
private void initData(){
for(int i=1;i<10;i++){
list.add("grid_"+i);
}
}
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private LayoutInflater lif;
public ImageAdapter(Context c){
mContext = c;
lif = LayoutInflater.from(c);
}
public int getCount() {
return list.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
/**
* 遇到的问题:
* 1、删除错了 会有重复的图片
* 这个是由 remove引起的
* 删除时 我们先删除了小的position
* 比如说 startPosition = 2;endPosition = 3;
* 当我先删startPosition时 这时 删除前position为3的项 已经是position为2了
* 2、数组越界 异常
* 这个是由 add引起的
* 比如说 startPosition = 8;endPosition = 7;
* 一共gridview有9个元素 也就是说8 已经是最大的了
* 当删除完后 你先增加爱 startposition时 就会异常了
* 3、preview问题
* 当我拖拽互换几次后 机会出现 当前的图片 显示的是另一个图片的preview
*
* 得调用 destroyDrawingCache
* @param startPosition
* @param endPosition
*/
public void exchange(int startPosition, int endPosition){
//比较一下 使startPosition永远小于endPosition的值 解决问题1 ,2
if(startPosition > endPosition){
int temp = endPosition;
endPosition = startPosition;
startPosition = temp;
}
Object endObject = getItem(endPosition);
Object startObject = getItem(startPosition);
//list.remove(endPosition);
//list.remove(startPosition);
System.out.println(startPosition + "========"+endPosition);
list.set(startPosition,(String)endObject);
list.set(endPosition,(String)startObject);
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
//ImageView iv;
if(convertView==null){
convertView = lif.inflate(R.layout.grid_item, null);
// iv = new ImageView(mContext);
// try{
// Field f = (Field)R.drawable.class.getDeclaredField(list.get(position));
// int i = f.getInt(R.drawable.class);
// iv.setImageResource(i);
// }catch(Exception e){
// e.printStackTrace();
// }
}
try {
Field f = (Field)R.drawable.class.getDeclaredField(list.get(position));
int i = f.getInt(R.drawable.class);
ImageView iv = (ImageView)convertView.findViewById(R.id.image);
iv.setImageResource(i);
} catch (Exception e) {
e.printStackTrace();
}
// else{
// iv = (ImageView)convertView;
// }
return convertView;
}
}
}
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"
>
<com.lp.DragGridView
android:id="@+id/drag_grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="5dip"
android:horizontalSpacing="20dip"
android:background="#ffffff"/>
</LinearLayout>
grid_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
具体说明 请看代码 里面有详细说明
分享到:
相关推荐
这个“Android源码——GridView拖拽实例源码_new_07.7z”压缩包包含了实现GridView拖拽功能的示例代码,对于学习如何增强用户交互体验非常有帮助。 GridView的基础知识: 1. **定义**:GridView继承自AbsListView,...
"安卓Android源码——gridview分页效果.zip"这个压缩包可能包含了一个实现GridView分页效果的示例项目。HorizontalGridView是GridView的一个扩展,它使得数据可以横向滚动,提供了更丰富的界面展示方式。 首先,...
这个"Android源码——GridView拖拽实例源码_new_07.zip"文件提供了关于如何实现GridView元素拖拽功能的示例代码。这个功能在很多场景下都非常实用,比如在移动应用中调整图片顺序或者在文件管理器中重新排列文件。 ...
本压缩包提供的“安卓Android源码——GridView拖拽实例源码”是一个实战案例,展示了如何实现GridView中的元素拖拽功能,这对于提升用户体验和增强应用交互性具有重要意义。 首先,我们需要理解GridView的基本用法...
"安卓Andriod源码——gridview分页效果.zip"这个压缩包的学习可以帮助开发者理解和实现Android中的GridView分页效果,同时也能掌握HorizontalGridView的使用,提升Android应用的交互体验。实际开发时,应根据项目...
在Android开发中,GridView是一种常用的布局控件,它允许我们以网格的形式展示数据。当我们处理大量数据时,分页加载可以提高应用性能,减少内存消耗,并提供更好的用户体验。本篇文章将详细讲解如何在Android中利用...
这个"安卓Android源码——gridview分页效果.rar"文件很可能是包含了一个实现GridView分页效果的示例项目。分页在大数据量展示时尤为重要,因为它提高了用户体验,避免一次性加载大量数据导致应用性能下降或内存溢出...
`Android中文翻译组——Android中文API——android.widget合集(中).chm`文件很可能是这个主题的中文参考手册,包含了这些控件的详细解释、使用示例和API文档,对于初学者来说是一份宝贵的资源。建议读者仔细阅读并...
这个“Android GridView拖拽实例源码”项目提供了一个具体的实现,让用户可以拖动GridView中的元素,增强用户体验。下面我们将详细探讨GridView以及如何实现拖放功能。 首先,理解`GridView`。`GridView`是`...
2. **GridView控件**:GridView是ASP.NET Web Forms中的一种数据绑定控件,常用于展示表格数据。它可以从数据库或其他数据源动态加载数据,并允许用户进行排序、分页和编辑。 3. **PDF文件格式**:PDF(Portable ...
在Android开发中,GridView是一个非常常用的布局控件,它允许我们以网格的形式展示数据,通常用于创建类似照片墙、应用快捷方式或者菜单等界面。在这个"Android GridView使用例子"中,我们将深入探讨如何有效地利用...
在Android开发中,GridView是一种常用的布局控件,它允许我们以网格的形式展示数据。这个"AndroidGridView点击每一个图片进入个人页面渐变特效.zip"压缩包包含的资源可能是一个示例项目,展示了如何在GridView中实现...
在Android开发中,GridView是一种非常常用的布局控件,它允许我们以网格的形式展示数据,通常用于创建像照片墙、应用列表等多列显示的内容。在本教程中,我们将深入探讨如何在Android应用中使用GridView。 首先,...
这个"Android GridView拖拽实例源码"是一个实用的资源,它提供了实现GridView元素拖放功能的代码示例,这对于提升用户交互体验和优化界面操作具有重要意义。 首先,我们要理解GridView的基本工作原理。GridView继承...
在Android GridView的拖拽操作中,主要涉及以下几个关键知识点: 1. **GridView的基本使用**:首先,我们需要了解GridView的基本用法,包括在XML布局文件中声明GridView,设置其属性如列数(android:numColumns)、...