@hx
2018-04-27T22:12:03.000000Z
字数 13261
阅读 998
Android
提供三种内置LayoutManager
LinearLayoutManager
:线性布局,横向或者纵向滑动列表
GridLayoutManager
:表格布局
StaggeredGridLayoutManager
:流式布局,例如瀑布流效果
常用类
1.主布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:scrollbars="horizontal"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
2.子布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_margin="1dp"
android:background="@color/colorLine">
<TextView
android:id="@+id/second_text_view"
android:layout_width="72dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="A"
android:textSize="24sp"/>
</FrameLayout>
3-1.Adapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
private Context mContext;
private List<String> mList;
private LayoutInflater mLayoutInflater;
public MyRecyclerViewAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
mLayoutInflater = LayoutInflater.from(context);
}
// 创建ViewHolder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.item, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mTextView.setText(mList.get(position));
}
@Override
public int getItemCount() {
return mList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
public MyViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.second_text_view);
}
}
}
3-2.瀑布流 StaggeredAdapter
public class StaggeredAdapter extends RecyclerView.Adapter<StaggeredAdapter.MyViewHolder> {
private Context mContext;
private List<String> mList;
private LayoutInflater mLayoutInflater;
// 自定义Item高度
private List<Integer> mHeight;
public StaggeredAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
mLayoutInflater = LayoutInflater.from(context);
mHeight = new ArrayList<>();
// 随机高度
for (int i = 0; i < mList.size(); i++) {
mHeight.add((int) (100 + Math.random() * 300));
}
}
// 创建ViewHolder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.item, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// 获取Item 父布局高度
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
layoutParams.height = mHeight.get(position);
// 设置Item 父布局高度
holder.itemView.setLayoutParams(layoutParams);
holder.mTextView.setText(mList.get(position));
}
@Override
public int getItemCount() {
return mList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
public MyViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.second_text_view);
}
}
}
4-1. MainActivity
public class SecondActivity extends AppCompatActivity {
private List<String> mList;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initViews();
initDatas();
MyRecyclerViewAdapter myRecyclerViewAdapter = new MyRecyclerViewAdapter(this, mList);
mRecyclerView.setAdapter(myRecyclerViewAdapter);
// 设置Recycler的布局方法
LinearLayoutManager linearLayoutManager =
new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
// 设置Item间分割线
// mRecyclerView.addItemDecoration(new DividerItemDecoration(
// this, DividerItemDecoration.VERTICAL_LIST));
}
private void initViews() {
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
}
private void initDatas() {
mList = new ArrayList<>();
for (int i = 'A'; i < 'Z'; i++) {
mList.add("" + (char) i);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main2, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_list:
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
break;
case R.id.action_gridView:
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
break;
case R.id.action_horizontalView:
mRecyclerView.setLayoutManager(
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
break;
case R.id.action_staggered:
startActivity(new Intent(SecondActivity.this, StaggeredActivity.class));
break;
case R.id.action_HorizontalGridView:
mRecyclerView.setLayoutManager(
new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.HORIZONTAL));
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
4-2. StaggeredActivity
public class StaggeredActivity extends AppCompatActivity {
private List<String> mList;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initViews();
initDatas();
StaggeredAdapter Staggered = new StaggeredAdapter(this, mList);
mRecyclerView.setAdapter(Staggered);
// 设置Recycler的布局方法
mRecyclerView.setLayoutManager(
new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
}
private void initViews() {
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
}
private void initDatas() {
mList = new ArrayList<>();
for (int i = 'A'; i <= 'Z'; i++) {
mList.add("" + (char) i);
}
}
}
5-1.普通分割线
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
RecyclerView v = new RecyclerView(
parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
5-2. Grid分隔线
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
public DividerGridItemDecoration(Context context) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, State state) {
drawHorizontal(c, parent);
drawVertical(c, parent);
}
private int getSpanCount(RecyclerView parent) {
// 列数
int spanCount = -1;
LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
spanCount = ((StaggeredGridLayoutManager) layoutManager)
.getSpanCount();
}
return spanCount;
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin
+ mDivider.getIntrinsicWidth();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
int childCount) {
LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
return true;
}
}
return false;
}
private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
int childCount) {
LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
return true;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
// StaggeredGridLayoutManager 且纵向滚动
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
childCount = childCount - childCount % spanCount;
// 如果是最后一行,则不需要绘制底部
if (pos >= childCount)
return true;
} else
// StaggeredGridLayoutManager 且横向滚动
{
// 如果是最后一行,则不需要绘制底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition,
RecyclerView parent) {
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
} else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
{
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(),
mDivider.getIntrinsicHeight());
}
}
}
6.设置Item动画
在MyRecyclerViewAdapter
中添加2个方法,然后在MainActivity中设置动画
// 创建添加方法
public void addData(int position) {
mList.add(position, "Insert one");
notifyItemInserted(position);
}
// 创建remove方法
public void removeDate(int position) {
mList.remove(position);
notifyItemRemoved(position);
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_add:
mMyRecyclerViewAdapter.addData(1);
break;
case R.id.action_delete:
mMyRecyclerViewAdapter.removeDate(1);
break;
7.设置点击和长按事件
在MyRecyclerViewAdapter
中创建接口,并在onBindViewHolder()
方法中设置点击和长按事件,然后在MainActivity
中添加代码。
// 创建接口
public interface OnItemClickListener {
void OnItemClick(View view, int position);
void OnItemLongClick(View view, int position);
}
private OnItemClickListener mOnItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.mTextView.setText(mList.get(position));
if (mOnItemClickListener != null) {
// 点击
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int layoutPosition = holder.getLayoutPosition();
mOnItemClickListener.OnItemClick(holder.itemView, layoutPosition);
}
}
});
// 长按
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
int layoutPosition = holder.getLayoutPosition();
@Override
public boolean onLongClick(View view) {
mOnItemClickListener.OnItemLongClick(holder.itemView, layoutPosition);
return true;
}
});
}
}
// 设置点击和长击事件
mMyRecyclerViewAdapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View view, int position) {
TextView textView = (TextView) view.findViewById(R.id.second_text_view);
Toast.makeText(
SecondActivity.this, "点击" + textView.getText() + "位置" + position, Toast.LENGTH_SHORT).show();
}
@Override
public void OnItemLongClick(View view, int position) {
Toast.makeText(
SecondActivity.this, "长按第" + position, Toast.LENGTH_SHORT).show();
}
});