diff options
Diffstat (limited to 'src/com/android/photos/views/HeaderGridView.java')
-rw-r--r-- | src/com/android/photos/views/HeaderGridView.java | 466 |
1 files changed, 0 insertions, 466 deletions
diff --git a/src/com/android/photos/views/HeaderGridView.java b/src/com/android/photos/views/HeaderGridView.java deleted file mode 100644 index 45a5eaf73..000000000 --- a/src/com/android/photos/views/HeaderGridView.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * 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 com.android.photos.views; - -import android.content.Context; -import android.database.DataSetObservable; -import android.database.DataSetObserver; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.Filter; -import android.widget.Filterable; -import android.widget.FrameLayout; -import android.widget.GridView; -import android.widget.ListAdapter; -import android.widget.WrapperListAdapter; - -import java.util.ArrayList; - -/** - * A {@link GridView} that supports adding header rows in a - * very similar way to {@link ListView}. - * See {@link HeaderGridView#addHeaderView(View, Object, boolean)} - */ -public class HeaderGridView extends GridView { - private static final String TAG = "HeaderGridView"; - - /** - * A class that represents a fixed view in a list, for example a header at the top - * or a footer at the bottom. - */ - private static class FixedViewInfo { - /** The view to add to the grid */ - public View view; - public ViewGroup viewContainer; - /** The data backing the view. This is returned from {@link ListAdapter#getItem(int)}. */ - public Object data; - /** <code>true</code> if the fixed view should be selectable in the grid */ - public boolean isSelectable; - } - - private ArrayList<FixedViewInfo> mHeaderViewInfos = new ArrayList<FixedViewInfo>(); - - private void initHeaderGridView() { - super.setClipChildren(false); - } - - public HeaderGridView(Context context) { - super(context); - initHeaderGridView(); - } - - public HeaderGridView(Context context, AttributeSet attrs) { - super(context, attrs); - initHeaderGridView(); - } - - public HeaderGridView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - initHeaderGridView(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - ListAdapter adapter = getAdapter(); - if (adapter != null && adapter instanceof HeaderViewGridAdapter) { - ((HeaderViewGridAdapter) adapter).setNumColumns(getNumColumns()); - } - } - - @Override - public void setClipChildren(boolean clipChildren) { - // Ignore, since the header rows depend on not being clipped - } - - /** - * Add a fixed view to appear at the top of the grid. If addHeaderView is - * called more than once, the views will appear in the order they were - * added. Views added using this call can take focus if they want. - * <p> - * NOTE: Call this before calling setAdapter. This is so HeaderGridView can wrap - * the supplied cursor with one that will also account for header views. - * - * @param v The view to add. - * @param data Data to associate with this view - * @param isSelectable whether the item is selectable - */ - public void addHeaderView(View v, Object data, boolean isSelectable) { - ListAdapter adapter = getAdapter(); - - if (adapter != null && ! (adapter instanceof HeaderViewGridAdapter)) { - throw new IllegalStateException( - "Cannot add header view to grid -- setAdapter has already been called."); - } - - FixedViewInfo info = new FixedViewInfo(); - FrameLayout fl = new FullWidthFixedViewLayout(getContext()); - fl.addView(v); - info.view = v; - info.viewContainer = fl; - info.data = data; - info.isSelectable = isSelectable; - mHeaderViewInfos.add(info); - - // in the case of re-adding a header view, or adding one later on, - // we need to notify the observer - if (adapter != null) { - ((HeaderViewGridAdapter) adapter).notifyDataSetChanged(); - } - } - - /** - * Add a fixed view to appear at the top of the grid. If addHeaderView is - * called more than once, the views will appear in the order they were - * added. Views added using this call can take focus if they want. - * <p> - * NOTE: Call this before calling setAdapter. This is so HeaderGridView can wrap - * the supplied cursor with one that will also account for header views. - * - * @param v The view to add. - */ - public void addHeaderView(View v) { - addHeaderView(v, null, true); - } - - public int getHeaderViewCount() { - return mHeaderViewInfos.size(); - } - - /** - * Removes a previously-added header view. - * - * @param v The view to remove - * @return true if the view was removed, false if the view was not a header - * view - */ - public boolean removeHeaderView(View v) { - if (mHeaderViewInfos.size() > 0) { - boolean result = false; - ListAdapter adapter = getAdapter(); - if (adapter != null && ((HeaderViewGridAdapter) adapter).removeHeader(v)) { - result = true; - } - removeFixedViewInfo(v, mHeaderViewInfos); - return result; - } - return false; - } - - private void removeFixedViewInfo(View v, ArrayList<FixedViewInfo> where) { - int len = where.size(); - for (int i = 0; i < len; ++i) { - FixedViewInfo info = where.get(i); - if (info.view == v) { - where.remove(i); - break; - } - } - } - - @Override - public void setAdapter(ListAdapter adapter) { - if (mHeaderViewInfos.size() > 0) { - HeaderViewGridAdapter hadapter = new HeaderViewGridAdapter(mHeaderViewInfos, adapter); - int numColumns = getNumColumns(); - if (numColumns > 1) { - hadapter.setNumColumns(numColumns); - } - super.setAdapter(hadapter); - } else { - super.setAdapter(adapter); - } - } - - private class FullWidthFixedViewLayout extends FrameLayout { - public FullWidthFixedViewLayout(Context context) { - super(context); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int targetWidth = HeaderGridView.this.getMeasuredWidth() - - HeaderGridView.this.getPaddingLeft() - - HeaderGridView.this.getPaddingRight(); - widthMeasureSpec = MeasureSpec.makeMeasureSpec(targetWidth, - MeasureSpec.getMode(widthMeasureSpec)); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } - - /** - * ListAdapter used when a HeaderGridView has header views. This ListAdapter - * wraps another one and also keeps track of the header views and their - * associated data objects. - *<p>This is intended as a base class; you will probably not need to - * use this class directly in your own code. - */ - private static class HeaderViewGridAdapter implements WrapperListAdapter, Filterable { - - // This is used to notify the container of updates relating to number of columns - // or headers changing, which changes the number of placeholders needed - private final DataSetObservable mDataSetObservable = new DataSetObservable(); - - private final ListAdapter mAdapter; - private int mNumColumns = 1; - - // This ArrayList is assumed to NOT be null. - ArrayList<FixedViewInfo> mHeaderViewInfos; - - boolean mAreAllFixedViewsSelectable; - - private final boolean mIsFilterable; - - public HeaderViewGridAdapter(ArrayList<FixedViewInfo> headerViewInfos, ListAdapter adapter) { - mAdapter = adapter; - mIsFilterable = adapter instanceof Filterable; - - if (headerViewInfos == null) { - throw new IllegalArgumentException("headerViewInfos cannot be null"); - } - mHeaderViewInfos = headerViewInfos; - - mAreAllFixedViewsSelectable = areAllListInfosSelectable(mHeaderViewInfos); - } - - public int getHeadersCount() { - return mHeaderViewInfos.size(); - } - - @Override - public boolean isEmpty() { - return (mAdapter == null || mAdapter.isEmpty()) && getHeadersCount() == 0; - } - - public void setNumColumns(int numColumns) { - if (numColumns < 1) { - throw new IllegalArgumentException("Number of columns must be 1 or more"); - } - if (mNumColumns != numColumns) { - mNumColumns = numColumns; - notifyDataSetChanged(); - } - } - - private boolean areAllListInfosSelectable(ArrayList<FixedViewInfo> infos) { - if (infos != null) { - for (FixedViewInfo info : infos) { - if (!info.isSelectable) { - return false; - } - } - } - return true; - } - - public boolean removeHeader(View v) { - for (int i = 0; i < mHeaderViewInfos.size(); i++) { - FixedViewInfo info = mHeaderViewInfos.get(i); - if (info.view == v) { - mHeaderViewInfos.remove(i); - - mAreAllFixedViewsSelectable = areAllListInfosSelectable(mHeaderViewInfos); - - mDataSetObservable.notifyChanged(); - return true; - } - } - - return false; - } - - @Override - public int getCount() { - if (mAdapter != null) { - return getHeadersCount() * mNumColumns + mAdapter.getCount(); - } else { - return getHeadersCount() * mNumColumns; - } - } - - @Override - public boolean areAllItemsEnabled() { - if (mAdapter != null) { - return mAreAllFixedViewsSelectable && mAdapter.areAllItemsEnabled(); - } else { - return true; - } - } - - @Override - public boolean isEnabled(int position) { - // Header (negative positions will throw an ArrayIndexOutOfBoundsException) - int numHeadersAndPlaceholders = getHeadersCount() * mNumColumns; - if (position < numHeadersAndPlaceholders) { - return (position % mNumColumns == 0) - && mHeaderViewInfos.get(position / mNumColumns).isSelectable; - } - - // Adapter - final int adjPosition = position - numHeadersAndPlaceholders; - int adapterCount = 0; - if (mAdapter != null) { - adapterCount = mAdapter.getCount(); - if (adjPosition < adapterCount) { - return mAdapter.isEnabled(adjPosition); - } - } - - throw new ArrayIndexOutOfBoundsException(position); - } - - @Override - public Object getItem(int position) { - // Header (negative positions will throw an ArrayIndexOutOfBoundsException) - int numHeadersAndPlaceholders = getHeadersCount() * mNumColumns; - if (position < numHeadersAndPlaceholders) { - if (position % mNumColumns == 0) { - return mHeaderViewInfos.get(position / mNumColumns).data; - } - return null; - } - - // Adapter - final int adjPosition = position - numHeadersAndPlaceholders; - int adapterCount = 0; - if (mAdapter != null) { - adapterCount = mAdapter.getCount(); - if (adjPosition < adapterCount) { - return mAdapter.getItem(adjPosition); - } - } - - throw new ArrayIndexOutOfBoundsException(position); - } - - @Override - public long getItemId(int position) { - int numHeadersAndPlaceholders = getHeadersCount() * mNumColumns; - if (mAdapter != null && position >= numHeadersAndPlaceholders) { - int adjPosition = position - numHeadersAndPlaceholders; - int adapterCount = mAdapter.getCount(); - if (adjPosition < adapterCount) { - return mAdapter.getItemId(adjPosition); - } - } - return -1; - } - - @Override - public boolean hasStableIds() { - if (mAdapter != null) { - return mAdapter.hasStableIds(); - } - return false; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - // Header (negative positions will throw an ArrayIndexOutOfBoundsException) - int numHeadersAndPlaceholders = getHeadersCount() * mNumColumns ; - if (position < numHeadersAndPlaceholders) { - View headerViewContainer = mHeaderViewInfos - .get(position / mNumColumns).viewContainer; - if (position % mNumColumns == 0) { - return headerViewContainer; - } else { - if (convertView == null) { - convertView = new View(parent.getContext()); - } - // We need to do this because GridView uses the height of the last item - // in a row to determine the height for the entire row. - convertView.setVisibility(View.INVISIBLE); - convertView.setMinimumHeight(headerViewContainer.getHeight()); - return convertView; - } - } - - // Adapter - final int adjPosition = position - numHeadersAndPlaceholders; - int adapterCount = 0; - if (mAdapter != null) { - adapterCount = mAdapter.getCount(); - if (adjPosition < adapterCount) { - return mAdapter.getView(adjPosition, convertView, parent); - } - } - - throw new ArrayIndexOutOfBoundsException(position); - } - - @Override - public int getItemViewType(int position) { - int numHeadersAndPlaceholders = getHeadersCount() * mNumColumns; - if (position < numHeadersAndPlaceholders && (position % mNumColumns != 0)) { - // Placeholders get the last view type number - return mAdapter != null ? mAdapter.getViewTypeCount() : 1; - } - if (mAdapter != null && position >= numHeadersAndPlaceholders) { - int adjPosition = position - numHeadersAndPlaceholders; - int adapterCount = mAdapter.getCount(); - if (adjPosition < adapterCount) { - return mAdapter.getItemViewType(adjPosition); - } - } - - return AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER; - } - - @Override - public int getViewTypeCount() { - if (mAdapter != null) { - return mAdapter.getViewTypeCount() + 1; - } - return 2; - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - mDataSetObservable.registerObserver(observer); - if (mAdapter != null) { - mAdapter.registerDataSetObserver(observer); - } - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - mDataSetObservable.unregisterObserver(observer); - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(observer); - } - } - - @Override - public Filter getFilter() { - if (mIsFilterable) { - return ((Filterable) mAdapter).getFilter(); - } - return null; - } - - @Override - public ListAdapter getWrappedAdapter() { - return mAdapter; - } - - public void notifyDataSetChanged() { - mDataSetObservable.notifyChanged(); - } - } -} |