Home | History | Annotate | Download | only in contacts
      1 /*
      2  * Copyright (C) 2011 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.contacts;
     18 
     19 import android.view.View;
     20 import android.widget.AbsListView;
     21 import android.widget.ListView;
     22 
     23 /**
     24  * Handles scrolling back of a list tied to a header.
     25  * <p>
     26  * This is used to implement a header that scrolls up with the content of a list to be partially
     27  * obscured.
     28  */
     29 public class BackScrollManager {
     30     /** Defines the header to be scrolled. */
     31     public interface ScrollableHeader {
     32         /** Sets the offset by which to scroll. */
     33         public void setOffset(int offset);
     34         /** Gets the maximum offset that should be applied to the header. */
     35         public int getMaximumScrollableHeaderOffset();
     36     }
     37 
     38     private final ScrollableHeader mHeader;
     39     private final ListView mListView;
     40 
     41     private final AbsListView.OnScrollListener mScrollListener =
     42             new AbsListView.OnScrollListener() {
     43                 @Override
     44                 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
     45                         int totalItemCount) {
     46                     if (firstVisibleItem != 0) {
     47                         // The first item is not shown, the header should be pinned at the top.
     48                         mHeader.setOffset(mHeader.getMaximumScrollableHeaderOffset());
     49                         return;
     50                     }
     51 
     52                     View firstVisibleItemView = view.getChildAt(firstVisibleItem);
     53                     if (firstVisibleItemView == null) {
     54                         return;
     55                     }
     56                     // We scroll the header up, but at most pin it to the top of the screen.
     57                     int offset = Math.min(
     58                             (int) -view.getChildAt(firstVisibleItem).getY(),
     59                             mHeader.getMaximumScrollableHeaderOffset());
     60                     mHeader.setOffset(offset);
     61                 }
     62 
     63                 @Override
     64                 public void onScrollStateChanged(AbsListView view, int scrollState) {
     65                     // Nothing to do here.
     66                 }
     67             };
     68 
     69     /**
     70      * Creates a new instance of a {@link BackScrollManager} that connected the header and the list
     71      * view.
     72      */
     73     public static void bind(ScrollableHeader header, ListView listView) {
     74         BackScrollManager backScrollManager = new BackScrollManager(header, listView);
     75         backScrollManager.bind();
     76     }
     77 
     78     private BackScrollManager(ScrollableHeader header, ListView listView) {
     79         mHeader = header;
     80         mListView = listView;
     81     }
     82 
     83     private void bind() {
     84         mListView.setOnScrollListener(mScrollListener);
     85         // We disable the scroll bar because it would otherwise be incorrect because of the hidden
     86         // header.
     87         mListView.setVerticalScrollBarEnabled(false);
     88     }
     89 }
     90