日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Metro风格的Launcher开发系列第三篇

發布時間:2023/12/18 Android 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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是這樣實現的:



[java] view plaincopyprint?
  • 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;??
  • ????}??
  • ??
  • }??
  • public class LauncherAdapter extends PagerAdapter {private ArrayList<PageViewItem> mViews;public LauncherAdapter(ArrayList<PageViewItem> views) {mViews = views;}@Overridepublic void destroyItem(View arg0, int arg1, Object arg2) {((ViewPager) arg0).removeView(mViews.get(arg1));}@Overridepublic void finishUpdate(View arg0) {}@Overridepublic int getCount() {if (mViews != null) {return mViews.size();}return 0;}public View getCurrentView(int currentID) {return mViews.get(currentID);}@Overridepublic Object instantiateItem(View arg0, int arg1) {((ViewPager) arg0).addView(mViews.get(arg1));return mViews.get(arg1);}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return (arg0 == arg1);}@Overridepublic void restoreState(Parcelable arg0, ClassLoader arg1) {}@Overridepublic 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()方法獲取的,具體動畫實現如下:

    [java] view plaincopyprint?
  • mPropertyAnimator.scaleX((width?+?mScaleX)?/?width)??
  • ???????????????????????.scaleY((height?+?mScaleY)?/?height).setDuration(duration)??
  • ???????????????????????.setInterpolator(new?DecelerateInterpolator())??
  • ???????????????????????.start();??
  • mPropertyAnimator.scaleX((width + mScaleX) / width).scaleY((height + mScaleY) / height).setDuration(duration).setInterpolator(new DecelerateInterpolator()).start();

    2、在xml文件靈活配置一些CellView的屬性,比如點擊打開的應用,呈現的ICON獲取地址,焦點x、y的放大值等,CellView對應的屬性定義attrs.xml文件如下:

    [html] view plaincopyprint?
  • <?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>??
  • <?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开发系列第三篇的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。