博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 交错 GridView
阅读量:4983 次
发布时间:2019-06-12

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

本文演示在你的 Android 应用程序中显示交错 GridView(Staggered GridView )。

交错 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:

,并导入到项目。

  • 把 StaggeredGridView 放到你的布局——activity_sgv.xml
 
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
 
android:id="@+id/panel_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >
 
 
android:id="@+id/imgView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
 
 
自定义行应该包含
DynamicHeightImageView
DynamicHeightTextView
  • 自定义 adapter
public class SampleAdapter extends ArrayAdapter
{
 
private static final String TAG = "SampleAdapter";
 
private final LayoutInflater mLayoutInflater;
private final Random mRandom;
private static final SparseArray
sPositionHeightRatios = new SparseArray
();
 
public SampleAdapter(Context context, int textViewResourceId,
ArrayList
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
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
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
generateData() {
ArrayList
listData = new ArrayList
();
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).

 

参考资料


 

转载于:https://www.cnblogs.com/liuning8023/p/3957380.html

你可能感兴趣的文章
《Android开发卷——自定义日期选择器(三)》
查看>>
游里工夫独造微一一小平邦彦传
查看>>
HTML5 JSON ( tuple => Object => JSON => Object=> Elements_of_tuple )
查看>>
#2006 - MySQL server has gone away 问题解决方法 (全) (转)
查看>>
php学习笔记4--php中的变量作用域
查看>>
D1格式是720*576还是704*576 分类: 生活百科 ...
查看>>
V4L2驱动的移植与应用(三) 分类: arm-linux-Ubunt...
查看>>
服务级后门自己做——创建服务 分类: VC++ ...
查看>>
push本地代码到github发生错误的解决办法
查看>>
设置遮罩层
查看>>
Catalyst 3850 升级-1
查看>>
static
查看>>
python模块之time模块
查看>>
layui中的html怎样接收后台的值,layui框架与SSM前后台交互的方法
查看>>
Skulpt在线模拟运行Python工具
查看>>
287.软件测试概述
查看>>
297.白盒测试
查看>>
新闻客户端的突破与创新
查看>>
网络通信引擎ICE的使用
查看>>
js滚动事件实现滚动触底加载
查看>>