blob: 9a747877d9be575af21baadae1b60923e960abec [file] [log] [blame]
Jason Monk231b0522018-01-04 10:49:55 -05001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.qs;
16
17import android.content.Context;
18import android.graphics.Rect;
19import android.support.v4.widget.NestedScrollView;
20import android.view.MotionEvent;
21import android.view.View;
22import android.view.ViewConfiguration;
23import android.view.ViewParent;
24import android.widget.LinearLayout;
25
26/**
27 * Quick setting scroll view containing the brightness slider and the QS tiles.
28 *
29 * <p>Call {@link #shouldIntercept(MotionEvent)} from parent views'
30 * {@link #onInterceptTouchEvent(MotionEvent)} method to determine whether this view should
31 * consume the touch event.
32 */
33public class QSScrollLayout extends NestedScrollView {
34 private final int mTouchSlop;
35 private int mLastMotionY;
36 private Rect mHitRect = new Rect();
37
38 public QSScrollLayout(Context context, View... children) {
39 super(context);
40 mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
41 LinearLayout linearLayout = new LinearLayout(mContext);
42 linearLayout.setLayoutParams(new LinearLayout.LayoutParams(
43 LinearLayout.LayoutParams.MATCH_PARENT,
44 LinearLayout.LayoutParams.WRAP_CONTENT));
45 linearLayout.setOrientation(LinearLayout.VERTICAL);
46 for (View view : children) {
47 linearLayout.addView(view);
48 }
49 addView(linearLayout);
50 }
51
52 public boolean shouldIntercept(MotionEvent ev) {
53 getHitRect(mHitRect);
54 if (!mHitRect.contains((int) ev.getX(), (int) ev.getY())) {
55 // Do not intercept touches that are not within this view's bounds.
56 return false;
57 }
58 if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
59 mLastMotionY = (int) ev.getY();
60 } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
61 // Do not allow NotificationPanelView to intercept touch events when this
62 // view can be scrolled down.
63 if (mLastMotionY >= 0 && Math.abs(ev.getY() - mLastMotionY) > mTouchSlop
64 && canScrollVertically(1)) {
65 requestParentDisallowInterceptTouchEvent(true);
66 mLastMotionY = (int) ev.getY();
67 return true;
68 }
69 } else if (ev.getActionMasked() == MotionEvent.ACTION_CANCEL
70 || ev.getActionMasked() == MotionEvent.ACTION_UP) {
71 mLastMotionY = -1;
72 requestParentDisallowInterceptTouchEvent(false);
73 }
74 return false;
75 }
76
77 private void requestParentDisallowInterceptTouchEvent(boolean disallowIntercept) {
78 final ViewParent parent = getParent();
79 if (parent != null) {
80 parent.requestDisallowInterceptTouchEvent(disallowIntercept);
81 }
82 }
83}