Android Metro风格的Launcher开发系列第三篇
前言:
各位小伙伴,又到了每周更新文章了时候了,本来是周日能发出来呢,这不是赶上清明节吗,女王大人发话了,清明节前两天半陪她玩,只留给我周一下午半天时间写博客
,哪里有女王哪里就有压迫呀有木有!好了闲话少说,上一篇博客(Android Metro风格的Launcher开发系列第二篇)说到Launcher主体框架用ViewPager来实现,这一篇博客咱们来说说每一个page的具体实现。
PagerAdapter:
Launcher主体ViewPager实现就引出了PagerAdapter,PagerAdapter是android.support.v4包中的类,它的子类有FragmentPagerAdapter, FragmentStatePagerAdapter,这两个adapter都是Fragment的适配器,这里因为没有用到Fragment所以这里不讲,我只讲PagerAdapter。关于PageAapter的描述,Google官网原文是这样的:Base class providing the adapter to populate pages inside of a ViewPager. You will most likely want to use a more specific implementation of this, such as FragmentPagerAdapter or FragmentStatePagerAdapter,大致就是说PagerAdapter是ViewPager提供的一个适配器,方便我们对ViewPager的每一个View进行控制。我的PagerAdapter是这样实现的:
public class LauncherAdapter extends PagerAdapter {
private ArrayList<PageViewItem> mViews;
public LauncherAdapter(ArrayList<PageViewItem> views) {
mViews = views;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView(mViews.get(arg1));
}
@Override
public void finishUpdate(View arg0) {
}
@Override
public int getCount() {
if (mViews != null) {
return mViews.size();
}
return 0;
}
public View getCurrentView(int currentID) {
return mViews.get(currentID);
}
@Override
public Object instantiateItem(View arg0, int arg1) {
((ViewPager) arg0).addView(mViews.get(arg1));
return mViews.get(arg1);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return (arg0 == arg1);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
}
PageViewItem:
PagerAdapter的getCurrentView方法返回的每一个view都是自定义View,为什么要自定义呢?因为在每一个图标获取焦点放大的时候会与旁边的图标有重叠部分,ViewPager每一页view都是一个FrameLayout,在绘制view的时候是按照一定的顺序绘制的,就会遇到焦点view放大后显示的效果是被旁边的view压了一部分,如果不改变view绘制顺序就不能避免这个问题。
如上图所示,图一显示效果就是焦点view放大,改变绘制顺序的实现效果。改变绘制顺序其实就是重写ViewGroup的getChildDrawingOrder(int childCount, int i)方法,每一次绘制时,最后返回focusview所在的viewgroup中的index就行了。
CellView:
如上图所示,每一个正方形的view我在这里叫做CellView,它也是一个自定义的view,自定义主要是为了实现:
1、获取焦点时放大和丢掉焦点时缩小效果,这里是应用了属性动画,ViewPropertyAnimator可以通过View的animate()方法获取的,具体动画实现如下:
mPropertyAnimator.scaleX((width + mScaleX) / width)
.scaleY((height + mScaleY) / height).setDuration(duration)
.setInterpolator(new DecelerateInterpolator())
.start();
2、在xml文件灵活配置一些CellView的属性,比如点击打开的应用,呈现的ICON获取地址,焦点x、y的放大值等,CellView对应的属性定义attrs.xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<resources> <declare-styleable name="Launcher_ScaleView">
<attr name="parentID" format="integer" />
<attr name="resUrl" format="string" />
<attr name="resType" format="integer" />
<attr name="isRightEdge" format="boolean" />
<attr name="isLeftEdge" format="boolean" />
<attr name="isTopEdge" format="boolean" />
<attr name="isBottomEdge" format="boolean" />
<attr name="scaleX" format="integer" />
<attr name="scaleY" format="integer" />
<attr name="packageName" format="string" />
<attr name="activityName" format="string" />
<attr name="intentKey" format="string" />
<attr name="intentValue" format="string" />
<attr name="focusType" format="integer" />
</declare-styleable> </resources>
3、实现在用遥控器移动焦点时不会焦点错乱,在开发遥控器应用时一个很大的问题就是焦点在移动时焦点错乱,基本上应用UI bug至少有一半时焦点bug,这个应用我为了防止焦点错乱定义了CellView的边界属性,上面的xml文件中isXXEdge就是,这样在焦点移动到边界时可以进行Page之间的切换和其他处理,防止焦点在进入每一个page时出现错乱。
下面来看一下实现的具体效果:
总结:以上就是Metro风格Launcher实现,我用了三篇博客来讲解这个应用,所有效果的实现都是自己摸索的,应该还有更好的实现方法,大家可以多多交流提出自己的看法,也可以关注我的微信号coder_online,以上谢谢!
第一时间获得博客更新提醒,以及更多技术信息分享,欢迎关注个人微信公众平台:程序员互动联盟(coder_online),扫一扫下方二维码或搜索微信号coder_online即可关注,我们可以在线交流。
Android Metro风格的Launcher开发系列第三篇的更多相关文章
- 【转载】Android Metro风格的Launcher开发系列第二篇
前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客Android Metro风格的Launcher开发系列第一篇写了如 ...
- [转载] Android Metro风格的Launcher开发系列第一篇
前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...
- Android Metro风格的Launcher开发系列第一篇
前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...
- Android Metro风格的Launcher开发系列第二篇
前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客http://www.cnblogs.com/2010wuhao/p ...
- chromium浏览器开发系列第三篇:chromium源码目录结构
上两篇介绍了下载源码和编译源码,这次主要介绍chromium的源码目录结构,我也是通过源码和官网结合来跟大家说,如果有说的不准确的,欢迎交流. 另外,官网的不一定准确,他们其实也很懒,所以最主要还是靠 ...
- Android进阶(十九)AndroidAPP开发问题汇总(三)
Android进阶(十九)AndroidAPP开发问题汇总(三) Java解析XML的几种方式: http://inotgaoshou.iteye.com/blog/1012188 从线程返回数据的两 ...
- 【Windows10 IoT开发系列】配置篇
原文:[Windows10 IoT开发系列]配置篇 Windows10 For IoT是Windows 10家族的一个新星,其针对不同平台拥有不同的版本.而其最重要的一个版本是运行在Raspberry ...
- openlayers5-webpack 入门开发系列一初探篇(附源码下载)
前言 openlayers5-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载 ...
- leaflet-webpack 入门开发系列一初探篇(附源码下载)
前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 w ...
随机推荐
- [C#.net]获取文本文件的编码,自动区分GB2312和UTF8
昨天生产突然反馈上传的结果查询出现了乱码,我赶紧打开后台数据库,发现果真有数据变成了乱码.这个上传程序都运行3个多月了,从未发生乱码现象,查看程序的运行日志,发现日志里的中文都变成了乱码,然后对比之前 ...
- day 35 线程
内容回顾 # 互斥锁 #在同一个进程中连续锁多次 #进程的数据共享 #进程之间可以共享数据 #提供共享数据的类是Manager #但是它提供的list|dict 这些数据类型 #针对+= -= *= ...
- vue中v-model动态生成的实例详解
每一行有一个input和一个select,其中行数是根据服务器返回的json数据动态变化的.那么问题来了,我们要怎样动态生成v-model? <template> <div> ...
- 学习Acegi应用到实际项目中(8)- 扩展UserDetailsService接口
一个能为DaoAuthenticationProvider提供存取认证库的的类,它必须要实现UserDetailsService接口: public UserDetails loadUserByUse ...
- (PMP)第1章-----引论
1.指南概述和目的: 2.基本要素: 项目:创造独特的产品,服务或成果而进行的临时性工作.特点:1.临时性 临时性并不一定意味着项目时间短.2.独特性 3.渐进明细性 项目管理:就是将知识,技 ...
- [f]聊天的时间格式化
代码如下: 参数: t: 时间戳, type:返回格式(1:IM界面,其他:会话列表) function formartTime(t, type) { var oldtime = new Date(t ...
- [swarthmore cs75] Compiler 5 – Egg-eater
课程回顾 Swarthmore学院16年开的编译系统课,总共10次大作业.本随笔记录了相关的课堂笔记以及第7次大作业. 抽象语法: 存储方式: 栈中的数据如果最后三位(tag bits)是001表示元 ...
- im4java+GraphicsMagick 的问题
1.convert.exe: non-conforming drawing primitive definition `' @ error/draw.c/RenderMVGContent/3901. ...
- 解决Ubuntu自带编译器不好使问题
解决Ubuntu自带编译器不好使问题 1.删除Ubuntu自带的tiny版本,这个版本用起来很别扭不好使. 2.安装full版本的vim 3.显示效果:full版本. 之前自带的版本:
- Oracle数据库---用户与角色
Oracle数据库---用户与角色 2019年02月26日 10:56:10 俊杰梓 阅读数:21 标签: 数据库 更多 个人分类: 数据库 版权声明:版权所有,转载请注明出处.谢谢 https: ...