출처 : http://www.journaldev.com/13792/android-gridlayoutmanager-example
Android GridLayoutManager
We’ve implemented a RecyclerView using a LinearLayoutManager here. Now let’s use a GridLayoutManager
to layout the RecyclerView as a grid.
Following is the constructor for a GridLayoutManager.
GridLayoutManager (Context context, int spanCount, int orientation, boolean reverseLayout)
reverseLayout if set true then layout items from end to start.
To set the span size for each item, we invoke the method setSpanSizeLookup
on the GridLayoutManager
Let’s implement RecyclerView using a GridLayoutManager in a new Android Studio project.
Android GridLayoutManager Example Project Structure
The project consists of a single Activity : MainActivity.java
, an adapter class : RecyclerViewAdapter.java
, a DataModel.java
class and a custom GridLayoutManager class AutoFitGridLayoutManager.java
.
The xml layout of the MainActivity.java class is defined in the file activity_main.xml
as
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:fitsSystemWindows="true" tools:context=".MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>
Note: Don’t forget to add the following dependencies for Material Design widgets and CardView
in the build.gradle file.
compile 'com.android.support:cardview-v7:25.1.1' compile 'com.android.support:design:25.1.1'
The DataModel.java
class is given below:
package com.journaldev.recyclerviewgridlayoutmanager;
public class DataModel { public String text; public int drawable; public String color; public DataModel(String t, int d, String c ) { text=t; drawable=d; color=c; } }
The DataModel class will hold the text, drawable icon and background colour of each item cell.
The RecyclerViewAdapter.java class is given below:
package com.journaldev.recyclerviewgridlayoutmanager; import android.content.Context; import android.graphics.Color; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.ArrayList; public class RecyclerViewAdapter extends RecyclerView.Adapter { ArrayList mValues; Context mContext; protected ItemListener mListener; public RecyclerViewAdapter(Context context, ArrayList values, ItemListener itemListener) { mValues = values; mContext = context; mListener=itemListener; } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView textView; public ImageView imageView; public RelativeLayout relativeLayout; DataModel item; public ViewHolder(View v) { super(v); v.setOnClickListener(this); textView = (TextView) v.findViewById(R.id.textView); imageView = (ImageView) v.findViewById(R.id.imageView); relativeLayout = (RelativeLayout) v.findViewById(R.id.relativeLayout); } public void setData(DataModel item) { this.item = item; textView.setText(item.text); imageView.setImageResource(item.drawable); relativeLayout.setBackgroundColor(Color.parseColor(item.color)); } @Override public void onClick(View view) { if (mListener != null) { mListener.onItemClick(item); } } } @Override public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_item, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder Vholder, int position) { Vholder.setData(mValues.get(position)); } @Override public int getItemCount() { return mValues.size(); } public interface ItemListener { void onItemClick(DataModel item); } }
In the above code we’ve defined an ItemListener interface that’ll be implemented in the MainActivity.java class.
The xml layout for each RecyclerView item is given below.recycler_view_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v7.widget.CardView android:id="@+id/cardView" android:layout_width="match_parent" android:layout_height="150dp" card_view:cardCornerRadius="0dp" card_view:cardElevation="@dimen/margin10" card_view:cardMaxElevation="@dimen/margin10" card_view:contentPadding="@dimen/margin10"> <RelativeLayout android:id="@+id/relativeLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:layout_gravity="center"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:tint="@android:color/white" android:padding="5dp" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textColor="@android:color/white" android:layout_below="@+id/imageView" /> </RelativeLayout> </android.support.v7.widget.CardView> </LinearLayout>
The AutoFitGridLayoutManager.java class is given below:
package com.journaldev.recyclerviewgridlayoutmanager; import android.content.Context; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; public class AutoFitGridLayoutManager extends GridLayoutManager { private int columnWidth; private boolean columnWidthChanged = true; public AutoFitGridLayoutManager(Context context, int columnWidth) { super(context, 1); setColumnWidth(columnWidth); } public void setColumnWidth(int newColumnWidth) { if (newColumnWidth > 0 && newColumnWidth != columnWidth) { columnWidth = newColumnWidth; columnWidthChanged = true; } } @Override public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { if (columnWidthChanged && columnWidth > 0) { int totalSpace; if (getOrientation() == VERTICAL) { totalSpace = getWidth() - getPaddingRight() - getPaddingLeft(); } else { totalSpace = getHeight() - getPaddingTop() - getPaddingBottom(); } int spanCount = Math.max(1, totalSpace / columnWidth); setSpanCount(spanCount); columnWidthChanged = false; } super.onLayoutChildren(recycler, state); } }
The span count is dynamically calculated based on the orientation, width and height available.
The MainActivity.java class
is given below:
package com.journaldev.recyclerviewgridlayoutmanager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ItemListener { RecyclerView recyclerView; ArrayList arrayList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.recyclerView); arrayList = new ArrayList(); arrayList.add(new DataModel("Item 1", R.drawable.battle, "#09A9FF")); arrayList.add(new DataModel("Item 2", R.drawable.beer, "#3E51B1")); arrayList.add(new DataModel("Item 3", R.drawable.ferrari, "#673BB7")); arrayList.add(new DataModel("Item 4", R.drawable.jetpack_joyride, "#4BAA50")); arrayList.add(new DataModel("Item 5", R.drawable.three_d, "#F94336")); arrayList.add(new DataModel("Item 6", R.drawable.terraria, "#0A9B88")); RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, arrayList, this); recyclerView.setAdapter(adapter); /** AutoFitGridLayoutManager that auto fits the cells by the column width defined. **/ /*AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500); recyclerView.setLayoutManager(layoutManager);*/ /** Simple GridLayoutManager that spans two columns **/ GridLayoutManager manager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false); recyclerView.setLayoutManager(manager); } @Override public void onItemClick(DataModel item) { Toast.makeText(getApplicationContext(), item.text + " is clicked", Toast.LENGTH_SHORT).show(); } }
- The above class implements the interface
RecyclerViewAdapter.ItemListener
and overrides the methodonItemClick
that’s defined in the adapter class. By doing this, we’ve implemented the RecyclerView Click Listener within our Activity instead of the Adapter class(similar to the standard onItemClickListener defined for a ListView) - A DataModel class holds the details for each RecyclerView item
- The LayoutManager of the RecyclerView can be defined by either instantiating the AutoFitGridLayoutManager class with the column width set as 500 or by invoking the GridLayoutManager class object and setting the number of columns as 2
Let’s see the output of the application with the standard GridLayoutManager code.
As you can see, each row has two items that span the column width in both orientations.
Now comment out the code for simple GridLayoutManager and run the code for AutoFitGridLayoutManager
AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500); recyclerView.setLayoutManager(layoutManager);
The output of the application in action is given below.
As you can see in the above output, when the orientation changes to landscape, each row has three items, thereby dynamically sizing the items to auto-fit the column width.
This brings an end to this tutorial. You can download the final android GridLayoutManager project from the link given below.
'Android > Tip&Tech' 카테고리의 다른 글
Called reconfigure on a bitmap that is in use! This may cause graphical corruption! (0) | 2017.02.14 |
---|---|
List of Android Top 1000 Libraries (0) | 2016.06.08 |
줌인되는 커스텀 리스트 뷰 소스 (0) | 2015.09.04 |
[펌]안드로이드 구글 맵 반경그리기 (1) | 2015.01.25 |
Android ListView CheckBox 스크롤후 없어지는 문제 (0) | 2015.01.24 |