打造属于自己的安卓Metro界面

前言:

各位小伙伴,又到了每周更新文章了时候了,本来是周日能发出来呢,这不是赶上清明节吗,女王大人发话了,清明节前两天半陪她玩,只留给我周一下午半天时间写博客,哪里有女王哪里就有压迫呀有木有!好了闲话少说,上一篇博客(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是这样实现的:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

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()方法获取的,具体动画实现如下:

?


1

2

3

4

  mPropertyAnimator.scaleX((width + mScaleX) / width)

                         .scaleY((height + mScaleY) / height).setDuration(duration)

                         .setInterpolator( new  DecelerateInterpolator())

                         .start();

2、在xml文件灵活配置一些CellView的属性,比如点击打开的应用,呈现的ICON获取地址,焦点x、y的放大值等,CellView对应的属性定义attrs.xml文件如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?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即可关注,我们可以在线交流。

时间: 2024-10-20 03:57:54

打造属于自己的安卓Metro界面的相关文章

打造自己的安卓Metro界面

前言: 各位小伙伴,又到了每周更新文章了时候了,本来是周日能发出来呢,这不是赶上清明节吗,女王大人发话了,清明节前两天半陪她玩,只留给我周一下午半天时间写博客,哪里有女王哪里就有压迫呀有木有!好了闲话少说,上一篇博客(Android Metro风格的Launcher开发系列第二篇)说到Launcher主体框架用ViewPager来实现,这一篇博客咱们来说说每一个page的具体实现. PagerAdapter: Launcher主体ViewPager实现就引出了PagerAdapter,Pager

安卓学习-界面-布局-RelativeLayout

RelativeLayout相对布局,所有内部的组件都是相对的 XML属性 XML属性 函数 说明 android:gravity setGravity 内部组件的对其方式 android:ignoreGravity setIgnoreGravity 设置哪个组件不受Gravity影响 RelativeLayout.LayoutParams用来设置内部组件的对齐方式 XML属性 说明 android:layout_centerHorizontal 水平居中 android:layout_cent

Android TV开发总结(二)构建一个TV Metro界面(仿泰捷视频TV版)

前言:上篇是介绍构建TV app前要知道的一些事儿,开发Android TV和手机本质上没有太大的区别,屏大,焦点处理,按键处理,是有别于有手机和Pad的实质区别.今天来介绍TV中Metro UI风格,并结合实例说明. Android TV发展离不开Metro UI,先看最新的泰捷TV的会员区效果,属于典型的Metro风格,如下: 什么是Metro UI: Metro的设计意念来源于交通局巴士站站牌机场和地铁的指示牌给了微软设计团队灵感,设计团队说Metro是来源于美国华盛顿州金县都会交通局(K

安卓切换界面从顶部滑入,右侧滑入

安卓切换界面从顶部滑入: 我们用到了overridePendingTransition这个方法, 第一个参数指定启动的 activity进入的方式,第二个参数指定当前activity退出的方式 overridePendingTransition(R.anim.ani_top_get_into, R.anim.ani_bottom_sign_out); R.anim.ani_top_get_into文件: <translate xmlns:android="http://schemas.an

安卓学习-界面-View和GroupView

所有的界面元素都是继承与View(如:ImageView .Button等),布局继承于GroupView(如:LinearLayout等) view的主要属性,这里直接是xml配置里写了,当然直接通过代码也是可以的 XML属性 相关方法 说明 android:alpha setAlpha(float alpha) alpha值是从0~1的,比如0.5相当于透明50%,并且需要注意的是3.0以下版本没有这个属性,因此只要设置了就相当于不透明,3.0版本以下可以用过view.getBackgrou

安卓学习-界面-布局-LinearLayout

1.常用的xml属性 XML属性 相关方法 说明 android:baselineAligned setBaselineAligned 看不懂什么意思,这个是网上的解释 设置为False将阻止该布局管理器于他的子元素基线对其  android:divider setDividerDrawable(Drawable divider) LinearLayout好像没效果 设置垂直布局时2个按钮之间的分隔线 android:gravity setGravity 组件内部的对齐方式,有如下几种 top

安卓学习-界面-View的自定义

android的所有UI控件,都是基于View的,因此特意重点学习了下这个,为后面学习其他控件打下基础. http://www.360doc.com/content/14/0102/12/12050012_342019150.shtml 重新时常用覆盖的方法 package com.example.ddddddd; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rec

记一次打造黑客手机——安装安卓kali的经历

首先说下引起我打造黑客手机的兴趣的原因.那是一个月黑风高的夜晚J,在我即将入睡前,忽然看到手机的文件夹消息提醒那多了几个消息,于是点开一看,微信上有人发布消息了.出于无聊,就点开看了看……….当然这些都是编的J.具体过程早已模糊,能记得的就是当时闲得无聊,点开微信看了看,发现自己的关注里竟然有余弦,而且还有新消息,好奇心驱使我点开看了看.当看完一篇文章的时候心情激动不已,随即寻找下一篇文章.在寻找的过程中不经意间发现了<打造属于你自己的黑客手机>这篇文章,看完后浑身不舒服,总想找个机会试试,但

【FastDev4Android框架开发】打造QQ6.X最新版本侧滑界面效果(三十八)

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50253925 本文出自:[江清清的博客] (一).前言: 这两天QQ进行了重大更新(6.X)尤其在UI风格上面由之前的蓝色换成了白色居多了,侧滑效果也发生了一些变化,那我们今天来模仿实现一个QQ6.X版本的侧滑界面效果.今天我们还是采用神器ViewDragHelper来实现,之前我们以前基于ViewDragHelper的使用和打造QQ5.X效果了,基本使用方法可以点