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>

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

    参考资料


    下载 Demo

    http://www.cnblogs.com/liuning8023/p/3957380.html

  • 相关阅读:
    经典卷积神经网络算法(4):GoogLeNet
    经典卷积神经网络算法(3):VGG
    经典卷积神经网络算法(2):AlexNet
    经典卷积神经网络算法(1):LeNet-5
    卷积神经网络入门篇
    人工神经网络实践
    Python操作Oracle数据库:cx_Oracle
    源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性
    实战SpringCloud通用请求字段拦截处理
    Elasticsearch系列---生产集群部署(下)
  • 原文地址:https://www.cnblogs.com/shanzei/p/4647463.html
Copyright © 2011-2022 走看看