AndroidStaggeredGrid是etsy实现的一个android瀑布流控件,没有继承ListView和Gridview,而是从更深层的AbsListVew着手实现,项目地址在这里https://github.com/etsy/AndroidStaggeredGrid。

特性

  • 设置列数,可以分别为横屏和竖屏指定不同的值
  • 屏幕方向改变时保持项的添加顺序不改变
  • 设置列表项之间的间隔
  • 支持添加header和footer
  • 支持OnScrollListener接口
下面是etsy开发的app的一个截图
这里我们看一下具体的使用方法 首先将AndroidStaggeredGrid项目导入eclipse,像这样 其中的StaggeredGridView就是要使用的瀑布流控件。导入后新建一个Android Project,
添加资源文件activity_main.xml
    
column_count指定列数,landscape、portrait分别指定横屏和竖屏,item_margin指定项之间的间隔。 之后在MainActivity中绑定资源,添加数据
private StaggeredGridView mGridView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mGridView = (StaggeredGridView) findViewById(R.id.grid_view);mGridView.setAdapter(new MyAdapter());}

private class MyAdapter extends BaseAdapter {@Overridepublic int getCount() {return DATA.length;}@Overridepublic Object getItem(int position) {return DATA[position];}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {convertView = new TextView(MainActivity.this);}TextView view = (TextView) convertView;view.setText(DATA[position]);view.setBackgroundColor(COLOR[position % 5]);view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);view.setGravity(Gravity.BOTTOM);view.setTextColor(Color.WHITE);return view;}}private static final String[] DATA = new String[] {"Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",        "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",        "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",        "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",        "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",        "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",        "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",        "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",        "Baylough", "Beaufort", "Beauvoorde"};

因为StaggeredGridView也继承自AbsListView,所以和ListView、GridView的用法完全一样。运行一下
背景色是这几个值
private static final int[] COLOR = new int[] {0xff33b5e5, 0xffaa66cc, 0xff99cc00, 0xffffbb33, 0xffff4444};

样子不太好看,美化一下,StaggeredGridView会根据列的个数计算列宽,因此我们可以指定每个项的高度,修改一下getView()方法
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {convertView = new TextView(MainActivity.this);LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);convertView.setLayoutParams(lp);}TextView view = (TextView) convertView;view.setText(DATA[position]);view.setBackgroundColor(COLOR[position % 5]);view.setGravity(Gravity.BOTTOM);view.setTextColor(Color.WHITE);LayoutParams lp = (LayoutParams) view.getLayoutParams();lp.height = (int) (getPositionRatio(position) * 200);view.setLayoutParams(lp);return view;}

其中计算项高的方法是从staggeredGridView提供的sample中提出来的,就是根据位置得到一个随机的比例
private final Random mRandom = new Random();    private static final SparseArray sPositionHeightRatios = new SparseArray();private double getPositionRatio(final int position) {        double ratio = sPositionHeightRatios.get(position, 0.0);        if (ratio == 0) {            ratio = getRandomHeightRatio();            sPositionHeightRatios.append(position, ratio);        }        return ratio;    }    private double getRandomHeightRatio() {        return (mRandom.nextDouble() / 2.0) + 1.0; // height will be 1.0 - 1.5 the width    }

再次运行的结果
到这里AndroidStaggeredGrid的使用方法就介绍完了, 为列表项添加点击事件setOnItemClickListener,在上面我们可以看到在项目文件中还提供了两个DynamicHeightImageview和DynamicHeightTextView,这两个视图就是如果指定了宽高比,会在绘制的时候保持该比例,具体操作看下面这几行
@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        if (mHeightRatio > 0.0) {            // set the image views size            int width = MeasureSpec.getSize(widthMeasureSpec);            int height = (int) (width * mHeightRatio);            setMeasuredDimension(width, height);        }        else {            super.onMeasure(widthMeasureSpec, heightMeasureSpec);        }    }

在实际应用中我们可以定义更加复杂的列表项。

更多相关文章

  1. ReactNative入门-Android原生项目转RN项目
  2. Android(安卓)NoSQL之SnappyDB
  3. Android程序开发0基础教程(一)
  4. Android合并两个APP的具体做法(掌握)
  5. android基于opencv的车牌识别,高识别率
  6. Android伸手党系列之四:Android项目开发常用技术
  7. 【Android(安卓)Studio】eclipse项目导入Android(安卓)Studio
  8. Android(安卓)App Ant打包
  9. 《Android经验分享》周刊第8期

随机推荐

  1. Android编译过程详解(三)
  2. Android布局文件layout.xml的一些属性值
  3. Android4: 请放弃使用Theme.Dialog
  4. Android布局详解(一)
  5. 用EditText控件的属性inputType
  6. Android(安卓)Framework中添加AIDL文件编
  7. android 预定义样式简述
  8. android GridView android:stretchMode="
  9. Android(安卓)Status bar添加耳机图标
  10. android 编译