我的第一个开源控件出炉了,希望各个小伙伴给个star,支持下。项目地址

1. 前言

因为项目须要,要做一个相似腾讯视频。频道管理。拖拽排序的效果。这个控件是在原地址 之上改造出来的。先看下效果图。

 1.0版本号的效果图

因为我电脑是ubuntu,没法弄gif,等星期一到了公司上gif吧。只是,github上有apk,能够弄下来看看,

2. 实现思路

2.1 怎样响应长按事件

我们尽管能够给view设置监听器。可是我们须要频繁的调用GridVIew的一些方法。显然,那样做是不合适的。

于是,我们在onInterceptTouchEvent中设置长按和短按的监听。

2.2 响应长按之后干什么

在响应长按事件之后。我们通过windowmanager在我们长按处加入一个view.加入view的代码例如以下。

windowParams = new WindowManager.LayoutParams();
windowParams.gravity = Gravity.TOP | Gravity.LEFT;
windowParams.x = x - win_view_x;
windowParams.y = y - win_view_y;
windowParams.width = (int) (dragScale * dragBitmap.getWidth());// 放大dragScale倍,能够设置拖动后的倍数
windowParams.height = (int) (dragScale * dragBitmap.getHeight());// 放大dragScale倍,能够设置拖动后的倍数
this.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
this.windowParams.format = PixelFormat.TRANSLUCENT;
this.windowParams.windowAnimations = 0;
ImageView iv = new ImageView(getContext());
iv.setImageBitmap(dragBitmap);
windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);// "window"
windowManager.addView(iv, windowParams);

2.3 移动的过程怎么处理

移动的过程中我们须要处理2件事。更改view的位置,动画。

先说更改view的位置。

代码例如以下

windowParams.alpha = 1.f;
windowParams.x = rawx - win_view_x;
windowParams.y = rawy - win_view_y;
windowManager.updateViewLayout(dragImageView, windowParams);

我们仅仅须要改动params的x,y。而且update就可以。再说动画。

  • 计算当前所在的position | pointToPosition(x, y);
  • 计算应该移动的数量 | 当前-移动那一块
movecount = endPosition - dragPosition;
  • 依据大小计算移动的方向和距离
for (int i = 0; i < movecount_abs; i++) {
to_x = x_vlaue;
to_y = y_vlaue;
//像左
if (movecount > 0) {
// 推断是不是同一行的
holdPosition = dragPosition + i + 1;
if (dragPosition / mColumns == holdPosition / mColumns) {
to_x = -x_vlaue;
to_y = 0;
} else if (holdPosition % 4 == 0) {
to_x = 3 * x_vlaue;
to_y = -y_vlaue;
} else {
to_x = -x_vlaue;
to_y = 0;
}
} else {
//向右,下移到上,右移到左
holdPosition = dragPosition - i - 1;
if (dragPosition / mColumns == holdPosition / mColumns) {
to_x = x_vlaue;
to_y = 0;
} else if ((holdPosition + 1) % 4 == 0) {
to_x = -3 * x_vlaue;
to_y = y_vlaue;
} else {
to_x = x_vlaue;
to_y = 0;
}
}
  • 在动画结束的时候更新数据源 

    我们须要做的大概就是上面几部。那么。如今我们移动完了。

2.4 up事件的处理

因为这种控件,百分之90可能会有数据联动。所以,我们须要在Up事件中回调通知其它的adapter数据源变化(注意,up事件非常可能发生在多次动画之后)。

((BaseDragAdapter)getAdapter()).dragEnd();
requestDisallowInterceptTouchEvent(false);

恩。大概就这么多了。详细的大家看代码吧。

3. 结语

这个控件。我已经用在了开发其中,尽管。这个控件还存在一些问题,如adapter不能使用convertView and holder来优化等等。

github地址:DragGridView 求个star

最新文章

  1. jQuery中的事件处理
  2. 2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结
  3. GDB调试笔记
  4. MONO Jexus部署最佳体验
  5. Python爬虫第一集
  6. Docker系列(五)OVS+Docker网络打通示例
  7. PHP下编码转换函数mb_convert_encoding与iconv的使用说明
  8. iOS开发中两个不错的宏定义
  9. Android调整TimePicker和DatePicker大小
  10. C++中实现 time_t, tm 相互转换
  11. view类的XML属性
  12. Python初识--基础
  13. CentOS 7.6 使用kubeadm安装Kubernetes 13
  14. Pyinstaller (python打包为exe文件)
  15. 基于vue cli 3.0创建前端项目并安装cube-ui
  16. js的短路
  17. 开发一个简单的chrome插件-解析本地markdown文件
  18. JAVA核心技术I---JAVA基础知识(映射Map)
  19. 行为驱动:BDD框架之Cucumber初探
  20. Jmeter执行python脚本函数使用说明

热门文章

  1. qemu-img命令
  2. 第一讲:vcs simulation basic
  3. Java学习笔记(1)-(GridBagLayout)网格袋布局
  4. django1.11 启动错误:Generator expression must be parenthesized
  5. 火狐插件youdao word capturer无法删除。
  6. 创意、实现和合作:一次原创H5的尝试
  7. Codeforces Round #387 (Div. 2) A+B+C+D!
  8. FZU-1881-Problem 1881 三角形问题,打表二分查找~~
  9. Monkey King(左偏树)
  10. docker镜像没有ifconfig、ping指令