zoukankan      html  css  js  c++  java
  • 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

    项目结构

    2014-09-05_111749_副本

    图 1 项目结构

    • StaggeredGrid 项目是 com.etsy.android.grid 库。
    • StaggeredGridDemo 项目是示例。

    示例:Etsy 交错 GridView

    1_副本

    图 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>
    自定义行应该包含 DynamicHeightImageViewDynamicHeightTextView
    • 自定义 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).

    参考资料


    下载 Demo

  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/liuning8023/p/3957380.html
Copyright © 2011-2022 走看看