Android瀑布流控件——AndroidStaggeredGrid

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

特性

  • 设置列数,可以分别为横屏和竖屏指定不同的值
  • 屏幕方向改变时保持项的添加顺序不改变
  • 设置列表项之间的间隔
  • 支持添加header和footer
  • 支持OnScrollListener接口
下面是etsy开发的app的一个截图
这里我们看一下具体的使用方法
首先将AndroidStaggeredGrid项目导入eclipse,像这样
Android瀑布流控件——AndroidStaggeredGrid_第1张图片
其中的StaggeredGridView就是要使用的瀑布流控件。导入后新建一个Android Project,
Android瀑布流控件——AndroidStaggeredGrid_第2张图片
添加资源文件activity_main.xml


    

column_count指定列数,landscape、portrait分别指定横屏和竖屏,item_margin指定项之间的间隔。
之后在MainActivity中绑定资源,添加数据
private StaggeredGridView mGridView;
	
	@Override
	protected 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 {

		@Override
		public int getCount() {
			return DATA.length;
		}

		@Override
		public Object getItem(int position) {
			return DATA[position];
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public 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的用法完全一样。运行一下
Android瀑布流控件——AndroidStaggeredGrid_第3张图片
背景色是这几个值
private static final int[] COLOR = new int[] {
		0xff33b5e5, 0xffaa66cc, 0xff99cc00, 0xffffbb33, 0xffff4444
	};

样子不太好看,美化一下,StaggeredGridView会根据列的个数计算列宽,因此我们可以指定每个项的高度,修改一下getView()方法
@Override
		public 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
    }

再次运行的结果
Android瀑布流控件——AndroidStaggeredGrid_第4张图片
到这里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);
        }
    }

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


你可能感兴趣的:(Android,Android动效实验室)