首页 > 代码库 > 为GridView添加HeaderView
为GridView添加HeaderView
实现这个功能一般有两种思路,一种思路是使用ScrollView+GridView,第二种思路是使用ListView来实现GridView的效果。
第一种思路的具体实现是把HeaderView和GridView都放到ScrollView里面,这里要解决的问题是ScrollView和GridView滑动手势的冲突问题,解决办法是让GridView充满ScrollView,不让GridView滑动而只让ScrollView滑动。具题做法是重载GridView的onMeasure()方法。
public class MyGridView extends GridView { public MyGridView(Context context, AttributeSet attrs) { super(context, attrs); } public MyGridView(Context context) { super(context); } public MyGridView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
这种方法的不足是GridView中的View没有复用,如果内容较多将比较消耗内存。
第二种思路的具体实现是使用ListView的addHeaderView()来添加HeaderView,而ListView的每一行都放一个LinearLayout来保存一行的item,这里要注意的是item的个数和ListView行数的关系。
后来在StackOverFlow上又看到了第三中方法。原来Google已经用GridView实现了,而且很巧妙,下面把代码贴出来
/* * 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 = http://www.mamicode.com/data;>代码地址:https://android.googlesource.com/platform/packages/apps/Gallery2/+/idea133/src/com/android/photos/views/HeaderGridView.java
为GridView添加HeaderView
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。