`
飞扬云
  • 浏览: 151928 次
  • 来自: 深圳
社区版块
存档分类
最新评论

Android 2.2的锁屏界面修改

阅读更多

 

 

Android 2.2的锁屏界面如图1所示,左右两侧是2个滑动条,正常状态下左边的是解锁,右边的是声音的开关,来电话时,左边是接听电话的解锁,右边是不接听来电的解锁。




图1

图1

当我们滑动解锁按钮时,右边会有一个绿色目标点,当滑动左边的解锁按钮到达右边的目标点时,解锁就成功了,然后就能够操作主界面了。如图2所示。


图2


问题:每次向右滑动解锁按钮时,都滑动的很远,也就是说,右边的那个绿色目标点很远,有些不太方便,那能否将这个点向左边移动一些呢?这样滑动的距离就少一些,如图3所示。


图3


答案:我们可以修改2.2源码中有关锁屏界面的部分代码就可以实现这个绿色的目标点左移了,而且解锁按钮滑动距离会变的很短,同时还可以把这个按钮做成透明的只显示一个按钮,不显示那个滑动条bar。


如何修改呢?

方法:

1) 锁屏界面主要有2个java文件、2个xml文件和一些图片文件。


frameworks/base/core/java/com/android/internal/widget/SlidingTab.java

frameworks/base/policy/src/com/android/internal/policy/impl/LockScreen.java

frameworks/base/core/res/res/layout/keyguard_screen_tab_unlock_.xml

frameworks/base/core/res/res/layout/keyguard_screen_tab_unlock_land.xml


2) 在SlidingTab.java文件中,可以使得滑动条向右移动的近一点,同时可以使得绿色的目标点向左移动;

3) 在LockScreen.java文件中,可以使得滑动条的颜色和背景图片换成定制的,也可以使得绿色的目标点变成定制的图片;

4) keyguard_screen_tab_unlock_.xml是竖屏的锁屏界面布局文件,keyguard_screen_tab_unlock_land.xml是横屏的锁屏界面布局文件。可以在此修改数字时钟、日期和时间、充电的图标显示等的布局、大小、边距等;


具体代码分析和修改步骤:


1. SlidingTab.java

首先我们看到这个类是继承android.view.ViewGroup的,说明这个类是一个布局类的java文件。再打开keyguard_screen_tab_unlock_.xml 或者 keyguard_screen_tab_unlock_land.xml 文件会发现里面有一个标签元素:

    <com.android.internal.widget.SlidingTab
        android:id="@+id/tab_selector"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginRight="80dip"
        />

从这里我们可以看出,其实这个标签元素正好对应一个布局。平时我们都是使用

<RelativeLayout

……>

……

</RelativeLayout>

这样的标签来表示一个布局,而在此处我们却使用了一个java类文件来表示这个布局,这就很有意思了。其实这个含义很明显:利用java类文件实现布局比用纯粹的标签更加灵活,会实现很多标签无法首先的功能。

理解上面一点之后,再看看这个SlidingTab.java文件,里面定义了一个内部类:private static class Slider。

这个Slider包含了三个子对象:tab、text、target。

tab:这个tab就是在默认情况下显示的那个滑动条,如图4所示:

图4

 

text:当拖动左边的滑动条时,会出现“Unlock”文本,就是这个text。如图5所示。

 

 

图5

 

target: 当触摸到这个滑动条时,左、右边会各有一个点,就是目标点target,他起到一个临界指示作用,每次拖动滑动条达到这个临界点时就会触发解锁事件,解锁结束后就可以使用主界面了。如图6所示。要注意的是:这个目标点只是起到临界指示作用,没有别的含义。真正的临界点时看不见的,为了起到一个视觉的认识,在这里就使用这样一个目标点来代表临界点,下面会在代码中解释真正的临界点在哪里。

 

 

图6

 

在这个Slider内部类中有一个布局方法:void layout(int l, int t, int r, int b, int alignment)

 

核心代码是:

 

 

      if (alignment == ALIGN_LEFT || alignment == ALIGN_RIGHT) {

                // horizontal

             Log.i(TAG,"Is this horizontal ?");

                final int targetTop = (parentHeight - targetHeight) / 2;

                final int targetBottom = targetTop + targetHeight;

                final int top = (parentHeight - handleHeight) / 2;

                final int bottom = (parentHeight + handleHeight) / 2;

                if (alignment == ALIGN_LEFT) {

                Log.i(TAG,"Is this leftBar? ");

                // modified by zhuluofeng 2011-11-15

                // 0 to 0+50,leftTarget to leftTarget+500

                    tab.layout(0, top, handleWidth, bottom);

                    text.layout(0 - parentWidth, top, 0, bottom);

                    text.setGravity(Gravity.RIGHT);

                    target.layout(leftTarget, targetTop, leftTarget + targetWidth, targetBottom);

                    Log.i(TAG,"targetTop is: " + targetTop);

                    Log.i(TAG,"targetBottom is: " + targetBottom);

                    alignment_value = l;

                } else {

                Log.i(TAG,"Is this RightBar?");

                    tab.layout(parentWidth - handleWidth, top, parentWidth, bottom);

                    text.layout(parentWidth, top, parentWidth + parentWidth, bottom);

                    target.layout(rightTarget, targetTop, rightTarget + targetWidth, targetBottom);

                    text.setGravity(Gravity.TOP);

                    alignment_value = r;

                }

            } else {

                // vertical

                Log.i(TAG,"Is this vertical ?");

                final int targetLeft = (parentWidth - targetWidth) / 2;

                final int targetRight = (parentWidth + targetWidth) / 2;

                final int top = (int) (THRESHOLD * parentHeight) + handleHeight / 2 - targetHeight;

                final int bottom = (int) ((1.0f - THRESHOLD) * parentHeight) - handleHeight / 2;

                if (alignment == ALIGN_TOP) {

                Log.i(TAG,"Is this TopBar ?");

                    tab.layout(left, 0, right, handleHeight);

                    text.layout(left, 0 - parentHeight, right, 0);

                    target.layout(targetLeft, top, targetRight, top + targetHeight);

                    alignment_value = t;

                } else {

                Log.i(TAG,"Is this BottomBar ?");

// modified by zhuluofeng 2011-11-15

// bottom to bottom+500, parentHeight - handleHeight to parentHeight - handleHeight-50

// the bottom is the right side 

                    tab.layout(left, parentHeight - handleHeight, right, parentHeight);

                    text.layout(left, parentHeight, right, parentHeight + parentHeight);

                    target.layout(targetLeft, bottom, targetRight, bottom + targetHeight);

                    Log.i(TAG,"the vertical bottom is: " + bottom);

                    Log.i(TAG,"the vertical targetHeight is: " + targetHeight);

                    alignment_value = b;

                }

            }

 

 

这段代码其实就一个if else控制语句,if (alignment == ALIGN_LEFT || alignment == ALIGN_RIGHT) 表示:

 

手机处在竖屏时(即滑动条处在水平方向),如果拖动左边的滑动条或者拖动右边的滑动条时的处理方法。

 

else中的代码表示手机处于横屏时(即滑动条处在竖直方向),如果拖动下面的滑动条或者拖动上面的滑动条的处理方法。

 

在大的if语句中包含了一个if else语句,if表示的是左边的滑动条,else就是右边的滑动条;在大得else语句中也包含了一个if else语句,if表示的是竖直方向的上面的滑动条,else表示的是竖直方向的下面的滑动条。

 

理解了这一点就很容易定位到具体的滑动条的代码了。

 

先修改当手机处在竖直方向时(即滑动条处在水平方向)左边的解锁滑动条的距离,目标点的距离。

 

a) 将左边的滑动条tab向右边移动下

 

看上面紫红颜色的代码,将andleWidth加上一个数值即可,比如我们加上50变成:

 

tab.layout(0, top, handleWidth + 50, bottom);

 

那这几个参数是什么意思呢?

 

 tab和target是ImageView对象,layout方法是继承android.view.View类,此方法表示给某个view进行布局,官网解释:

public void layout (int l, int t, int r, int b)

Since: API Level 1

Assign a size and position to a view and all of its descendants

This is the second phase of the layout mechanism. (The first is measuring). In this phase, each parent calls layout on all of its children to position them. This is typically done using the child measurements that were stored in the measure pass().

Derived classes should not override this method. Derived classes with children should override onLayout. In that method, they should call layout on each of their children.

 

Parameters
l t r b
Left position, relative to parent
Top position, relative to parent
Right position, relative to parent

Bottom position, relative to parent

 

 

 

由此可知,四个参数分别表示当前view相对于父视图的左、上、右、下的距离。

根据此可知,为了将tab向右移动一些距离,那可以将tab向右的距离增加一个数字即可,如下:

tab.layout(0, top, handleWidth + 50, bottom);     //  这里加上了50,那么tab将会向右移动50个dp

按此推理,可以将target即目标点向左移动,如下:

target.layout(leftTarget, targetTop, leftTarget + targetWidth - 500, targetBottom);  // 将向右的参数向减去500dp即表示向右的距离变少,那么目标点就会向左移动。

上面代码蓝色表示水平放置手机时(即滑动条处于垂直方向)的左边的tab的布局。青绿色的代码表示水平放置手机时(即滑动条处于垂直方向)的target的布局。

可以修改成:

tab.layout(left, parentHeight - handleHeight-50, right, parentHeight);  // 减去50,表明将相对于父视图的top长度减少一个数值,这样tab的距离就会向下移动,就会变短。

target.layout(targetLeft, bottom+500, targetRight, bottom + targetHeight);  // 加上500,表明将相对于父视图的top长度增加一个数值,这样target的距离就会向下移动,就会变短。

这里要注意,一会加上一个距离,一会减去一个距离,这时为什么?因为各个参数在layout里面表示的含义不一样,要具体看待,千万不能看这个参数的中文含义,比如说,你看到bottom+500,好像以为把底部的距离加上了500,那怎么看都想不通,都不是对的。所以要把参数带到具体的代码中去看,千万不能看这个单词的中文含义,容易迷惑,这一点我非常反感google,你可以把某个方法的名字起一个比较让人一看就懂这个方法是干什么的,但是不能把某个参数随便起名,容易迷惑。



修改保存后编译运行,发现target确实向左移动了,拖动滑动条开始解锁,这时发现可以解锁,但是解锁的临界点和target的位置不对应,那么如何解决?答:应该再减少拖动的距离,使得拖动一段距离后,正好和target相遇,此时正好解锁。如何修改?在SlidingTab类中还有一个方法:

    public boolean onTouchEvent(MotionEvent event) {
        if (mTracking) {
            final int action = event.getAction();
            final float x = event.getX();
            final float y = event.getY();

            switch (action) {
                case MotionEvent.ACTION_MOVE:
                    if (withinView(x, y, this) ) {
                        moveHandle(x, y);
                        float position = isHorizontal() ? x : y;
                        float target = mThreshold * (isHorizontal() ? getWidth() : getHeight());
                        boolean thresholdReached;
                        if (isHorizontal()) {
                            thresholdReached = mCurrentSlider == mLeftSlider ?
                                    position > target : position < target;
                        } else {
                             //xiehua
                            thresholdReached = mCurrentSlider == mLeftSlider ?
                                    position < target : position > target;
                        }
                        if (!mTriggered && thresholdReached) {
                            mTriggered = true;
                            mTracking = false;
                            mCurrentSlider.setState(Slider.STATE_ACTIVE);
                            boolean isLeft = mCurrentSlider == mLeftSlider;
                            dispatchTriggerEvent(isLeft ?
                                OnTriggerListener.LEFT_HANDLE : OnTriggerListener.RIGHT_HANDLE);

                            startAnimating(isLeft ? mHoldLeftOnTransition : mHoldRightOnTransition);
                            setGrabbedState(OnTriggerListener.NO_HANDLE);
                        }
                        break;
                    }
                    // Intentionally fall through - we're outside tracking rectangle

                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mTracking = false;
                    mTriggered = false;
                    mOtherSlider.show(true);
                    mCurrentSlider.reset(false);
                    mCurrentSlider.hideTarget();
                    mCurrentSlider = null;
                    mOtherSlider = null;
                    setGrabbedState(OnTriggerListener.NO_HANDLE);
                    break;
            }
        }

        return mTracking || super.onTouchEvent(event);
    }


最重要的是紫红色的代码(如上),他表示的含义是:

如果isHorizontal()返回为真,表示滑动条处于水平方向(注意,千万不能认为是手机处于水平方向,这一点很容易迷惑,很鄙视google,源代码也不叫上一个注释,害的我被迷惑了好几天)。

代码中得position表示滑动条移动的距离,position等于event.getX()。这时滑动条处在水平方向,为了减少滑动条向右解锁时移动的距离,那么就可以把position加上一个数值即可,那么加上一个多大的数值呢?这里为了使得解锁的临界点和target的位置在一个点上,必须满足一个等式:position = (500-50)/2 即position=225,为什么会这样呢?这个地方其实就是几何图形的长宽高的数值计算,target向左移动500,tab向右移动50,就等于target向左移动450,这时tab向右移动的距离大概等于450的一半,具体为什么是这样,其实我也是有点模糊,这个数值也是根据自己多次试验出来的,因为源代码中出现了很多有关长宽高的变量,没有注释,一时还真得难看懂,但这些数值试验后是正确的,所以大概推算就是这样的计算公式了(如果有非常了解的,还请告诉我一声)。

当手机处于垂直方向时,其实也是一个道理,加上和减去的数值都是一样的。

修改后的代码如下:


 if (isHorizontal()) {
                            thresholdReached = mCurrentSlider == mLeftSlider ?
                                    position + 225 > target : position < target;
                        } else {
                             //xiehua
                            thresholdReached = mCurrentSlider == mLeftSlider ?
                                    position-225 < target : position > target;
                        }



注意上面,一个是加上225,一个是减去225,为什么?这个需要把数值带到具体代码中去看,同时需要画一个图形来看就清楚了。千万从变量的中文含义去理解,那就很容易迷惑。


至此,关于这个锁屏的修改基本上结束了。

关于锁屏还有其他的修改,比如把tab变成透明的,这个其实很简单,只要把tab的图片全部换成透明的就行了。

其他的修改还包括数字时钟、上下午时间显示等等,这些都是直接在下面的两个xml文件中修改:

frameworks/base/core/res/res/layout/keyguard_screen_tab_unlock_.xml

frameworks/base/core/res/res/layout/keyguard_screen_tab_unlock_land.xml

这个修改不再详述。











3
5
分享到:
评论
8 楼 ritterliu 2012-07-30  
您好,这个问题麻烦您看下
http://topic.csdn.net/u/20120730/15/8d3dacf2-7196-4e5e-a325-0e16a87208f6.html
7 楼 lnb333666 2012-05-16  
不知道飞扬兄可否有空,可否加QQ339579300联系,想向您请教些问题,指点迷津
6 楼 飞扬云 2012-05-15  
black_smart 写道
飞扬云 写道
black_smart 写道
飞扬兄,你好! 我现在也在做锁屏这块工作,有一些问题想请教,能方便留个联系方式吗? 或者加我qq也行:120576641 谢谢!~


我现在已经不在做UI这一块了,不过可以讨论,交流,谢谢。。。


我现在 需要做一个仿htc的滑动锁屏界面,由于刚接触不久 ,也没有很好的思路,能否指点一二呢?(直接在framework里面修改的话感觉改动挺大的,而且不知道怎样去实现)


:)
一般来说,源码那么大,全面掌握太难,我这里基本上就是在做项目中熟悉基本架构,然后学会使用grep find命令去搜索,这样就很容易定位到某个文件。比如:如果你看到某个图片,先可以在目录下查找,找到后,可以通过这个图片得名子去搜索和这个图片相关的文件。你查看多了,自然就会了解目录结构了。一般来说,图片和各种在资源在framework以及package下面的res里面。好了,这也是我大概学习的过程,仅供参考。你多和你同事沟通,时间长了,肯定有自己的方法。。。如果有好的方法,还请提供一下,互相学习。。。
5 楼 black_smart 2012-05-07  
飞扬云 写道
black_smart 写道
飞扬兄,你好! 我现在也在做锁屏这块工作,有一些问题想请教,能方便留个联系方式吗? 或者加我qq也行:120576641 谢谢!~


我现在已经不在做UI这一块了,不过可以讨论,交流,谢谢。。。


我现在 需要做一个仿htc的滑动锁屏界面,由于刚接触不久 ,也没有很好的思路,能否指点一二呢?(直接在framework里面修改的话感觉改动挺大的,而且不知道怎样去实现)
4 楼 飞扬云 2012-04-27  
black_smart 写道
飞扬兄,你好! 我现在也在做锁屏这块工作,有一些问题想请教,能方便留个联系方式吗? 或者加我qq也行:120576641 谢谢!~


我现在已经不在做UI这一块了,不过可以讨论,交流,谢谢。。。
3 楼 black_smart 2012-04-23  
飞扬兄,你好! 我现在也在做锁屏这块工作,有一些问题想请教,能方便留个联系方式吗? 或者加我qq也行:120576641 谢谢!~
2 楼 烧伤的火柴 2012-04-13  
好文章  谢谢了
1 楼 sultrychen 2012-02-24  
很不错的文章。学习了

相关推荐

    Android2.2通讯录源码

    首先,我们要明白Android 2.2的通讯录系统是由多个组件组成的,包括数据库管理、UI界面、服务以及广播接收器等。主要涉及以下几个关键知识点: 1. **Content Provider**:通讯录数据存储的核心组件,它提供了一个...

    Android13 锁屏界面禁止下拉状态栏.patch

    Android13 锁屏界面禁止下拉状态栏.patch

    android-2.2源码

    9. **UI改进**:在用户界面方面,Android 2.2做了许多细节调整,使操作更加直观,用户体验得到提升。例如,改进了通知中心的设计,增加了动态壁纸等个性化设置。 10. **开发者工具**:Android 2.2源码还包括了...

    android2.2 adb工具

    在“android2.2 adb工具”这个主题下,我们主要关注的是适用于Android 2.2(Froyo)版本的ADB工具及其相关功能。 ### ADB简介 ADB全称为Android Debug Bridge,它是Google提供的一个开发工具套件的一部分,主要用于...

    Android 2.2 API 中文文档

    Android 2.2 API,又称为Froyo(冻酸奶),是Android操作系统的一个重要版本,为开发者提供了丰富的功能和改进,旨在提升应用性能和用户体验。本文将深入探讨Android 2.2 API的关键特性、更新以及如何利用这些知识来...

    android 2.2 源代码

    - **自定义修改**:开发者可以根据需求修改系统源码,创建自己的Android ROM或添加特定功能。 - **性能优化**:源码分析有助于找出性能瓶颈并进行优化,提高应用运行效率。 - **学习编程技巧**:Android的源码中充满...

    Android 2.2下能用的SwitchButton

    标题提到的"Android 2.2下能用的SwitchButton"是指在Android 2.2(API级别8)这个较旧的版本上,开发者通常无法直接使用原生的Switch控件,因为Switch是在Android 4.0(API级别14)及以上版本引入的。描述中提到的...

    Android2.2 ApiDemos

    《Android 2.2 ApiDemos深度解析》 在Android开发领域,ApiDemos是一个非常重要的参考资料,它是由Google官方提供的一个示例程序,包含了Android SDK中的各种API功能的演示。这个项目,针对的是Android 2.2(API...

    Android 2.2 API中文文档合集

    Android 2.2 API中文文档合集是一份极其宝贵的资源,尤其对于正在学习或从事Android应用开发的人员来说。这份文档集合包含了Android 2.2(API级别8)及部分2.3(API级别9)的详细中文翻译,旨在帮助开发者理解和使用...

    android2.2源码下载

    在Android操作系统的发展历程中,Android 2.2(Froyo)是一个重要的里程碑,它带来了许多性能提升和新功能。本文将深入探讨Android 2.2源码的相关知识点,包括其下载、解压、编译以及如何利用这些源码进行学习和开发...

    Android 2.2 源码

    通过分析和研究Android 2.2源码,开发者不仅可以了解Android系统的底层运作,还能发现性能瓶颈,优化应用程序,或是开发出独特的系统修改和扩展。源码学习是Android开发者进阶的必经之路,也是提升自身技能的有效...

    android 2.2 源码

    《Android 2.2 源码解析与深入理解》 Android 2.2,代号Froyo(冻酸奶),是Google推出的一款重要的移动操作系统版本。它在2010年发布,带来了诸多性能提升和新功能,为开发者提供了更丰富的API和工具。源码的开放...

    Android 2.2 开发环境配置详解(最新出炉)

    【Android 2.2 开发环境配置详解】 随着Google在2010年Google I/O大会上发布了Android 2.2(代号Froyo),开发者们迎来了一个性能大幅提升的新版本。Froyo不仅引入了对Flash 10.1的支持,还对系统界面和功能进行了...

    android2.2 录音程序完整源码

    针对"android2.2 录音程序完整源码"这个主题,我们将深入探讨Android 2.2(Froyo)版本下的录音API,以及如何实现一个简单的录音应用。这段源码为初学者提供了实践和理解Android录音机制的良好机会。 Android录音...

    android2.2中文排序data包

    在Android系统中,排序和文本处理对于用户界面的本地化和国际化是非常关键的。这个"android2.2中文排序data包"显然与Android 2.2版本中的中文字符排序功能有关,它涉及到Android如何处理中文字符的顺序,这对于构建...

    android 2.2 source api 8

    在这个压缩包中,包含的是Android 2.2的源代码,这对于开发者来说是一个宝贵的资源,可以深入理解系统的内部工作原理,进行自定义修改,或者对Android应用程序进行更底层的优化。 一、Android 2.2的特性与改进 1. *...

    android锁屏界面显示,仿播放器。

    在Android平台上,创建一个仿播放器的锁屏界面可以为用户提供独特的交互体验,尤其是在音乐播放、视频观看等场景下。本项目"LockScreenDemo"旨在教你如何实现这一功能,使用的是Android Studio作为开发工具。 首先...

    android2.2sdk2共2个

    android2.2sdk1共2个 android2.2sdk1共2个android2.2sdk1共2个

    Android 2.2 API 中文版

    《Android 2.2 API 中文版》是一个针对Android开发者的重要资源,它提供了全面的、中文解释的Android 2.2版本的应用程序接口(API)文档。这份文档对于那些使用这个平台进行移动应用开发的专业人士来说,无疑是一份...

    android 2.2 源码下载 学习必备

    Android 2.2(Froyo)源码学习是Android开发者深入理解系统工作原理和优化应用性能的关键步骤。源码提供了对操作系统内核、库、框架以及用户界面等所有层次的详细视图,使得开发者能够从底层到高层全面了解Android...

Global site tag (gtag.js) - Google Analytics