Android 交错 GridView
本文演示在你的 Android 应用程序中显示交错 GridView(Staggered GridView )。
下载 Demo
交错 GridView
交错 GridView 只是具有不等大小行、多个列的 GridView。你可能已经使用过 Pinterest,Expedia 或 Etsy Android app。
目前,已经有 2、3 个很不错的开源库。
交错 GridView 库
下面说明最流行使用最广泛的 Etsy 的交错 gridview。
Etsy 交错 GridView
自定义的交错 GridView 是根据 AbsListView 类扩展的,它当然也就支持 AbsListView.OnScrollListener。
功能
- 可以配置横向和纵向的列数量。
- 跨方向变化的异步行位置。
- 可配置项的边距(margin)
- 支持页眉(header)和页脚(footer)。
- 内部填充(Internal padding ),不影响页眉和页脚。
Etsy 的交错 gridview 不支持项的长按事件和选择器 drawables,而 Maurycy 的交错 gridview 则支持长按事件。
环境
- Windows 2008 R2 64 位
- Eclipse ADT V22.6.2,Android 4.4.2(API 19)
- SAMSUNG GT-8618,Android OS 4.1.2
项目结构
图 1 项目结构
- StaggeredGrid 项目是 com.etsy.android.grid 库。
- StaggeredGridDemo 项目是示例。
示例:Etsy 交错 GridView
图 2 演示交错 GridView
- 下载/包含库 com.etsy.android.grid
com.etsy.android.grid 库目前配置为只能通过 Gradle 生成,因此,如果您使用 Android Studio,那么你可以直接的方式包括这个库,作为 gradle 依赖来生成。如果你使用 Eclipse/ Ant,那么你必须执行额外的步骤。
对 Android Studio 环境:
repositories {
mavenCentral()
}
dependencies {
compile 'com.etsy.android.grid:library:x.x.x' // read below comment
}
对 Eclipse/Ant build:
下载 com.etsy.android.grid,并导入到项目。
- 把 StaggeredGridView 放到你的布局——activity_sgv.xml
<com.etsy.android.grid.StaggeredGridView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:column_count="@integer/grid_column_count"
app:item_margin="8dp" />
- 为 StaggeredGridView 定义行布局——row_grid_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/panel_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >
<com.etsy.android.grid.util.DynamicHeightImageView
android:id="@+id/imgView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</FrameLayout>
自定义行应该包含 DynamicHeightImageView 或 DynamicHeightTextView。
- 自定义 adapter
public class SampleAdapter extends ArrayAdapter<String> {
private static final String TAG = "SampleAdapter";
private final LayoutInflater mLayoutInflater;
private final Random mRandom;
private static final SparseArray<Double> sPositionHeightRatios = new SparseArray<Double>();
public SampleAdapter(Context context, int textViewResourceId,
ArrayList<String> objects) {
super(context, textViewResourceId, objects);
this.mLayoutInflater = LayoutInflater.from(context);
this.mRandom = new Random();
}
@Override
public View getView(final int position, View convertView,
final ViewGroup parent) {
ViewHolder vh;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.row_grid_item,
parent, false);
vh = new ViewHolder();
vh.imgView = (DynamicHeightImageView) convertView
.findViewById(R.id.imgView);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
double positionHeight = getPositionRatio(position);
vh.imgView.setHeightRatio(positionHeight);
ImageLoader.getInstance().displayImage(getItem(position), vh.imgView);
return convertView;
}
static class ViewHolder {
DynamicHeightImageView imgView;
}
private double getPositionRatio(final int position) {
double ratio = sPositionHeightRatios.get(position, 0.0);
// if not yet done generate and stash the columns height
// in our real world scenario this will be determined by
// some match based on the known height and width of the image
// and maybe a helpful way to get the column height!
if (ratio == 0) {
ratio = getRandomHeightRatio();
sPositionHeightRatios.append(position, ratio);
Log.d(TAG, "getPositionRatio:" + position + " ratio:" + ratio);
}
return ratio;
}
private double getRandomHeightRatio() {
return (mRandom.nextDouble() / 2.0) + 1.0; // height will be 1.0 - 1.5
// the width
}
}
自定义 adapter 类用来在交错 GridView 中显示动态高度的图片。另外,还使用了 Universal image loader 库用来异步加载图片。
- 把自定义 adapter 设置给 StaggeredGridView
public class StaggeredGridActivity extends Activity implements
AbsListView.OnScrollListener, AbsListView.OnItemClickListener {
private static final String TAG = "StaggeredGridActivity";
public static final String SAVED_DATA_KEY = "SAVED_DATA";
private StaggeredGridView mGridView;
private boolean mHasRequestedMore;
private SampleAdapter mAdapter;
private ArrayList<String> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sgv);
setTitle("TechnoTalkative - SGV Demo");
mGridView = (StaggeredGridView) findViewById(R.id.grid_view);
mAdapter = new SampleAdapter(this, android.R.layout.simple_list_item_1,
generateData());
// do we have saved data?
if (savedInstanceState != null) {
mData = savedInstanceState.getStringArrayList(SAVED_DATA_KEY);
}
if (mData == null) {
mData = generateData();
}
for (String data : mData) {
mAdapter.add(data);
}
mGridView.setAdapter(mAdapter);
mGridView.setOnScrollListener(this);
mGridView.setOnItemClickListener(this);
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList(SAVED_DATA_KEY, mData);
}
@Override
public void onScrollStateChanged(final AbsListView view,
final int scrollState) {
Log.d(TAG, "onScrollStateChanged:" + scrollState);
}
@Override
public void onScroll(final AbsListView view, final int firstVisibleItem,
final int visibleItemCount, final int totalItemCount) {
Log.d(TAG, "onScroll firstVisibleItem:" + firstVisibleItem
+ " visibleItemCount:" + visibleItemCount + " totalItemCount:"
+ totalItemCount);
// our handling
if (!mHasRequestedMore) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if (lastInScreen >= totalItemCount) {
Log.d(TAG, "onScroll lastInScreen - so load more");
mHasRequestedMore = true;
onLoadMoreItems();
}
}
}
private void onLoadMoreItems() {
final ArrayList<String> sampleData = generateData();
for (String data : sampleData) {
mAdapter.add(data);
}
// stash all the data in our backing store
mData.addAll(sampleData);
// notify the adapter that we can update now
mAdapter.notifyDataSetChanged();
mHasRequestedMore = false;
}
private ArrayList<String> generateData() {
ArrayList<String> listData = new ArrayList<String>();
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_2iitkhx.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_w0omeb.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_w9iu1d.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_iw6kh2.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_ru08c8.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_k12r10.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_2e3daug.jpg");
listData.add("http://images.cnblogs.com/cnblogs_com/liuning8023/610092/o_2igznfr.jpg");
return listData;
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id) {
Toast.makeText(this, "Item Clicked: " + position, Toast.LENGTH_SHORT)
.show();
}
}
表 1 交错 GridView 可配置的属性
属性 |
说明 |
item_margin | The margin around each grid item (default 0dp). |
column_count | The number of columns displayed. Will override column_count_portrait and column_count_landscape if present (default 0). |
column_count_portrait | The number of columns displayed when the grid is in portrait (default 2). |
column_count_landscape | The number of columns displayed when the grid is in landscape (default 3). |
grid_paddingLeft | Padding to the left of the grid. Does not apply to headers and footers (default 0). |
grid_paddingRight | Padding to the right of the grid. Does not apply to headers and footers (default 0). |
grid_paddingTop | Padding to the top of the grid. Does not apply to headers and footers (default 0). |
grid_paddingBottom | Padding to the bottom of the grid. Does not apply to headers and footers (default 0). |
参考资料
Android 交错 GridView的更多相关文章
- Android中GridView通过自定义适配器(未优化)实现图文视图排列
Android中GridView组件用来以网格方式排列视图,与矩阵类似,当屏幕上有很多元素(文字.图片或其他元素)需要显示时,可以使用该组件.下面我们通过代码实现如下图例(为了方便截图,将事件处理(土 ...
- Android中GridView拖拽的效果【android进化三十六】
最 近看到联想,摩托罗拉等,手机launcher中有个效果,进入mainmenu后,里面的应用程序的图标可以拖来拖去,所以我也参照网上给的代码,写了 一个例子.还是很有趣的,实现的流畅度没有人家的 ...
- Android中GridView的实现实例
实现效果: activity文件代码: package com.tmacsky; import android.app.Activity; import android.os.Bundle; impo ...
- Android中GridView拖拽的效果
最 近看到联想,摩托罗拉等,手机launcher中有个效果,进入mainmenu后,里面的应用程序的图标可以拖来拖去,所以我也参照网上给的代码,写了 一个例子.还是很有趣的,实现的流畅度没有人家的那么 ...
- android 31 GridView
GridView:网格列表,也支持适配器. package com.sxt.day05_01; import java.util.ArrayList; import java.util.List; i ...
- Android的GridView和Gallery结合Demo
Android的GridView和Gallery结合Demo Demo介绍:首页是一个GridView加载图片,竖屏时显示3列图片,横屏时显示4列图片;并且对图片进行大小限制和加灰色边框处理. 点击某 ...
- Android中GridView的使用——使用自带的SimpleAdapter(简单适配器)
GridView一直是一个系统登录后以九宫格方式展现功能子模块的最佳选择,经过试验和网上资料的查阅,现把实现方式总结一下: 一直是通过自定义Adapter方式,在getView()方法中设置图片的显示 ...
- 从头学起android<GridView网格视图.二十八.>
GridView基于组件的网络格所有的形式的组分的,例如:当制作专辑,所有的图片将在相同的尺寸在不同的显示格在孩子,是否能够依靠这个组件完成.此组件的继承结构参见例如下面: java.lang.Obj ...
- Android中用GridView实现九宫格的两种方法(转)
Android中用GridView实现九宫格的两种方法http://blog.csdn.net/shakespeare001/article/details/7768455 1.传统办法:实现一个继承 ...
随机推荐
- 如何修改UITableView每个cell的分隔线和左边的距离?
在ios7中,UITableViewCell左侧会有默认15像素的空白.这时候,设置setSeparatorInset:UIEdgeInsetsZero 能将空白去掉.但是在ios8中,设置setSe ...
- JS 日常
判断一个字符串是否在另一个字符串里面 var str = 'bblText'; if(str.indexOf("Text") > 0) alert("包含了Tex ...
- 希尔排序(Shell's Sort)的C语言实现
原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 希尔排序(Shell's Sort)又称“缩小增量排序”(Diminishing Incre ...
- java线程同步问题
Java面试当中,线程可以说是必考内容,在看面试题的时候发现一遍很全的讲解Java面试题的博客:http://blog.csdn.net/csh624366188/article/details/80 ...
- IDF 实验室部分题目WriteUp
前天花了一个下午的时间刷了几道IDF实验室的题目, 这个网站实在是有点冷清, 题目也比较少, 所以就被我和师兄们刷榜了2333... 因为我最先开始做, 所以就干脆刷到第一去了. 题目很水, 切莫见怪 ...
- C语言学习--链表
#include "node.h" #include<stdio.h> #include<stdlib.h> //typedef struct _node ...
- RUBY,玩玩~~~
我觉得吧,这东瀛的红宝石,也得玩玩,毕竟,RUBY ON RAILS,PUPPET等也是一股力量. 作为混IT圈的,知道总没坏处. 就是感觉和C,C++,JAVA,C#,PHP,甚至PYTHON的感觉 ...
- Codeforces Round #312 (Div. 2)小结
爆炸了爆炸了...E题一个裸线段树没打完,A题wa了半天...... 爆炸了爆炸了....爆炸了爆炸了....rank270+滚粗 以后还是得多做模拟题...
- (转)C++ 编程规范
转载地址:http://www.cnblogs.com/len3d/archive/2008/02/01/1061902.html C/C++编码规范 今天人们越来越明白软件设计更多地是一种工程,而不 ...
- ISNULL-sqlserver语句
语法 ISNULL ( check_expression , replacement_value ) 参数 check_expression 将被检查是否为 NULL的表达式.check_expres ...