Android开源系列:仿网易Tab分类排序控件实现
前言
产品:网易新闻那个Tab排序好帅。
开发:哦~
然后这个东东在几天后就出现了。。。。。
(PS:差不多一年没回来写博客了~~~~(>_<)~~~~,顺便把名字从 enjoy风铃 修改为 码农叔叔)
效果图
使用方法
1、XML布局引入
<com.net168.lib.SortTabLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
2、设置数据源数据,也就是每个item的对应文本数据
//构造数据源,暂时仅支持String
List<String> data = new ArrayList<String>();
for (int i = 0; i < 20; i ++) {
data.add("item" + i);
}
//设置数据源
vSortLayout.setShowData(data, 1);
3、设置监听,用于交互点击和长按的事件
vSortLayout.setOnSelectListener(new onSelectListener() {
//点击事件,点击Tab布局里面的item触发
@Override
public void onSelect(View v, int index) {
Toast.makeText(MainActivity.this, "你点击了item ,内容为:" + ((TextView)v).getText(), Toast.LENGTH_SHORT).show();
}
//长按事件,长按Tab布局里面的item触发
@Override
public void onLongSelect(View v) {
Toast.makeText(MainActivity.this, "长按Tab,开始排列", Toast.LENGTH_SHORT).show();
}
});
4、开始排序和结束排序的接口
//如果参数是true的话,开始排序,也就是可以拖动
vSortLayout.setIsMoveList(true);
//结束排序,并且会返回选择tab的当前新位置
vSortLayout.getAndFinishSortData();
5、基本没有其他的了~
未完善的自定义功能
1、现在仅仅是支持String,并且布局也无法自定义,后续可能会完善Tab的item的View的自定义输入
2、现在布局的行数和间距由硬代码控制,并没有形成简便易懂的接口暴漏
PS:调试间距的方法,主要调试下列几个参数
/**
* 配置参数区域
* mMaxRow : 每行的个数
* Magin Width Tab的间隔和本身的宽度的占比
* 例如mMaxRow = 4,则宽度会由此策略分配
* |Magin|View|Magin|View|Magin|View|Magin|View|Magin|
* 记控件宽度为这么分配 : 总宽度 = 5 * Magin + 4 * View, 而 Magin : View = mRowMagin : mRowWidth
* 可以推导出各个控件的宽度,高度也如此计算
*/
private final int mMaxRow = 4;
private final int mRowMagin = 5;
private final int mRowWidth = 26;
private final int mColumnMagin = 4;
private final int mColumnHeight = 10;
3、回滚不流畅,后期可以引入Scroller来控制缓慢回滚
原理实现
1、布局item排序采用基于ViewGroup的自定义布局,在onLayout的方法逻辑根据配置参数区域的参数进行计算配置
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { final int childCount = getChildCount(); int row = 0;
int column = 0;
int startWidth = 0;
int startHeight = 0; for (int i = 0; i < childCount; i++) {
View childeView = childList.get(i);
row = i / 4;
column = i % 4;
startWidth = (int) ((column * (mRowWidth + 2 * mRowMagin) + mRowMagin) * mChildeItemSize);
startHeight = (int) ((row * (mColumnHeight + 2 * mColumnMagin) + mColumnMagin) * mChildeItemSize);
childeView.layout(startWidth ,startHeight ,(int)(startWidth + mRowWidth * mChildeItemSize),
(int)(startHeight + mColumnHeight * mChildeItemSize));
} }
2、滑动模块部分,在onTouchEvent里面根据坐标的捕获,有坐标分析出对应的子Item,利用View.layout()方法让拖动的View跟随手指移动,参加代码
private void moveChildView(float x, float y) {
if (mMoveChildView != null) {
int left = (int) (((mChildIndex % 4) * (mRowWidth + 2 * mRowMagin) + mRowMagin) * mChildeItemSize);
int top = (int) (((mChildIndex / 4) * (mColumnHeight + 2 * mColumnMagin) + mColumnMagin) * mChildeItemSize);
int width = (int) (left + mRowWidth * mChildeItemSize);
int heigth = (int) (top + mColumnHeight * mChildeItemSize);
int moveX = (int) (x - beginX);
int moveY = (int) (y - beginY);
mMoveChildView.layout(left + moveX, top + moveY, width + moveX, heigth + moveY);
mMoveChildView.invalidate();
}
}
3、动画模块,由于考虑低版本和不想引入过多的开源库,故采用普通的动画实现
具体参见beginAnimation(final int start,final int end, boolean forward)方法。
4、整体流程
a、Touch的down事件,捕捉当前的x、y数据,计算出被移动的View的所对应index,并且其余view开始抖动动画
b、move事件,将被选中的view根据x、y利用layout方法进行跟随手指移动
c、up事件,执行位置调整动画,并且在调整完毕后,进行新位置的设置
结语
因为懒,所以懒~
控件是为了需求而写,并没有开源那般易于扩展,后续有时间会进行优化
github地址:https://github.com/CodeFarmerUncle168/SortTabLayout
作者:码农叔叔(enjoy风铃)
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了
Android开源系列:仿网易Tab分类排序控件实现的更多相关文章
- (转载) Android RecyclerView 使用完全解析 体验艺术般的控件
Android RecyclerView 使用完全解析 体验艺术般的控件 标签: Recyclerviewpager瀑布流 2015-04-16 09:07 721474人阅读 评论(458) 收藏 ...
- Android 打造完美的侧滑菜单/侧滑View控件
概述 Android 打造完美的侧滑菜单/侧滑View控件,完全自定义实现,支持左右两个方向弹出,代码高度简洁流畅,兼容性高,控件实用方便. 详细 代码下载:http://www.demodashi. ...
- 动手分析安卓仿QQ联系人列表TreeView控件
因项目需要需要用到仿QQ联系人列表的控件样式,于是网上找到一个轮子(https://github.com/TealerProg/TreeView),工作完成现在简单分析一下这个源码. 一. 需要用 ...
- ANDROID L——Material Design详解(UI控件)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...
- Android判断Touch为滑动事件还是操作控件
Android判断Touch为滑动事件还是操作控件 因为在项目中要判断WebView是否处于滚动状态,但它不像ListView有onScrollStateChanged方法来监听,要实现就得手动监听它 ...
- 怎样在Android实现桌面清理内存简单Widget小控件
怎样在Android实现桌面清理内存简单Widget小控件 我们常常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一 ...
- Android 自定义支持快速搜索筛选的选择控件(一)
Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...
- android开源系列:CircleImageView采用圆形控制它们的定义
1.定义自己的圆形控制github住址:https://github.com/hdodenhof/CircleImageView 基本的类: package de.hdodenhof.circleim ...
- Android 高仿微信支付密码输入控件
像微信支付密码控件,在app中是一个多么司空见惯的功能.最近,项目需要这个功能,于是乎就实现这个功能. 老样子,投篮需要找准角度,变成需要理清思路.对于这个"小而美"的控件,我们思 ...
随机推荐
- Django contenttypes 应用
Django contenttypes 应用 什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Dja ...
- Python开发——解释器安装
Python(解释器)安装 Windows 1.Python(解释器)下载链接 2.选择好安装路径,点击安装即可 3.环境变量配置 [右键计算机]-->[属性]-->[高级系统设置]--& ...
- Python开发——数据类型【数字】
布尔型 bool型只有两个值:True 或 False 我们将bool值归类为数字,习惯上:1表示true,0表示false 整型 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2* ...
- journalctl 清理journal日志
在CentOS 7开始使用的systemd使用了journal日志,这个日志的管理方式和以往使用syslog的方式不同,可以通过管理工具维护. 使用df -h检查磁盘文件,可以看到/run目录下有日志 ...
- [网络流]Farm Tour(费用流
Farm Tour 题目描述 When FJ's friends visit him on the farm, he likes to show them around. His farm compr ...
- tar: Removing leading `/' from member names
解决办法使用 -P 参数 注意 -f 参数后面跟压缩后的文件名
- 地址重写 No input file specified的解决方法
转载自:http://blog.csdn.net/williamsblog/article/details/37532737 (一)IIS Noinput file specified 方法一:改PH ...
- 摹客iDoc「标注」新玩法!这些细节让你爱不释手(201903-2版本更新)
哈喽小伙伴们,我们又见面啦!没错,小摹就是来告诉大家:摹客iDoc又双叒叕升级了!这次又上线了许多新玩法,在此之前,小摹先带大家温习一下iDoc以往的知识点: 攻城狮查看标注的利器 —— 标注信息智能 ...
- SQL里执行CLR c#代码
这里只说一个重点: 1.直接在sql里执行clr代码的时候,sql还是会报错 说没有启用 clr 执行以下代码才会起作用 EXEC sp_configure 'clr enabled', 1; RE ...
- 第七次spring会议
昨天我对加密文件进行了解密. 我今天对已完成的代码进行了总体运行,检查运行中出现的bug,在显示便签中出现了过长就无法一次显示完全的情况,没有办法