• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settingslib.widget;
18 
19 import android.content.Context;
20 import android.graphics.Rect;
21 import android.util.AttributeSet;
22 import android.view.TouchDelegate;
23 import android.view.View;
24 import android.widget.LinearLayout;
25 
26 import androidx.annotation.Nullable;
27 
28 import com.android.settingslib.widget.preference.banner.R;
29 
30 /**
31  * The view providing {@link BannerMessagePreference}.
32  *
33  * <p>Callers should not instantiate this view directly but rather through adding a
34  * {@link BannerMessagePreference} to a {@code PreferenceScreen}.
35  */
36 public class BannerMessageView extends LinearLayout {
37     private Rect mTouchTargetForDismissButton;
38 
BannerMessageView(Context context)39     public BannerMessageView(Context context) {
40         super(context);
41     }
42 
BannerMessageView(Context context, @Nullable AttributeSet attrs)43     public BannerMessageView(Context context,
44             @Nullable AttributeSet attrs) {
45         super(context, attrs);
46     }
47 
BannerMessageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)48     public BannerMessageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
49         super(context, attrs, defStyleAttr);
50     }
51 
BannerMessageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)52     public BannerMessageView(Context context, AttributeSet attrs, int defStyleAttr,
53             int defStyleRes) {
54         super(context, attrs, defStyleAttr, defStyleRes);
55     }
56 
57     @Override
onLayout(boolean changed, int l, int t, int r, int b)58     protected void onLayout(boolean changed, int l, int t, int r, int b) {
59         super.onLayout(changed, l, t, r, b);
60         setupIncreaseTouchTargetForDismissButton();
61     }
62 
setupIncreaseTouchTargetForDismissButton()63     private void setupIncreaseTouchTargetForDismissButton() {
64         if (mTouchTargetForDismissButton != null) {
65             // Already set up
66             return;
67         }
68 
69         // The dismiss button is in the 'top row' RelativeLayout for positioning, but this element
70         // does not have enough space to provide large touch targets.  We therefore set the top
71         // target on this view.
72         View topRow = findViewById(R.id.top_row);
73         View dismissButton = findViewById(R.id.banner_dismiss_btn);
74         if (topRow == null || dismissButton == null || dismissButton.getVisibility() != VISIBLE) {
75             return;
76         }
77 
78         int minimum =
79                 getResources()
80                         .getDimensionPixelSize(com.android.settingslib.widget.theme.R.dimen.settingslib_preferred_minimum_touch_target);
81         int width = dismissButton.getWidth();
82         int height = dismissButton.getHeight();
83         int widthIncrease = width < minimum ? minimum - width : 0;
84         int heightIncrease = height < minimum ? minimum - height : 0;
85 
86         // Compute the hit rect of dismissButton within the local co-orindate reference of this view
87         // (rather than it's direct parent topRow).
88         Rect hitRectWithinTopRow = new Rect();
89         dismissButton.getHitRect(hitRectWithinTopRow);
90         Rect hitRectOfTopRowWithinThis = new Rect();
91         topRow.getHitRect(hitRectOfTopRowWithinThis);
92         mTouchTargetForDismissButton = new Rect();
93         mTouchTargetForDismissButton.left =
94                 hitRectOfTopRowWithinThis.left + hitRectWithinTopRow.left;
95         mTouchTargetForDismissButton.right =
96                 hitRectOfTopRowWithinThis.left + hitRectWithinTopRow.right;
97         mTouchTargetForDismissButton.top =
98                 hitRectOfTopRowWithinThis.top + hitRectWithinTopRow.top;
99         mTouchTargetForDismissButton.bottom =
100                 hitRectOfTopRowWithinThis.top + hitRectWithinTopRow.bottom;
101 
102         // Adjust the touch target rect to apply the necessary increase in width and height.
103         mTouchTargetForDismissButton.left -=
104                 widthIncrease % 2 == 1 ? (widthIncrease / 2) + 1 : widthIncrease / 2;
105         mTouchTargetForDismissButton.top -=
106                 heightIncrease % 2 == 1 ? (heightIncrease / 2) + 1 : heightIncrease / 2;
107         mTouchTargetForDismissButton.right += widthIncrease / 2;
108         mTouchTargetForDismissButton.bottom += heightIncrease / 2;
109 
110         setTouchDelegate(new TouchDelegate(mTouchTargetForDismissButton, dismissButton));
111     }
112 
113 }
114