Android学习系列(12)--App列表之拖拽GridView
根据前面文章中ListView拖拽的实现原理,我们也是很容易实现推拽GridView的,下面我就以相同步骤实现基本的GridView拖拽效果。
因为GridView不用做分组处理,代码处理起来更简洁,而且原理前面已经讲解清楚了,代码中只是简单的过下,必要的地方简单的注释一下。
1.主界面DragGridActivity.
- public class DragGridActivity extends Activity {
- private static List<String> list = null;
- //自定义适配器
- private DragGridAdapter adapter = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.drag_grid_activity);
- 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);
- }
- }
- }
复制代码
2.主界面UI布局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="#ffffff"
- android:padding="10dip"
- >
- <com.fengjian.test.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>
复制代码
3.列表项布局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:src="@drawable/grid_icon"
- android:layout_margin="5dip"
- android:layout_alignParentTop="true"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"/>
- <ImageView android:id="@+id/drag_grid_item_drag"
- android:src="@drawable/grid_drag"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- </RelativeLayout>
复制代码
4.自定义适配器DragGridAdapter,继承ArrayAdapter<String>.
- 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 {
- //根据文件名获取资源文件夹中的图片资源
- 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;
- }
- }
复制代码
5.自定义视图类DragGridView,继承GridView.
- 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);
- }
- }
复制代码
6. 重写触控拦截事件方法onInterceptTouchEvent().
- @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);
- }
复制代码
startDrag和stopDrag方法如下:
- 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);
- }
- }
复制代码
7.重写onTouchEvent()方法.
- @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);
- }
复制代码
其中onDrag方法如下:
- 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);
- }
- }
复制代码
8.放下影像,数据更新。
在onDrop方法中实现:
- 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();
- }
- }
复制代码
这篇文章也算是前面文章的一个补充和扩展。
Android学习系列(12)--App列表之拖拽GridView的更多相关文章
- Android学习系列(11)--App列表之拖拽ListView(下)
接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法. 在这个方法中我们主要是处理 ...
- Android学习系列(10)--App列表之拖拽ListView(上)
研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨. 鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...
- Android学习系列(15)--App列表之游标ListView(索引ListView)
游标ListView,提供索引标签,使用户能够快速定位列表项. 也可以叫索引ListView,有的人称也为Tweaked ListView,可能更形象些吧. 一看图啥都懂了: 1. ...
- Android学习系列(17)--App列表之圆角ListView(续)
http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html 本来这篇文章想并到上篇Android学习系列(16)- ...
- Android学习系列(16)--App列表之圆角ListView
有些东西看多了,就厌烦了:extjs对我这种感觉最为强烈.甚至,有时觉得设计之殇是审美疲劳.直角看多了,就想看看圆角,不知何时,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,iphone中 ...
- Android学习系列(9)--App列表之分组ListView
吸引用户的眼球,是我们至死不渝的追求: 第一时间呈现最有价值的信息,简明大方,告诉客户,你的选择是多么的明智,这正是你寻觅已久的东西. 分组的应用场合还是很多的,有数据集合的地方 ...
- Android学习系列--App列表之拖拽ListView(下)
接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法. 在这个方法中我们主要是处理 ...
- Android学习系列--App列表之拖拽ListView(上)
研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨. 鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. 一 ...
- Android学习系列(7)--App轮询服务器消息
这篇文章是android开发人员的必备知识. 1.轮询服务器 一般的应用,定时通知消息可以采用轮询的方法从服务器拿取消息,当然实时消息通知的话,建议采用推送服务. 其中需要注意轮询的频率 ...
随机推荐
- mongodb实现远程连接
mongodb远程连接配置分为以下4步: 1. 添加管理员账户 > use admin switched to db admin > db.addUser('tank','test'); ...
- 附6 hystrix metrics and monitor
一.基本方式 hystrix为每一个commandKey提供了计数器 二.实现流程 https://raw.githubusercontent.com/wiki/Netflix/Hystrix/ima ...
- Python编程学习,高效求解素数程序实例
素数是编程中经常需要用到的. 作为学习Python的示例,下面是一个高效求解一个范围内的素数的程序,不需要使用除法或者求模运算. #coding:utf-8 #设置python文件的编码为utf-8, ...
- Div+Css实现段落首行缩进两个字符(text-indent标签)
段落前面空两个字的距离,不要再使用空格了,用CSS实现段落首缩进两个字符.应该使用首行缩进text-indent.text-indent可以使得容器内首行缩进一定单位.比如中文段落一般每段前空两个汉字 ...
- 红黑树,TreeMap,插入操作
红黑树 红黑树顾名思义就是节点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡.对于一棵有效的红黑树二叉树而言我们必须增加如下规则: 1.每个节点都只能是红色或者黑色 2.根节点是黑色 ...
- Python访问MongoDB数据库
#encoding: utf-8 __author__ = 'Administrator' #import pymongo from pymongo import MongoClient,GEO2D ...
- Discuz常见大问题-如何允许用户插入视频-如何允许用户在编辑帖子的时候带标签,允许用户插入视频
在用户-用户组中,切换到会员用户组或系统用户组,可以勾选批量编辑前面的方框,然后点击批量编辑 点击论坛相关-帖子相关(默认是基本设置,你可以在这里设置所有用户的所有权限),然后把你要设置允许的用户的组 ...
- Hadoop的简单使用
Hadoop的简单使用 使用Hadoop提供的命令行,向文件系统中创建一个文件. ./hadoop fs -put temp.txt hdfs://localhost:8888/ 说明: ./hado ...
- ng-src 的坑
问题: <ion-slide ng-repeat="item in bannrImgData" ng-click="getActivity($index)" ...
- java各种框架的比较,分析
Spring 框架 优点 1.提供了一种管理对象的方法,可以把中间层的对象有效地组织起来 2.采用了分层结构,可以增量引入到项目中. 3.代码测试较容易 4.非侵入性,应用程序对Spring API的 ...