您的位置:首页 > 其它

RecyclerView的基本使用

2015-06-24 20:51 423 查看
传统的ListView了最多的优化也只能使用你自定义的一个布局,于是乎出现了RecyclerView这样的更加方便的东西。接下来就简单的说一说它的使用吧:

1.首先 我们要导入jar包,或者在android studio上moudle的build.gradle文件中添加这么一句话

compile 'com.android.support:recyclerview-v7:22.2.0'

2.然后了在布局中加入这个控件

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="fill_parent"
android:layout_height="match_parent"
></android.support.v7.widget.RecyclerView>

3.还要声明一个适配器 recyclerView 可以说是强制性使用了viewholder,这样也还是有好处的,代码如下:

public class SimpleAdapter extends RecyclerView.Adapter<MyViewHolder>{
List<String> dates;
LayoutInflater inflater;
Context context;
public interface OnItemClickListener{
void OnItemClick(View view,int pos);
void OnItemLongClick(View view,int pos);
}
OnItemClickListener clickListener;

public void setOnClickListener(OnItemClickListener listener){
this.clickListener=listener;
}

SimpleAdapter(Context context,List<String> dates){
this.context=context;
this.dates=dates;
inflater=LayoutInflater.from(context);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.list_item,parent,false);

MyViewHolder holder=new MyViewHolder(view);

return holder;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
ViewGroup.LayoutParams ll=holder.itemView.getLayoutParams();
ll.height=(int) (Math.random()*300+100);
holder.itemView.setLayoutParams(ll);
holder.tv.setText(dates.get(position));

if(clickListener!=null){
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos=holder.getLayoutPosition();
clickListener.OnItemClick(v, pos);
}
});
holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos=holder.getLayoutPosition();
clickListener.OnItemLongClick(v,pos);
return  true;
}
});
}

}

@Override
public int getItemCount() {
return dates.size();
}

public void addData(int pos){
dates.add("insert one");
//不是notifydatachanged
notifyItemInserted(pos);
}
public void deleteData(int pos){
dates.remove(pos);
notifyItemRemoved(pos);
}
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView tv;
public MyViewHolder(View itemView) {
super(itemView);
tv= (TextView) itemView.findViewById(R.id.show_text);
}

}

上面的MyViewHolder继承了RecyclerView的viewholder,由于我的布局只有一个textview,所以在viewholde中只有一个textview,假如你的多个布局都是不同的内容,你就应该先重写一个viewholder继承RecyclerView的viewholde,然后为每一个布局实现自己的viewholder。

addData和deleteData方法实现了对列表项的增加和删除,需要注意的就是notifyItemRemoved和notifyItemInserted 而不是平常的notifysetDataChanged。

平时我们经常要用到onclick和onlongclick方法,所以在前面也对这两个进行了自定义。

ViewGroup.LayoutParams ll=holder.itemView.getLayoutParams();
ll.height=(int) (Math.random()*300+100);
holder.itemView.setLayoutParams(ll);
holder.tv.setText(dates.get(position));

这几句代码的功能就是利用随机数产生的高度,模仿瀑布流的实现,简单的布局你可以删掉不需要;

int pos=holder.getLayoutPosition();
clickListener.OnItemLongClick(v,pos);

这里传入的position不是上面参数的position,而是你刷新数据列表之后的位置,因为你前面增加或者删除以后,数据项的position会发生改变,如果是前面参数的position的话,你增加或者删除的时候那个位置都是相同的。

接下来就是activity中代码的解释:

首先还是Recyclerview的获取和基本的方法的实现

recyclerView = (RecyclerView) this.findViewById(R.id.recycler_view);
adapter = new SimpleAdapter(this, dates);
adapter.setOnClickListener(new SimpleAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View view, int pos) {
Toast.makeText(getApplicationContext(),"v--"+pos,Toast.LENGTH_SHORT).show();
}

@Override
public void OnItemLongClick(View view, int pos) {
Toast.makeText(getApplicationContext(),"v-++-"+pos,Toast.LENGTH_SHORT).show();
adapter.deleteData(pos);
}
});
recyclerView.setAdapter(adapter);


Recyclerview需要设置一个Layoutmanager

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);


LayoutManager的不同,我们可以让RecyclerView展现出不同的样式,例如Gridview,LinearLayout的样式,还有StaggerGridLayout的样式,其中StaggerGridLayout高度不一就可以实现瀑布流。

下面是具体的代码:

case R.id.action_listview:
LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager);
break;
case R.id.action_gridview:
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
break;
case R.id.action_stagger:
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.VERTICAL));
break;


我们的ListView可以实现自定义的分割线,这个当然也可以的啦,默认的是没有分割线的!!!

简单的分割线我们可以通过margin实现,背景的反差可以实现简单的分割效果,

接下来告诉大家一个人家定义好的多样化的分割线的类

代码如下:

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)
{
Log.v("itemdecoration", "onDraw()");
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, int itemPosition,
RecyclerView parent)
{
if (mOrientation == VERTICAL_LIST)
{
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}


在Acitvity中我们这样使用:

recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

第二个参数是设置水平还是垂直。

当你这样做了你会发现他的样子还是普通的灰色分割线,因为我们还没有为它指定特殊的样式~~~

先声明一个独特的样式 如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="4dp" ></size>
<gradient android:startColor="#ffff0000" android:centerColor="#ff00ff00" android:endColor="#ff0000ff" android:type="linear"></gradient>
</shape>


完了以后需要在你的style样式文件中添加这么一句话

<item name="android:listDivider">@drawable/divider</item>

为啥要这样做了?

private static final int[] ATTRS = new int[] { android.R.attr.listDivider };

懂了吧?以为它的drawable对象是从style文件中的listDivider获取的 ,所以我们之前要在style文件中添加那么一条.....

到现在为止,实现的RecyclerView的简单使用和添加点击事件,还有分割线的自定义,接下来就剩下最后的特效动画的实现了。

增加和删除肯定酷炫比较好看,

recyclerView.setItemAnimator(new DefaultItemAnimator());

这么一句话就可以简单的设置特效啦,是不是很简单!!!

这个是默认的简单的动画效果,我们也可以自定义效果,Github上有人家定义的一些特效,网址如下
https://github.com/gabrielemariotti/RecyclerViewItemAnimators
大家有兴趣的可以自己去试试看,然后编写自己的特效吧~.~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: