Android系统锁屏修改时钟KeyguardClockSwitch布局边距

statusbar状态栏的相关ui嵌套简单说明梳理下:
父布局
/frameworks/base/packages/SystemUI/res/layout/super_notification_shade.xml
滑动布局相关控制父布局
/frameworks/base/packages/SystemUI/res/layout/status_bar_expanded.xml
用户状态、时钟、日期等布局
/frameworks/base/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
时钟布局
/pep/frameworks/base/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
日期等布局
/pep/frameworks/base/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
需求说明
当设备屏幕较小时例如穿戴手表设备,屏幕上要显示较大的钟表ui但是依然套用系统的锁屏系统,就需要给时钟ui扩展下空间,这里的核心是删除不必要的元素ui,以及缩减padding、margin。
隐藏:keyguard_status_area.xml
其他的位置的话看需求修改,这里重点关注keyguard_clock_switch.xml中的android:id="@+id/clock_view",刚开始只是单纯增加长宽大小,但是很局限只有整块屏蔽的上半部分显示,若是高度设置过大,还会出现时钟ui不显示的问题(目前大概推测是因为ui高度过大,在整个滑动逻辑中部分判断逻辑直接影藏了这个keyguard_status_view.xml,未证实)。
通过测试整个时钟刷新流程发现了,关于keyguard_status_view.xml的ui,也就是com.android.keyguard.KeyguardStatusView这个类设置了最低margin值,导致只能在屏幕上半部分展示:/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java中的getExpandedClockPosition()方法

/**
     * Vertically align the clock and the shade in the available space considering only
     * a percentage of the clock height defined by {@code CLOCK_HEIGHT_WEIGHT}.
     * @return Clock Y in pixels.
     */
    public int getExpandedClockPosition() {
        final int availableHeight = mMaxShadeBottom - mMinTopMargin;
        final int containerCenter = mMinTopMargin + availableHeight / 2;

        float y = containerCenter - mKeyguardStatusHeight * CLOCK_HEIGHT_WEIGHT
                - mClockNotificationsMargin - mNotificationStackHeight / 2;
        if (y < mMinTopMargin) {
            y = mMinTopMargin;
        }

        // Don't allow the clock base to be under half of the screen
        final float maxClockY = getMaxClockY();
        if (y > maxClockY) {
            y = maxClockY;
        }
//************重点修改部分:直接给y赋值,我这里使用的是keyguardClockTopMargin=res.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);***********************************
        y=keyguardClockTopMargin;
        return (int) y;
    }
//把最大高度修改为mHeight 而不是mHeight/2
 private int getMaxClockY() {
        return mHeight  - mKeyguardStatusHeight - mClockNotificationsMargin;
    }

修改这两个部分后,就可以去重新修改keyguard_clock_switch.xml下面id:clock_view长宽布局大小了
上述就是解决时钟ui全屏显示的方法供参考。
下面分析下系统如何进行限制KeyguardStatusView只在屏幕上半部分展示的流程:
提示:写这部分时,代码逻辑有些忘了,只说下大概设计到的逻辑,具体的话自己打log测试下吧
KeyguardStatusView在这个类中加载:/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java

//该方法中设计到对KeyguardStatusView的长宽、动画一些绑定执行
    private void positionClockAndNotifications() {
        boolean animate = mNotificationStackScroller.isAddOrRemoveAnimationPending();
        boolean animateClock = animate || mAnimateNextPositionUpdate;
        int stackScrollerPadding;
        if (mBarState != StatusBarState.KEYGUARD) {
            stackScrollerPadding = getUnlockedStackScrollerPadding();
        } else {
            int totalHeight = mView.getHeight();
            int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
            int clockPreferredY = mKeyguardStatusView.getClockPreferredY(totalHeight);
            boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
            final boolean
                    hasVisibleNotifications =
                    !bypassEnabled && mNotificationStackScroller.getVisibleNotificationCount() != 0;
            mKeyguardStatusView.setHasVisibleNotifications(hasVisibleNotifications);
//涉及ui的长宽以及位置,相关重点第七个参数clockPreferredY数据计算
            mClockPositionAlgorithm.setup(mStatusBarMinHeight, totalHeight - bottomPadding,
                    mNotificationStackScroller.getIntrinsicContentHeight(), getExpandedFraction(),
                    totalHeight, (int) (mKeyguardStatusView.getHeight() - mShelfHeight / 2.0f
                            - mDarkIconSize / 2.0f), clockPreferredY, hasCustomClock(),
                    hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
                    bypassEnabled, getUnlockedStackScrollerPadding());
//数据赋值执行
            mClockPositionAlgorithm.run(mClockPositionResult);
            PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X,
                    mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
//Y坐标动画展示,以及在手动上滑锁屏屏幕时,上移KeyguardStatusView动画
            PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.Y,
                    mClockPositionResult.clockY, CLOCK_ANIMATION_PROPERTIES, animateClock);
            updateNotificationTranslucency();
            updateClock();
            stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;
        }
        mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
        mKeyguardBottomArea.setAntiBurnInOffsetX(mClockPositionResult.clockX);

        mStackScrollerMeasuringPass++;
        requestScrollerTopPaddingUpdate(animate);
        mStackScrollerMeasuringPass = 0;
        mAnimateNextPositionUpdate = false;
    }

动画相关类/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
public static <T extends View> void setProperty(final T view,
            AnimatableProperty animatableProperty, float newEndValue,
            AnimationProperties properties, boolean animated) {
        int animatorTag = animatableProperty.getAnimatorTag();
        ValueAnimator previousAnimator = ViewState.getChildTag(view, animatorTag);
        if (previousAnimator != null || animated) {
            startAnimation(view, animatableProperty, newEndValue, animated ? properties : null);
        } else {
//走的是这个方法
            // no new animation needed, let's just apply the value
            animatableProperty.getProperty().set(view, newEndValue);
        }
    }

。。。。。。
具体的下次一定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安卓APP访问CAN有如下报错05-16 18:09:54.015 8022 8022 D can_test: nCanFd = 67 05-16 18:09:54.015 8022 8022 D can_test: Send can_id 05-16 18:09:54.013 8022 8022 I com.bin.cantest: type=1400 audit(0.0:444): avc: denied { ioctl } for path="socket:[114169]" dev="sockfs" ino=114169 ioctlcmd=0x8933 scontext=u:r:system_app:s0 tcontext=u:r:system_app:s0 tclass=can_socket permissive=1 05-16 18:09:54.015 8022 8022 D can_test: Send Error frame[0] 05-16 18:09:54.013 8022 8022 I com.bin.cantest: type=1400 audit(0.0:445): avc: denied { bind } for scontext=u:r:system_app:s0 tcontext=u:r:system_app:s0 tclass=can_socket permissive=1 05-16 18:09:54.013 8022 8022 I com.bin.cantest: type=1400 audit(0.0:446): avc: denied { write } for path="socket:[114169]" dev="sockfs" ino=114169 scontext=u:r:system_app:s0 tcontext=u:r:system_app:s0 tclass=can_socket permissive=1 05-16 18:09:54.020 0 0 W audit : audit_lost=15 audit_rate_limit=5 audit_backlog_limit=64 05-16 18:09:54.020 0 0 E audit : rate limit exceeded 05-16 18:09:54.060 305 388 W APM::AudioPolicyEngine: getDevicesForStrategy() unknown strategy: -1 05-16 18:09:54.060 459 477 I system_server: oneway function results will be dropped but finished with status OK and parcel size 4 05-16 18:09:54.150 459 1215 E TaskPersister: File error accessing recents directory (directory doesn't exist?). 05-16 18:09:56.930 274 401 D AudioHardwareTiny: do_out_standby,out = 0xea043b70,device = 0x2 05-16 18:09:56.932 274 401 D alsa_route: route_set_controls() set route 24 05-16 18:09:56.941 274 401 D AudioHardwareTiny: close device 05-16 18:09:56.943 459 477 I system_server: oneway function results will be dropped but finished with status OK and parcel size 4 05-16 18:10:00.010 620 620 D KeyguardClockSwitch: Updating clock:
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值