最近买了一本书《Android进阶之光》,希望能够让自己提高Android知识,走向进阶之路。
在看到RecycleView的讲解部分时,确实挺容易理解的,也自己敲了一遍代码,对RecycleView的使用理解更加深刻。RecycleView具有高度的解耦,异常灵活,RecycleView不但可以替代ListView、GridView等控件。还可以通过设置它提供的不同的LayoutManager、ItenDecoration、ItemAnimator可实现更加丰富多彩的效果。但是呢设置列表的分割线需要自己自定义,还有列表的点击事件需要自己去实现。
效果图:
image.png那么如何使用RecycleView:
- 配置build.gradle
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
- 使用RecycleView
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private List<String> mListData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListData=new ArrayList<>();
for (int i = 0; i <30; i++) {
mListData.add(i+"");
}
/*List<Integer> mHeights=new ArrayList<>();
for (int i = 0; i < 30; i++) {
mHeights.add((int) ((100+Math.random())+10*i));
}*/
mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
mRecyclerView.addItemDecoration(new
DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
//设置item增加和删除的动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
final RecycleViewMyAdapter adapter=new RecycleViewMyAdapter(mListData,MainActivity.this);
/**
* 实现RecycleView的item的点击效果
*/
adapter.setOnItenClickListener(new RecycleViewMyAdapter.OnItenClickListener() {
//单点击
@Override
public void onItenClick(View view, int position) {
Toast.makeText(MainActivity.this, "点击了第"+position+"条"+"数据"+mListData.get(position), Toast.LENGTH_SHORT).show();
}
//长按点击
@Override
public void onItenLonfClick(View view, final int position) {
//Toast.makeText(MainActivity.this, "长按了第"+position+"条"+"数据"+mListData.get(position), Toast.LENGTH_SHORT).show();
new AlertDialog.Builder(MainActivity.this).setTitle("确定要删除吗?").
setNegativeButton("取消",null).setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Toast.makeText(MainActivity.this, "---"+which, Toast.LENGTH_SHORT).show();
//Toast.makeText(MainActivity.this, "---------------------"+position, Toast.LENGTH_SHORT).show();
adapter.removeData(position);
}
}).show();
}
});
mRecyclerView.setAdapter(adapter);
}
}
和ListView不同,需要设置布局管理器用于设置条目的排列样式,可以是水平或垂直。
mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
- Adapter的设置
Adapter最大的改进就是对ViewHolder进行了封装,我们只需要定义一个ViewHolder继承RecycleView.ViewHolder就可以了。另外,Adapter继承RecycleView.adapter,在onCreateViewHolder中加载条目布局,在onBindViewHolder中将视图与数据进行绑定。
*适配器RecycleView的Adapter
* Created by an on 2017/7/11.
public class RecycleViewMyAdapter extends RecyclerView.Adapter<RecycleViewMyAdapter.ViewHolder> {
private List<String> mListDatas;
private Context mContext;
private static final String TAG = "RecycleViewMyAdapter";
/**
* 通过接口来实现点击、长按等事件
*/
private OnItenClickListener mOnItenClickListener;
private List<Integer> mHeights;
public interface OnItenClickListener {
void onItenClick(View view,int position);
void onItenLonfClick(View view,int position);
}
public void setOnItenClickListener(OnItenClickListener mOnItenClickListener){
this.mOnItenClickListener=mOnItenClickListener;
}
public RecycleViewMyAdapter(List<String> mListData, MainActivity mainActivity) {
this.mContext=mainActivity;
this.mListDatas=mListData;
}
public void removeData(int position){
mListDatas.remove(position);
notifyItemRemoved(position);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_recycle, parent,false);
ViewHolder holder=new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.tv.setText(mListDatas.get(position));
/* ViewGroup.LayoutParams lp= holder.lin.getLayoutParams();
lp.height=mHeights.get(position);
holder.lin.setLayoutParams(lp);*/
if (mOnItenClickListener!=null){
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos=holder.getLayoutPosition();
Toast.makeText(mContext, ""+pos, Toast.LENGTH_SHORT).show();
Log.d(TAG, "onClick: "+pos);
mOnItenClickListener.onItenClick(holder.tv,pos);
}
});
holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos=holder.getLayoutPosition();
Toast.makeText(mContext, ""+pos, Toast.LENGTH_SHORT).show();
mOnItenClickListener.onItenLonfClick(holder.tv,pos);
return false;
}
});
}
}
@Override
public int getItemCount() {
return mListDatas.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView tv;
// private ImageView lin;
public ViewHolder(View itemView) {
super(itemView);
tv= (TextView) itemView.findViewById(R.id.item_tv);
//lin= (ImageView) itemView.findViewById(R.id.img);
}
}
}
- 设置分割线
可以使用RecycleView.addItemDecoration()来加入分割线。
Created by an on 2017/7/11.
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;
private int orientation;
public DividerItemDecoration(Context mContext, int mOrientation) {
final TypedArray a = mContext.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(mOrientation);
}
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) {
if (mOrientation==VERTICAL_LIST){
drawVertical(c,parent);
}else{
drawHorizontal(c,parent);
}
}
/**
* 画水平方向的分割线
* @param c
* @param parent
*/
private 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);
}
}
/**
*画 随之方向
* @param c
* @param parent
*/
private 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());
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);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mOrientation==VERTICAL_LIST){
outRect.set(0,0,0,mDivider.getIntrinsicHeight());
}else{
outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
}
}
}
当然,也可以替代GridView的作用:
修改LinearLayoutManager
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
效果图:
image.png
- 自定义点击事件
列表中的点击事件需要自己定义的。在Adapter中定义接口并提供回调。
/**
* 通过接口来实现点击、长按等事件
*/
private OnItenClickListener mOnItenClickListener;
public interface OnItenClickListener {
void onItenClick(View view,int position);
void onItenLonfClick(View view,int position);
}
public void setOnItenClickListener(OnItenClickListener mOnItenClickListener){
this.mOnItenClickListener=mOnItenClickListener;
}
- 实现瀑布流
只要在Adapter中写一个随机的高度来控制每一个item的高度就可以了,通常高度是有服务器这边来控制的,现在我们随意来一个高度:
List<Integer> mHeights=new ArrayList<>();
for (int i = 0; i < 30; i++) {
mHeights.add((int) ((100+Math.random())+10*i));
}
效果图:
image.png在onCreateViewHolder中设置控件高度
holder.tv.setText(mListDatas.get(position));
ViewGroup.LayoutParams lp= holder.tv.getLayoutParams();
lp.height=mHeights.get(position);
holder.tv.setLayoutParams(lp);
自此,RecycleView替代ListView、GridView并且实现瀑布的功能都已实现。
网友评论