博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  Android4.0的Launcher自带了一个简单的分页指示器,就是Hotseat上面那个线段,这个本质上是一个ImageView利用.9.png图片做,效果实在是不太美观,用测试人员的话,太丑了。特别是搭配其他风格的图标和背景,的确不好看。所以打算自己重新写一个指示器。这个所谓的分页指示器作用很简单,就是告诉用户界面有多少分屏,目前处于第几分屏。当然目前也有一些Launcher增强了这个功能,只要滑动这些指示器就可以 快速滑动桌面。

  今天给大家讲讲如何自定义一个分页指示器,并添加到Launcher里面使用,滑动切换功能后续再讲。默认的蓝色分页指示器~

(PS:新建的QQ群,有兴趣可以加入一起讨论:Android群:322599434)

 

1、自定义View

  为了实现自定义分页指示器,需要先自定义一个View,这个也是为了后面可以方便增加其他功能进去,也不会打乱Launcher原来的代码逻辑。最后我选择使用LinearLayout作为这个View的容器,重载LinearLayout来做这个分页指示器。使用LinearLayout只要横向排布这些页面图标就可以。


//Edited by mythou
//http://www.cnblogs.com/mythou/
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、初始化分页指示器

//Edited by mythou
//http://www.cnblogs.com/mythou/
  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的配置。


//Edited by mythou
//http://www.cnblogs.com/mythou/
<!--分页指示器  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里面初始化


//Edited by mythou
//http://www.cnblogs.com/mythou/
//初始化页面标识器 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、检测滑动切换页面

    
//Edited by mythou
//http://www.cnblogs.com/mythou/
  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开发的人比较少。不管怎样,这个系列会继续写下去。

 

系列文章:

Android Launcher分析和修改1——Launcher默认界面配置(default_workspace)

Android Launcher分析和修改2——Icon修改、界面布局调整、壁纸设置

Android Launcher分析和修改3——Launcher启动和初始化

Android Launcher分析和修改4——初始化加载数据

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

Android Launcher分析和修改6——页面滑动(PagedView

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

Android Launcher分析和修改8——AllAPP界面拖拽元素(PagedViewWithDraggableItems)

Android Launcher分析和修改9——Launcher启动APP流程

Android Launcher分析和修改10——HotSeat深入进阶

 

Edited by mythou

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3231000.html