/* * Copyright (c) 2011. WillowTree Apps * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package oak; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.BaseAdapter; import android.widget.SectionIndexer; import oak.widget.SectionListView; public abstract class BaseSectionAdapter extends BaseAdapter implements SectionIndexer, OnScrollListener { public static final String TAG = BaseSectionAdapter.class.getSimpleName(); /** * Pinned header state: don't show the header. */ public static final int PINNED_HEADER_GONE = 0; /** * Pinned header state: show the header at the top of the list. */ public static final int PINNED_HEADER_VISIBLE = 1; /** * Pinned header state: show the header. If the header extends beyond the bottom of the first shown element, push it * up and clip. */ public static final int PINNED_HEADER_PUSHED_UP = 2; /** * Computes the desired state of the pinned header for the given position of the first visible list item. Allowed * return values are {@link #PINNED_HEADER_GONE}, {@link #PINNED_HEADER_VISIBLE} or {@link * #PINNED_HEADER_PUSHED_UP}. */ public int getPinnedHeaderState(int position) { if (position < 0 || getCount() == 0) { return PINNED_HEADER_GONE; } // The header should get pushed up if the top item shown // is the last item in a section for a particular letter. int section = getSectionForPosition(position); int nextSectionPosition = getPositionForSection(section + 1); if (nextSectionPosition != -1 && position == nextSectionPosition - 1) { return PINNED_HEADER_PUSHED_UP; } return PINNED_HEADER_VISIBLE; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (view instanceof SectionListView) { ((SectionListView) view).configureHeaderView(firstVisibleItem); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // nop } @Override public final View getView(int position, View convertView, ViewGroup parent) { View res = getAmazingView(position, convertView, parent); final int section = getSectionForPosition(position); boolean displaySectionHeaders = (getPositionForSection(section) == position); bindSectionHeader(res, position, displaySectionHeaders); return res; } /** * Configure the view (a listview item) to display headers or not based on displaySectionHeader (e.g. if * displaySectionHeader header.setVisibility(VISIBLE) else header.setVisibility(GONE)). */ protected abstract void bindSectionHeader(View view, int position, boolean displaySectionHeader); /** * read: get view too */ public abstract View getAmazingView(int position, View convertView, ViewGroup parent); /** * Configures the pinned header view to match the first visible list item. * * @param header pinned header view. * @param position position of the first visible list item. * @param alpha fading of the header view, between 0 and 255. */ public abstract void configurePinnedHeader(View header, int position, int alpha); @Override public abstract int getPositionForSection(int section); @Override public abstract int getSectionForPosition(int position); @Override public abstract Object[] getSections(); }