自定義GridView并且實現(xiàn)拖拽(附源碼)
更新時間:2013年06月07日 17:06:30 作者:
本文實現(xiàn)了GridView的拖拽功能,原理很簡單只是在交換位置上記錄了X軸的相關(guān)坐標(biāo),計算了X軸的相關(guān)變量,實例代碼如下,感興趣的額朋友可以參考下哈
寫在前面的話
本篇blog實現(xiàn)了GridView的拖拽功能。方法和上一篇自定義ListView實現(xiàn)拖拽ListItem項交換位置一個原理。只是在交換位置上記錄了X軸的相關(guān)坐標(biāo),計算了X軸的相關(guān)變量。
實現(xiàn)效果圖如下
說明:
本篇給出實現(xiàn)代碼,但是不做任何說明。如需了解請看上一篇blog:自定義ListView實現(xiàn)拖拽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);
//初始化數(shù)據(jù)
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));
//根據(jù)文件名獲取資源文件夾中的圖片資源
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坐標(biāo)的計算
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);
//如果選中拖動圖標(biāo)
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來實現(xiàn)滾動
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;
}
//數(shù)據(jù)交換
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>
源碼下載
本篇blog實現(xiàn)了GridView的拖拽功能。方法和上一篇自定義ListView實現(xiàn)拖拽ListItem項交換位置一個原理。只是在交換位置上記錄了X軸的相關(guān)坐標(biāo),計算了X軸的相關(guān)變量。
實現(xiàn)效果圖如下
說明:
本篇給出實現(xiàn)代碼,但是不做任何說明。如需了解請看上一篇blog:自定義ListView實現(xiàn)拖拽ListItem項交換位置
文件代碼:
1、MainActivity.java
復(fù)制代碼 代碼如下:
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);
//初始化數(shù)據(jù)
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));
//根據(jù)文件名獲取資源文件夾中的圖片資源
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
復(fù)制代碼 代碼如下:
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坐標(biāo)的計算
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);
//如果選中拖動圖標(biāo)
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來實現(xiàn)滾動
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;
}
//數(shù)據(jù)交換
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
復(fù)制代碼 代碼如下:
<?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
復(fù)制代碼 代碼如下:
<?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>
源碼下載
您可能感興趣的文章:
- GridView分頁的實現(xiàn)以及自定義分頁樣式功能實例
- GridView自定義分頁的四種存儲過程
- C#自定義DataGridViewColumn顯示TreeView
- yii2.0之GridView自定義按鈕和鏈接用法
- GridView自定義刪除操作的具體方法
- asp.net gridview自定義value值的代碼
- asp.net gridview分頁:第一頁 下一頁 1 2 3 4 上一頁 最末頁
- asp.net中的GridView分頁問題
- Android入門之ActivityGroup+GridView實現(xiàn)Tab分頁標(biāo)簽的方法
- asp.net Gridview分頁保存選項
- 基于GridView和ActivityGroup實現(xiàn)的TAB分頁(附源碼)
- GridView自定義分頁實例詳解(附demo源碼下載)
相關(guān)文章
Android 將view 轉(zhuǎn)換為Bitmap出現(xiàn)空指針問題解決辦法
這篇文章主要介紹了Android 將view 轉(zhuǎn)換為Bitmap出現(xiàn)空指針問題解決辦法的相關(guān)資料,這里提供實例并提供解決辦法,需要的朋友可以參考下2017-07-07
Android基礎(chǔ)開發(fā)小案例之短信發(fā)送器
這篇文章主要為大家詳細(xì)介紹了Android基礎(chǔ)開發(fā)小案例之短信發(fā)送器的具體實現(xiàn)代碼,感興趣的小伙伴們可以參考一下2016-05-05
Android使用Volley框架定制PostUploadRequest上傳文件
這篇文章主要為大家詳細(xì)介紹了Android使用Volley框架定制PostUploadRequest上傳文件或圖片,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12
Android開發(fā)之TextView控件用法實例總結(jié)
這篇文章主要介紹了Android開發(fā)之TextView控件用法,結(jié)合實例形式總結(jié)分析了TextView控件常用的屬性設(shè)置及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-02-02
android同時控制EditText輸入字符個數(shù)和禁止特殊字符輸入的方法
這篇文章主要介紹了android同時控制EditText輸入字符個數(shù)和禁止特殊字符輸入的方法,涉及Android操作EditText控制字符操作的技巧,需要的朋友可以參考下2015-04-04

