Android staggered GridView and androidgridview

Source: Internet
Author: User

Android staggered GridView and androidgridview
Download Demo staggered GridView

The staggered GridView is only a GridView with unequal rows and multiple columns. You may have used Pinterest, Expedia or Etsy Android app.

Currently, there are two or three good open source libraries.

Staggered GridView Library

  • Staggered GridView by Etsy
  • Staggered GridView by Maurycy Wojtowicz

The following describes the most popular Etsy staggered gridview.

Etsy staggered GridView

The custom staggered GridView is based onAbsListViewClass extension, of course, it also supportsAbsListView. OnScrollListener.

Function
  • You can configure the number of horizontal and vertical columns.
  • The position of the asynchronous row that varies in different directions.
  • Configurable margin (margin)
  • Supports headers and footers ).
  • Internal padding does not affect the header and footer.

Etsy's staggered gridview does not support long-pressed events and Selector drawables, while Maurycy's staggered gridview supports long-pressed events.

Environment
  • Windows 2008 R2 64-bit
  • Eclipse ADT V22.6.2, Android 4.4.2 (API 19)
  • SAMSUNG GT-8618, Android OS 4.1.2
Project Structure

Figure 1 Project Structure

  • The StaggeredGrid project is the com. etsy. android. grid library.
  • The StaggeredGridDemo project is an example.
Example: Etsy staggered GridView

Figure 2 demonstrate staggered GridView

  • Download/include the com. etsy. android. grid Library

Currently, the com. etsy. android. grid library is only configured to be generated using Gradle. Therefore, if you use Android Studio, you can directly include this library as the gradle dependency. If you use Eclipse/Ant, you must perform additional steps.

For the Android Studio environment:

repositories {
    mavenCentral()
}
 
dependencies {
    compile 'com.etsy.android.grid:library:x.x.x' // read below comment
}

For Eclipse/Ant build:

Download com. etsy. android. grid and import it to the project.

  • Put StaggeredGridView in your layout -- 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" />
  • Define row layout for 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>

Custom rows should containDynamicHeightImageViewOrDynamicHeightTextView.

  • Custom 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
    }
}

The custom adapter class is used to display images with dynamic heights in the staggered GridView. In addition, the Universal image loader library is used to asynchronously load images.

  • Set the custom adapter to 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();
    }
}

Table 1 configurable properties of the staggered GridView

Attribute

Description

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 ).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.