利用 RecyclerView 实现垂直交错的网格
来源:互联网 发布:java foreach能倒序 编辑:程序博客网 时间:2024/05/17 21:52
效果如下(关于 RecyclerView 见前文):
MainActivity.java :
package com.crazy.simplerecyclerviewof;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;public class MainActivity extends AppCompatActivity implements SimpleItemAdapter.OnItemClickListener{ private RecyclerView mRecyclerView; private SimpleItemAdapter mAdapter; /* 布局管理器 */ private GridLayoutManager mVerticalGridManager; /* 修饰 */ private ConnectorDecoration mConnectors; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRecyclerView = new RecyclerView(this); mVerticalGridManager = new GridLayoutManager(this, 2, LinearLayoutManager.VERTICAL, false); // 垂直网格的连接线修饰 mConnectors = new ConnectorDecoration(this); // 交错垂直网格 mVerticalGridManager.setSpanSizeLookup(new GridStaggerLookup()); mAdapter = new SimpleItemAdapter(this); mAdapter.setOnItemClickListener(this); mRecyclerView.setAdapter(mAdapter); // 对所有连接应用边缘修饰 mRecyclerView.addItemDecoration(new InsetDecoration(this)); // 默认为垂直布局 selectLayoutManager(R.id.action_grid_vertical); setContentView(mRecyclerView); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.layout_options, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { return selectLayoutManager(item.getItemId()); } private boolean selectLayoutManager(int id) { switch (id){ case R.id.action_grid_vertical: mRecyclerView.setLayoutManager(mVerticalGridManager); mRecyclerView.addItemDecoration(mConnectors); return true; case R.id.action_add_item: // 插入新的项 mAdapter.insertItemAtIndex("百家姓:", 1); return true; case R.id.action_remove_item: // 删除第一项 mAdapter.removeItemAtIndex(1); return true; default: return false; } } @Override public void onItemClick(SimpleItemAdapter.ItemHolder item, int position) { Toast.makeText(this, item.getSummary(), Toast.LENGTH_SHORT).show(); }}
需要让适配器将数据与视图关联起来:
SimpleItemAdapter.java :
package com.crazy.simplerecyclerviewof;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class SimpleItemAdapter extends RecyclerView.Adapter<SimpleItemAdapter.ItemHolder> { /** * 单击处理程序的接口,与 AdapterView 不同, * RecyclerView 没有自己的内部接口 */ public interface OnItemClickListener { public void onItemClick(ItemHolder item, int position); } private static final String[] ITEMS = { "赵...", "钱...", "孙...", "李...", "周...", "吴...", "郑...", "王...", "冯...", "陈...", "楮...", "卫..." }; private List<String> mItems; private OnItemClickListener mOnItemClickListener; private LayoutInflater mLayoutInflater; public SimpleItemAdapter(Context context) { mLayoutInflater = LayoutInflater.from(context); // 创建虚拟项的静态列表 mItems = new ArrayList<>(); mItems.addAll(Arrays.asList(ITEMS)); mItems.addAll(Arrays.asList(ITEMS)); } /** * 创建 */ @Override public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = mLayoutInflater.inflate(R.layout.collection_item, parent, false); // 创建新的视图 return new ItemHolder(itemView, this); } /** * 绑定 */ @Override public void onBindViewHolder(ItemHolder holder, int position) { // 把 position 位置处的数据附加到新的视图 holder.setTitle("Item #" + (position + 1)); holder.setSummary(mItems.get(position)); } @Override public int getItemCount() { return mItems.size(); } public OnItemClickListener getOnItemClickListener() { return mOnItemClickListener; } public void setOnItemClickListener(OnItemClickListener listener) { mOnItemClickListener = listener; } /* 管理数据集修改的方法 */ public void insertItemAtIndex(String item, int position) { mItems.add(position, item); // 通知视图触发变化动画 notifyItemInserted(position); } public void removeItemAtIndex(int position) { if (position >= mItems.size()) return; mItems.remove(position); // 通知视图触发变化动画 notifyItemRemoved(position); } /** * 用作与子项关联的元数据(例如当前位置和稳定的 ID)的存储位置, * 具体的实现通常还提供对视图内部字段的直接访问,从而尽量减少对 findViewById() 的重复调用 */ public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ private SimpleItemAdapter mParent; private TextView mTitleView, mSummaryView; public ItemHolder(View itemView, SimpleItemAdapter parent) { super(itemView); itemView.setOnClickListener(this); mParent = parent; mTitleView = (TextView)itemView.findViewById(R.id.text_title); mSummaryView = (TextView)itemView.findViewById(R.id.text_summary); } public void setTitle(CharSequence title) { mTitleView.setText(title); } public void setSummary(CharSequence summary) { mSummaryView.setText(summary); } public CharSequence getSummary() { return mSummaryView.getText(); } @Override public void onClick(View v) { // ViewHolder 处理子视图上的单击事件,并将其发送回在适配器上定义的公共监听接口 // 这样 ViewHolder 就可以在最后的监听器回调中添加位置数据 final OnItemClickListener listener = mParent.getOnItemClickListener(); if (listener != null) { listener.onItemClick(this, getPosition()); } } }}
交错网格,继承 SpanSizeLookup:
GridStaggerLookup.java :
package com.crazy.simplerecyclerviewof;import android.support.v7.widget.GridLayoutManager;/** * 该类用于生成交错效果,要么 1 行 2 列,要么 1 行 1 列 */public class GridStaggerLookup extends GridLayoutManager.SpanSizeLookup { @Override public int getSpanSize(int position) { // 每隔 3 个位置占据 2 列,其他位置则占 1 列 int pos = position % 3 == 0 ? 2 : 1; return pos; }}
设置页边距:
InsetDecoration.java :
package com.crazy.simplerecyclerviewof;import android.content.Context;import android.graphics.Rect;import android.support.v7.widget.RecyclerView;import android.view.View;/** * 为每个子项提供页边距 */public class InsetDecoration extends RecyclerView.ItemDecoration { private int mInsetMargin; public InsetDecoration (Context context) { super(); mInsetMargin = context.getResources().getDimensionPixelOffset(R.dimen.inset_margin); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); // 对子视图的所有 4 个边界应用计算得出的页边距 outRect.set(mInsetMargin, mInsetMargin, mInsetMargin, mInsetMargin); }}
连接线 ItemDecoration :
ConnectorDecoration.java :
package com.crazy.simplerecyclerviewof;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.RecyclerView.ItemDecoration;import android.view.View;/** * 在主要和次要网格项之间绘制连接线 */public class ConnectorDecoration extends ItemDecoration { private Paint mLinePaint; private int mLineLength; public ConnectorDecoration(Context context) { super(); mLineLength =context.getResources() .getDimensionPixelOffset(R.dimen.inset_margin); int connectorStroke = context.getResources() .getDimensionPixelOffset(R.dimen.connector_stroke); // 允许锯齿 mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLinePaint.setColor(Color.RED); mLinePaint.setStyle(Paint.Style.STROKE); mLinePaint.setStrokeWidth(connectorStroke); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { final RecyclerView.LayoutManager manager = parent.getLayoutManager(); // 遍历子视图,并在未占据两列的每个子项上绘制中心线 for (int i = 0; i < parent.getChildCount(); i++) { final View child = parent.getChildAt(i); boolean isLarge = parent .getChildViewHolder(child) .getPosition() % 3 == 0; // 得到视图当前所在的位置,以此绘制线段 if (!isLarge) { final int childLeft = manager.getDecoratedLeft(child); final int childRight = manager.getDecoratedRight(child); final int childTop = manager.getDecoratedTop(child); final int x = childLeft + ((childRight - childLeft) / 2); c.drawLine(x, childTop - mLineLength, x, childTop + mLineLength, mLinePaint); } } }}
collection_item.xml :
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="8dp" android:background="#CCF" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/text_title" android:textAppearance="?android:textAppearanceLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_summary" android:textAppearance="?android:textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
dimens.xml :
<resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="fab_margin">16dp</dimen> <dimen name="inset_margin">8dp</dimen> <dimen name="connector_stroke">2dp</dimen></resources>
layout_options.xml :
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.crazy.extendibleview.MainActivity"> <!--app:showAsAction="ifRoom" 如果有位置才显示,不然就出现在右边的三个点中--> <item android:id="@+id/action_add_item" android:title="Add Item" android:icon="@android:drawable/ic_menu_add" app:showAsAction="ifRoom" /> <item android:id="@+id/action_remove_item" android:title="Remove Item" android:icon="@android:drawable/ic_menu_delete" android:showAsAction="ifRoom" /> <!--app:showAsAction="ifRoom" 不显示在界面上,只让出现在右边的三个点中--> <item android:id="@+id/action_grid_vertical" android:title="Vertical Grid" android:showAsAction="never" /></menu>
0 0
- 利用 RecyclerView 实现垂直交错的网格
- 使用StaggeredGridLayoutManager实现交错式网格布局
- 自定义RecyclerView之垂直和网格转换
- 自定义RecyclerView实现垂直滑动的ViewPager
- recyclerview 实现正方形网格效果
- Android——实现酷炫的RecyclerView心形交错下拉刷新动画
- RecyclerView实现瀑布流,网格等
- Delphi 利用API实现网格内组件的嵌入
- RecyclerView 实现瀑布流交错效果,并使最后一行子View高度占满RecyclerView
- RecyclerView 实现瀑布流交错效果,并使最后一行子View高度占满RecyclerView
- RecyclerView重写网格的布局管理器
- Android RecyclerView 的 网格布局 ItemDecoration
- 自定义RecyclerView的网格分割线
- Android实现交错的GridView视图
- 利用C#实现图片的垂直镜像
- 利用自定义的 RecyclerView 实现相册的滑动功能
- 利用RecyclerView实现listview布局
- 利用 ItemTouchHelper 实现 RecyclerView 的侧滑删除
- 【郝斌数据结构自学笔记】57-59_递归8 _ 汉诺塔_1线性结构总复习 2线性结构和非线性结构关系 3栈队列链表数组之间的关系【重点】
- 在win10+Linux Ubuntu双系统下安装win xp三系统的痛苦经历
- Java String StringBuffer StringBuilder
- Android PullZoomView:PullToZoomListViewEx(1)
- HDU 1207 汉诺塔II DP
- 利用 RecyclerView 实现垂直交错的网格
- CStdioFile Class
- Android
- Parquet_3. 在 Impala, Hive, Pig, MR中使用 Parquet File -- 待完善
- 【C语言提高30】二级指针强化训练
- 【郝斌数据结构自学笔记】60-65_树的定义_树的专业术语解释_树的分类_二叉树连续存【重点】_二叉树的链式存储_普通树的存储
- 连接数据库
- DynamicAPK基本概念
- MongoDB中的_id和ObjectId