1. 程式人生 > >Android Launcher分析和修改11——自定義分頁指示器(paged_view_indicator)

Android Launcher分析和修改11——自定義分頁指示器(paged_view_indicator)

  Android4.0的Launcher自帶了一個簡單的分頁指示器,就是Hotseat上面那個線段,這個本質上是一個ImageView利用.9.png圖片做,效果實在是不太美觀,用測試人員的話,太醜了。特別是搭配其他風格的圖示和背景,的確不好看。所以打算自己重新寫一個指示器。這個所謂的分頁指示器作用很簡單,就是告訴使用者介面有多少分屏,目前處於第幾分屏。當然目前也有一些Launcher增強了這個功能,只要滑動這些指示器就可以 快速滑動桌面。

  今天給大家講講如何自定義一個分頁指示器,並新增到Launcher裡面使用,滑動切換功能後續再講。預設的藍色分頁指示器~

(PS:新建的QQ群,有興趣可以加入一起討論:Android群:322599434)

1、自定義View

  為了實現自定義分頁指示器,需要先自定義一個View,這個也是為了後面可以方便增加其他功能進去,也不會打亂Launcher原來的程式碼邏輯。最後我選擇使用LinearLayout作為這個View的容器,過載LinearLayout來做這個分頁指示器。使用LinearLayout只要橫向排布這些頁面圖示就可以。

public class PageSlideIndicator extends LinearLayout
{
    private final static String TAG="OWL_PageIndicator";
    //控制元件頁面滑動,操作PagedView
PagedView mPagedView
=null; Context mContext; //其他頁面標識 Drawable mNormalDrawable; //當前頁面標識 Drawable mFocusDrawable; //總頁面數 int mTotalPage=0; //當前頁面 int mCurPageNum=0; //............... }

  上面是我定義的一個分頁指示器類,主要的屬性就是兩個Drawable,分別代表兩張不同的圖片,當前頁面和其他頁面的圖片。之所以直接定義Drawable是因為,其他頁面指示器的數量是不確定的,這裡直接把圖片Drawable儲存好,方便後面建立ImageView使用。當然你也可以直接載入ImageView,動態維護一個佇列,只是會比較耗資源。

  另外還有兩個比較重要的屬性,總頁面數和當前頁面的序號。這兩個屬性決定了分頁指示器需要顯示的數量和那個位置顯示當前的頁面指示器。這兩個屬性的資料,我們都可以通過PagedView類裡面獲取到。(新增這個頁面指示器需要對PagedView、Workspace、Launcher、AppsCustomizePagedView這些類有一定的瞭解)

  另外我還定義了一個PagedView的物件,這個是方便以後用來做滑動頁面時,需要呼叫PagedView的方法。滑動功能今天暫時不講,以後再說~

2、初始化分頁指示器

  public void reflashIndacitor(int curPage, int totalPage)
    {
        mTotalPage = totalPage;
        mCurPageNum = curPage;
        //清空容器的view物件
        this.removeAllViews();
        //新增分頁指示器
        for (int page = 0; page < mTotalPage; ++page) 
        {
       //View的屬性設定 LayoutParams layoutParams
= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); layoutParams.leftMargin=10; layoutParams.rightMargin=10;
       //新建ImageView,用來顯示分頁圖示 ImageView newPageImageView
= new ImageView(mContext);    //根據當前頁還是其他頁面設定對應圖示 if (page == mCurPageNum) { newPageImageView.setBackgroundDrawable(mFocusDrawable); } else { newPageImageView.setBackgroundDrawable(mNormalDrawable); } //把圖示新增到LinearLayout this.addView(newPageImageView, layoutParams); } }

  上面就是簡單的初始化過程,根據傳入的總頁面數和當前頁面號,設定相關圖片以及初始化LinearLayout。需要注意的是,上面的ImageView因為是動態建立的,所以需要使用LayoutParams類來設定相關的引數屬性。

3、資原始檔引用

  下面我們看看如何在XML配置檔案裡面使用我們新編寫的類,這裡只介面Workspace的配置。workspace和AllApp頁面裡面是不一樣的配置。因為兩個介面引用了不同的View配置,所以如果你想兩個介面都使用自定義的分頁指示器,需要分別配置使用。原理基本一致,這裡只介紹Workspace的配置。

<!--分頁指示器  OWL  -->
<com.android.launcher2.PageSlideIndicator
     android:id="@+id/workSpacePageIndicator" 
     android:layout_width="match_parent"  
     android:layout_height="wrap_content" 
     android:layout_marginBottom="153dp"
     android:layout_gravity="bottom"
     android:gravity="center_horizontal"
/> 

  上面是我在launcher.xml裡面引用我們剛剛編寫的分頁指示器。至於這個View的位置,可以根據你實際介面需要自行調整,我這裡是放到了hotseat上面。裡面配置的屬性沒有什麼特別,其實就是配置一個LinearLayout的屬性。

4、Launcher.java裡面初始化

//初始化頁面標識器 OWL
mPageSlideIndicator = (PageSlideIndicator)findViewById(R.id.workSpacePageIndicator);
mPageSlideIndicator.InitPageSlideIndicator(3, 1);
mPageSlideIndicator.setPageViewObject(mWorkspace);
mWorkspace.setPageIndicator(mPageSlideIndicator);

  接著我們在Launcher.java裡面初始化這個類,可能會有人問為什麼要在Launcher.java裡面初始化而不是在workspace裡面初始化,因為這個其實是使用了workspace裡面的資料。原因是因為我們的XML配置檔案是在launcher.xml檔案裡面引用的,我們需要找到對應的資源。初始化工作注意就是把頁面有多少頁和當前頁存放進去,我這裡設定了一個固定值,因為我workspace預設只有3頁,當前頁面是第2頁。這個你可以預設設定,也可以在載入介面完成後,獲取workspace的資料再設定。另外就是把這個PageSlideIndicator物件傳遞給workspace類裡面去,因為具體檢測頁面滑動切換都是在workspace裡面完成(準確來說是PagedView)。

5、檢測滑動切換頁面

  protected void onPageEndMoving() 
    {
        super.onPageEndMoving();
        if (isHardwareAccelerated()) 
        {
            updateChildrenLayersEnabled();
        } 
        else 
        {
            clearChildrenCache();
        }
        if (!mDragController.dragging()) 
        {
            if (LauncherApplication.isScreenLarge()) 
            {
                hideOutlines();
            }
        }
        mOverScrollMaxBackgroundAlpha = 0.0f;
        mOverScrollPageIndex = -1;
        if (mDelayedResizeRunnable != null) 
        {
            mDelayedResizeRunnable.run();
            mDelayedResizeRunnable = null;
        }
        //檢測頁面滑動完成,設定相關頁面切換
        mPageSlideIndicator.setCurrentPage(mCurrentPage, getPageCount());
    }

  然後把我們相關的頁面切換資料傳遞給PageSlideIndicator處理就可以了。如果對這些處理不瞭解的朋友,需要先了解Launcher裡面PagedView和workspace關係以及他們之間如何處理滑動切換頁面,這個我前面的文章已經分析過,有興趣可以查閱我前面的文章。

  還有一點就是,如果想做出比較炫的效果,可以在這裡加入動畫效果。例如淡入淡出的效果,使用者體驗會好一些。我這裡只是簡單講解如何實現自定義分頁指示器。

  另外還有一點需要注意的是,如果你的頁面是動態變化(例如AllAPP介面裡面)的,也就是說你的頁面數目是不固定的,需要檢測APP變化,並且監聽removeview等方法,然後動態修改你的頁面數目。ALlAPP介面裡面就需要監聽頁面數目的變化,因為這個是不確定的,會根據使用者安裝軟體數目動態變化。

6、後語

  回頭看看,這已經是第11篇有關Launcher分析和修改的文章,不過今天看了一下,發現我那些Launcher的文章,看的人很少o(╯□╰)o  ,不知道是我寫得太菜還是搞Launcher開發的人比較少。不管怎樣,這個系列會繼續寫下去。

系列文章:

Edited by mythou

相關推薦

Android Launcher分析修改11——定義指示器paged_view_indicator

  Android4.0的Launcher自帶了一個簡單的分頁指示器,就是Hotseat上面那個線段,這個本質上是一個ImageView利用.9.png圖片做,效果實在是不太美觀,用測試人員的話,太醜了。特別是搭配其他風格的圖示和背景,的確不好看。所以打算自己重新寫一個指示器。這個所謂的分頁指示器作用很簡單,

Android Launcher分析修改8——AllAPP介面拖拽元素PagedViewWithDraggableItems

  接著上一篇文章,繼續分析AllAPP列表介面。上一篇文章分析了所有應用列表的介面構成以及如何通過配置檔案修改屬性。今天主要是分析PagedViewWithDraggableItems類,因為在我們分析AppsCustomizePagedView之前,需要先了解PagedViewWithDraggableI

Android Launcher分析修改3 Launcher啟動初始化

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android Launcher分析修改1——Launcher預設介面配置default_workspace

//Edited by mythou // //傳入default_workspace檔案的資源ID和資料庫實力,把xml裡面資料解析,儲存到Launcher資料庫。返回總共解析了多少個標籤。 private int loadFavorites(SQLiteDatabase db, int workspa

Android Launcher分析修改13——實現Launcher編輯模式(1) 桌布更換

  已經很久沒更新Launcher系列文章,今天不分析原始碼,講講如何在Launcher裡面新增桌面設定的功能。目前很多第三方Launcher或者定製Rom都有簡單易用的桌面設定功能。例如小米MIUI的Launcher就有很豐富編輯功能。今天開始會講一下如何實現桌面編輯功能。網上對於實現Launcher一些編

Android Launcher分析修改2——Icon修改、介面佈局調整、桌布設定

<!-- Workspace cell size --> <dimen name="workspace_cell_width_land">88dp</dimen> <dimen name="workspace_cell_width_port">

Android Launcher分析修改7——AllApp全部應用列表(AppsCustomizeTabHost)

  今天主要是分析一下Launcher裡面的所有應用列表。Android4.0 Launcher的所有應用列表跟2.X比較大的區別就是多了Widget的顯示。下面會詳細分析Launcher裡面有關所有應用列表配置和程式碼分析。   1、AllApp列表配置檔案 配置AllAPP應用列表介面的配置檔案

Android Launcher分析修改6——頁面滑動(PagedView)

public boolean onTouchEvent(MotionEvent ev) { if(OWL_DEBUG) Log.d(OWL, "onTouchEvent entering..");      //........switch (action &

Android Launcher分析修改10——HotSeat深入進階

  void addInScreen(View child, long container, int screen, int x, int y, int spanX, int spanY, boolean insert) { if(OWLLaunche

Android Launcher分析修改9——Launcher啟動APP流程

  本來想分析AppsCustomizePagedView類,不過今天突然接到一個臨時任務。客戶反饋說機器介面的圖示很難點選啟動程式,經常點選了沒有反應,Boss說要優先解決這問題。沒辦法,只能看看是怎麼回事。今天分析一下Launcher啟動APP的過程。從使用者點選到程式啟動的流程,下面針對WorkSpac

Android Launcher分析修改5——HotSeat分析

void resetLayout() {    //清空原來的內容 mContent.removeAllViewsInLayout(); //新增AllAPP按鈕,也是一個BubbleTextView物件 Context context = g

Android Launcher分析修改4——初始化載入資料

private void bindWorkspace() {       //通知Launcher開始繫結資料 mHandler.post(new Runnable() { public void run() {

Android Launcher分析修改3——Launcher啟動初始化

@Override protected void onCreate(Bundle savedInstanceState)   { super.onCreate(savedInstanceState); //獲取Application 例項 La

Android Launcher分析修改12——Widget列表資訊收集

public void syncWidgetPageItems(final int page, final boolean immediate) { int numItemsPerPage = mWidgetCountX * mWidgetCountY; //

cookiesession以及定義

cookie值 無法 解析 link try render 強制 raise 需求 cookie Cookie的由來 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直

django 1.11 定義功能的實現

在WEB中很多時候是免不了要分頁的,如果我們的資料太多了,分出來6000多頁或者更多的時候,用django自帶的分頁功能就不好看了,所以我們來自定義一下。我是參考http://www.cnblogs.com/nulige/p/6558207.html這篇文章的,不過如果照著

【朝花夕拾】Android定義View篇之Android事件分發機制從原始碼分析事件分發邏輯及經常遇到的一些“詭異”現象

前言        轉載請註明,轉自【https://www.cnblogs.com/andy-songwei/p/11039252.html】謝謝!        在上一篇文章【【朝花夕拾】Android自定義View篇之(

laravel 定義 offset limit 的使用

有一個 信息 代碼 自定義 快速 技術 多少 信息技術 只需要 laravel 本身有一個自帶的快速分頁方法 paginate,只需要傳入每頁顯示多少條數據就可以 了,但是如果想使用自定義從哪裏開始呢,這時候就可以使用offset 和 limit 的組合,offset 設置

Cookie、Session定義

cookie值 image 分享 show base 新的 ive name pen cookie Cookie的由來 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直

Python cookie、session定義

參數 dom backend 一個 文本 per iter none 不知道 cookie Cookie的由來 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直接影響,