我正在为gridView创建一个ArrayAdapter,考虑页眉和页脚视图。
activity_main.xml中:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<GridView
android:id="@+id/activity_main_gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="4" />
</RelativeLayout>
问题在于,当我滚动到网格标题/底部视图的顶部或底部时,会覆盖网格项目,当点击任何项目时,它会返回到原始位置(如果需要,我会放置屏幕截图)< / p>
这是我的GridView适配器(按顺序排列:上下文,网格项的arraylist(没有页眉/页脚),所有第一行的页眉视图,所有最后一行的页脚视图,gridview列编号):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGridView = (GridView) findViewById(R.id.activity_main_gridview);
List<String> list = new ArrayList<String>();
for (int i = 0; i < 500; i++) {
list.add("item " + i);
}
View headerView = new View(this);
headerView.setMinimumHeight(70);
headerView.setBackgroundColor(Color.argb(255, 63, 81, 181));
GridHeaderFooterAdapter adapter =
new GridHeaderFooterAdapter(this, list, headerView, headerView, 4);
mGridView.setAdapter(adapter);
}
private final class GridHeaderFooterAdapter extends ArrayAdapter<String> {
private int mNumColumns;
private int mListSize;
private List<String> mList;
private View mHeaderView;
private View mFooterView;
private LayoutInflater mInflater;
public GridHeaderFooterAdapter(ActivityMain context, List<String> list, View headerView, View footerView, int numColumns) {
super(context, 0);
this.mNumColumns = numColumns;
this.mListSize = list.size();
this.mList = list;
this.mHeaderView = headerView;
this.mFooterView = footerView;
mInflater = context.getLayoutInflater();
}
@Override
public int getCount() {
int count = 0;
//headers
count += mNumColumns;
//list items
count += mListSize;
//footers
count += mNumColumns + (mNumColumns - mList.size() % mNumColumns);
Log.w("ActivityMain", "getCount() = " + count);
return count;
}
@Override
public String getItem(int position) {
//discard header items
return mList.get(position - mNumColumns);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//headers
if (position < mNumColumns){
Log.w("ActivityMain", "headers: position = " + position);
return mHeaderView;
}
//listitems
if (position >= mNumColumns && position < mNumColumns + mListSize) {
Log.w("ActivityMain", "listitems: position = " + position);
LinearLayout ll = (LinearLayout) mInflater.inflate(R.layout.listitem_main, null);
TextView tv = (TextView) ll.findViewById(R.id.textView);
tv.setText(getItem(position));
return ll;
}
//footers
if (position >= mNumColumns + mListSize){
Log.w("ActivityMain", "footers: position = " + position);
/*TODO: some footers might be in the same row as listitem, which is wrong because Gridview uses last item of the row to determine row height... */
return mFooterView;
}
return null;
}
}
在滚动之前: 滚动后:
如您所见,目标是添加标题以避免第一项位于状态栏
之后答案 0 :(得分:2)
手动玩位置编号是一件危险的事情,尽管如果做得恰到好处,这很有可能。这里的问题是您试图绕过getView()
方法的运作方式。 getView()
将保留它自己对返回的视图的引用,并相应地回收或销毁它。它已经进行了大量优化以提供卓越的性能,并且为了实现您的最终目标,您希望使用它...而不是反对。
最终,您希望GridView中第1行(页眉)和最后(页脚)行的间距避免与半透明状态/导航栏重叠。我将更全面地了解需要发生的事情。
getCount()
需要返回:
mListSize + (mNumColumns * 2)
为什么呢?因为您需要每列的标题视图以及每列的页脚视图。
getItem()
需要为所有可能的位置返回一些内容。这意味着getCount()
返回的任何值都需要能够返回某些内容......即使它是一个空字符串。如下所示:
// if a header position or a footer position
if (position < mNumColumns || position > mListSize + mNumColumns) {
return ""
} else {
return mList.get(position - mNumColumns);
}
请注意,考虑到数量不是零,但位置是......,这可能会稍微偏离......但它显示了您需要的基本要点。
getView()
需要正常呈现视图。区别在于,如果位置编号指示页眉/页脚位置,则返回空白视图。例如:
ViewHolder vh = null;
if (convertView == null) {
//inflate your view
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView;
}
//If position is indicative of a header/footer. Alternatively you could see if getItem() returns an empty string...assuming your data can never contain an empty string.
if (position < mNumColumns || position > mListSize + mNumColumns) {
//Don't fill the view with any data. Make any visible elements INVISIBLE
} else {
//populate convertView with data
}
摆脱传递视图以供适配器使用的整个概念。那会破坏一切。如果表现非常令人担忧,那么使用getItemViewType()
和getViewTypeCount()
就是一个更好的选择(而且正确的选择......比我发布的更多)。但是,这将要求您创建一个可以表示实际数据的类对象(例如字符串)和一个表示它是页眉,页脚和数据的标志。