博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HeaderGridView
阅读量:7048 次
发布时间:2019-06-28

本文共 16916 字,大约阅读时间需要 56 分钟。

hot3.png

package com.soke.widget;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;        /** true if the fixed view should be selectable in the grid */        public boolean isSelectable;    }    private ArrayList
 mHeaderViewInfos = new ArrayList
();    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.     * 

     * 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.     * 

     * 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

 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.     *

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

 mHeaderViewInfos;        boolean mAreAllFixedViewsSelectable;        private final boolean mIsFilterable;        public HeaderViewGridAdapter(ArrayList
 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
 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();        }    }} /*@Overridepublic 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);}*/

转载于:https://my.oschina.net/u/1781028/blog/395529

你可能感兴趣的文章
在kubernets中搭建jenkins服务
查看>>
iEclipse-不只是Eclipse的开发者社区
查看>>
Oracle个人的一些记录
查看>>
20.分屏查看命令 less命令
查看>>
感谢付费客户不覺流年似水(271558528) 对C#ASP.NET通用权限管理组件的改进意见,已修正...
查看>>
MySQL5.6.17学习笔记(四)复合分区及分区管理
查看>>
android 让 TextView 自带滚动条
查看>>
PHP过滤常见html标签的正则表达式
查看>>
注册与登录界面的美化
查看>>
win2003远程桌面不自动注销,自动锁定时间
查看>>
Shell脚本
查看>>
RPM包管理
查看>>
7个顶级心理寓言
查看>>
我的友情链接
查看>>
2.vi 和 vim 编辑器
查看>>
mdadm--RAID 5
查看>>
java异常设计
查看>>
服务器的几种时间同步
查看>>
我的友情链接
查看>>
WPF“动画序列”框架的初步研究与实现(附源码)
查看>>