Home | History | Annotate | Download | only in widget
      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     public int getFastScrollerThumbInactiveColor(int defaultInactiveThumbColor) {
     68         return getResources().getColor(R.color.widgets_view_fastscroll_thumb_inactive_color);
     69     }
     70 
     71     /**
     72      * Sets the widget model in this view, used to determine the fast scroll position.
     73      */
     74     public void setWidgets(WidgetsModel widgets) {
     75         mWidgets = widgets;
     76     }
     77 
     78     /**
     79      * We need to override the draw to ensure that we don't draw the overscroll effect beyond the
     80      * background bounds.
     81      */
     82     @Override
     83     protected void dispatchDraw(Canvas canvas) {
     84         canvas.clipRect(mBackgroundPadding.left, mBackgroundPadding.top,
     85                 getWidth() - mBackgroundPadding.right,
     86                 getHeight() - mBackgroundPadding.bottom);
     87         super.dispatchDraw(canvas);
     88     }
     89 
     90     /**
     91      * Maps the touch (from 0..1) to the adapter position that should be visible.
     92      */
     93     @Override
     94     public String scrollToPositionAtProgress(float touchFraction) {
     95         int rowCount = mWidgets.getPackageSize();
     96         if (rowCount == 0) {
     97             return "";
     98         }
     99 
    100         // Stop the scroller if it is scrolling
    101         stopScroll();
    102 
    103         getCurScrollState(mScrollPosState);
    104         float pos = rowCount * touchFraction;
    105         int availableScrollHeight = getAvailableScrollHeight(rowCount, mScrollPosState.rowHeight, 0);
    106         LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager());
    107         layoutManager.scrollToPositionWithOffset(0, (int) -(availableScrollHeight * touchFraction));
    108 
    109         int posInt = (int) ((touchFraction == 1)? pos -1 : pos);
    110         PackageItemInfo p = mWidgets.getPackageItemInfo(posInt);
    111         return p.titleSectionName;
    112     }
    113 
    114     /**
    115      * Updates the bounds for the scrollbar.
    116      */
    117     @Override
    118     public void onUpdateScrollbar() {
    119         int rowCount = mWidgets.getPackageSize();
    120 
    121         // Skip early if, there are no items.
    122         if (rowCount == 0) {
    123             mScrollbar.setScrollbarThumbOffset(-1, -1);
    124             return;
    125         }
    126 
    127         // Skip early if, there no child laid out in the container.
    128         getCurScrollState(mScrollPosState);
    129         if (mScrollPosState.rowIndex < 0) {
    130             mScrollbar.setScrollbarThumbOffset(-1, -1);
    131             return;
    132         }
    133 
    134         synchronizeScrollBarThumbOffsetToViewScroll(mScrollPosState, rowCount, 0);
    135     }
    136 
    137     /**
    138      * Returns the current scroll state.
    139      */
    140     private void getCurScrollState(ScrollPositionState stateOut) {
    141         stateOut.rowIndex = -1;
    142         stateOut.rowTopOffset = -1;
    143         stateOut.rowHeight = -1;
    144 
    145         int rowCount = mWidgets.getPackageSize();
    146 
    147         // Return early if there are no items
    148         if (rowCount == 0) {
    149             return;
    150         }
    151         View child = getChildAt(0);
    152         int position = getChildPosition(child);
    153 
    154         stateOut.rowIndex = position;
    155         stateOut.rowTopOffset = getLayoutManager().getDecoratedTop(child);
    156         stateOut.rowHeight = child.getHeight();
    157     }
    158 }