blob: 192b79ea0163fca1239a1a2aadb57ca69111d7d0 [file] [log] [blame]
Flavio Lerdad1333a22011-08-11 16:19:47 +01001/*
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
17package com.android.contacts;
18
19import android.view.View;
20import android.widget.AbsListView;
21import 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 */
29public 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}