OSDN Git Service

3dcb33268f09941659a92719db691cd5c5fc7b56
[android-x86/packages-apps-Launcher3.git] / src / com / android / launcher3 / widget / WidgetsRecyclerView.java
1 /*
2  * Copyright (C) 2015 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.launcher3.widget;
18
19 import android.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Color;
22 import android.support.v7.widget.LinearLayoutManager;
23 import android.util.AttributeSet;
24 import android.view.View;
25 import com.android.launcher3.BaseRecyclerView;
26 import com.android.launcher3.R;
27 import com.android.launcher3.model.PackageItemInfo;
28 import com.android.launcher3.model.WidgetsModel;
29
30 /**
31  * The widgets recycler view.
32  */
33 public class WidgetsRecyclerView extends BaseRecyclerView {
34
35     private static final String TAG = "WidgetsRecyclerView";
36     private WidgetsModel mWidgets;
37     private ScrollPositionState mScrollPosState = new ScrollPositionState();
38
39     public WidgetsRecyclerView(Context context) {
40         this(context, null);
41     }
42
43     public WidgetsRecyclerView(Context context, AttributeSet attrs) {
44         this(context, attrs, 0);
45     }
46
47     public WidgetsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
48         // API 21 and below only support 3 parameter ctor.
49         super(context, attrs, defStyleAttr);
50     }
51
52     public WidgetsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
53             int defStyleRes) {
54         this(context, attrs, defStyleAttr);
55     }
56
57     @Override
58     protected void onFinishInflate() {
59         super.onFinishInflate();
60         addOnItemTouchListener(this);
61     }
62
63     public int getFastScrollerTrackColor(int defaultTrackColor) {
64         return Color.WHITE;
65     }
66
67     /**
68      * Sets the widget model in this view, used to determine the fast scroll position.
69      */
70     public void setWidgets(WidgetsModel widgets) {
71         mWidgets = widgets;
72     }
73     
74     /**
75      * We need to override the draw to ensure that we don't draw the overscroll effect beyond the
76      * background bounds.
77      */
78     @Override
79     protected void dispatchDraw(Canvas canvas) {
80         canvas.clipRect(mBackgroundPadding.left, mBackgroundPadding.top,
81                 getWidth() - mBackgroundPadding.right,
82                 getHeight() - mBackgroundPadding.bottom);
83         super.dispatchDraw(canvas);
84     }
85
86     /**
87      * Maps the touch (from 0..1) to the adapter position that should be visible.
88      */
89     @Override
90     public String scrollToPositionAtProgress(float touchFraction) {
91         int rowCount = mWidgets.getPackageSize();
92         if (rowCount == 0) {
93             return "";
94         }
95
96         // Stop the scroller if it is scrolling
97         stopScroll();
98
99         getCurScrollState(mScrollPosState);
100         float pos = rowCount * touchFraction;
101         int availableScrollHeight = getAvailableScrollHeight(rowCount, mScrollPosState.rowHeight);
102         LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager());
103         layoutManager.scrollToPositionWithOffset(0, (int) -(availableScrollHeight * touchFraction));
104
105         int posInt = (int) ((touchFraction == 1)? pos -1 : pos);
106         PackageItemInfo p = mWidgets.getPackageItemInfo(posInt);
107         return p.titleSectionName;
108     }
109
110     /**
111      * Updates the bounds for the scrollbar.
112      */
113     @Override
114     public void onUpdateScrollbar(int dy) {
115         int rowCount = mWidgets.getPackageSize();
116
117         // Skip early if, there are no items.
118         if (rowCount == 0) {
119             mScrollbar.setThumbOffset(-1, -1);
120             return;
121         }
122
123         // Skip early if, there no child laid out in the container.
124         getCurScrollState(mScrollPosState);
125         if (mScrollPosState.rowIndex < 0) {
126             mScrollbar.setThumbOffset(-1, -1);
127             return;
128         }
129
130         synchronizeScrollBarThumbOffsetToViewScroll(mScrollPosState, rowCount);
131     }
132
133     /**
134      * Returns the current scroll state.
135      */
136     protected void getCurScrollState(ScrollPositionState stateOut) {
137         stateOut.rowIndex = -1;
138         stateOut.rowTopOffset = -1;
139         stateOut.rowHeight = -1;
140
141         int rowCount = mWidgets.getPackageSize();
142
143         // Return early if there are no items
144         if (rowCount == 0) {
145             return;
146         }
147         View child = getChildAt(0);
148         int position = getChildPosition(child);
149
150         stateOut.rowIndex = position;
151         stateOut.rowTopOffset = getLayoutManager().getDecoratedTop(child);
152         stateOut.rowHeight = child.getHeight();
153     }
154 }