使用RecyclerView

RecyclerView 是一种新的ViewGroup 用来生成基于适配器的view的方式,可以看作是ListViewGridView 的方式,优势在于RecyclerView拥有更加可扩展的矿建,而且提供了生成水平和垂直布局的能力。当你的数据集合动态的根据用户的动作或者网络事件而改变时推荐使用。
- RecyclerView.Adapter :处理数据集合并且将数据绑定到视图上
- LayoutManager 帮助定位项的位置
- ItemAnimator 对于常见的操作比如添加删除进行动画化
这里写图片描述
此外,它还提供对于ListView中项的动画的支持,而且支持ViewHolder 模式,这一模式已经被整合到新的框架中了。

和ListView的比较

  • 对于适配器中ViewHolder的要求:ListView的适配器不要求使用ViewHolder提高表现,而相反,实现RecyclerView的适配器需要使用ViewHolder模式。
  • 自定义item布局 : ListView只支持竖直的项布局而且不能自定义,而RecyclerView.Manager允许各式的布局包括水平列表或者交错的网格
  • 简单的动画 : ListView对于项的动画没有特别的规定,而RecyclerView有RecyclerView.ItemAnimator类用来处理项的动画
  • 数据源处理 : ListView对于不同的数据源有不同的适配器例如ArrayAdapterCursorAdapter 分别对应数组和数据库。而RecyclerView要求自定义实现将数据提供给适配器。
  • 项的摆放 : ListView有android:divider 属性简单的将列表中的项分离开,而RecyclerView有RecyclerView.ItemDecoration对象进行手动的分离的设置
  • 手动检测点击 : ListVIiew有AdapterView.OnItemClickListener接口将点击事件绑定到列表中的项上面。而后者只支持RecyclerView.OnItemTouchListener管理单独的点击事件,但是没有内置的点击处理。

RecyclerView 的组件

LayoutManagers

RecyclerView需要布局管理器和适配器的对象,布局管理器负责将视图放置在RecyclerView中,并且决定何时重新使用对于用户不可见的视图。
内置的布局管理器:
- LinearLayoutManager 在水平或者竖直的列表中展示项
- GridLayoutManager 将项展示在网格中
- StagegeredGridLayoutManager 在格栅视图中展示
为了创建自定义的管理器需要继承RecyclerView.LayoutManager

LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
GridLayoutManager manager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);//有俩列columns
manager,setSpanSizeLookup(
    new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            //每隔一行合并两列
            return (position % 3 == 0 ? 2 : 1);
        }
});
//交错的窗格
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
//不对缝隙做处理
manager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);

RecyclerView.Adapter

包含了一种新的适配器,与我们之前使用的有些相似,但也有其独特性,例如要求ViewHolder,我们需要重写两个主要方法:一个是加载view和ViewHolder,另外一个是将数据绑定到视图上,好的地方在于对于第一种方法我们只在需要创建新的view时候调用,不用检查是否用于了循环。

ItemAnimator

RecyclerView.ItemAnimator 将会对ViewGroup 的修改进行动画化,并通知到适配器。DefaultItemAnimator 可以用于基本的动画化而且不错。

使用RecyclerView

  1. RecyclerView 的支持
  2. 定义模块类来使用数据源
  3. 在活动中加入RecyclerView 展示项
  4. 创建一个自定义的行布局文件并进行加载
  5. 创建RecyclerView.AdapterViewHolder 生成项
  6. 在adapter上绑定数据源来填充RecyclerView

配置

dependencies {
    compile 'com.android.support:recyclerview-v7:23.4.0'
}

定义一个模块

我们定义一个联系人类

public class Contact {
    private String mName;
    private boolean mOnline;

    public Contact(String name, boolean online) {
        mName = name;
        mOnline = online;
    }
    public String getName() {
        return mName;
    }

    public boolean isOnline() {
        return mOnline;
    }
    private static int lastContactId = 0;
    //获得一个用户的列表数组
    public static ArrayList<Contact> createContactList(int numContacts) {
        ArrayList<Contact> contacts = new ArrayList<Contact>();

        for (int i = 1; i <= numContacts; i++) {
            contacts.add(new Contact("person" + ++lastContactId, i <= numContacts / 2));
        }
        return contacts;
    }


}

布局中创建RecyclerView

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

    </android.support.v7.widget.RecyclerView>

自定义项的布局

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        >

    <TextView
        android:id="@+id/contact_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        />

    <Button
        android:id="@+id/message_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textSize="10sp"
        />
</LinearLayout>

创建适配器

作用是将某一位置的对象转换成表中的一项插入。
viewHolder对象作用是描述和提供对于每一行的视图的访问权限的

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder> {
    //对每一项中的views进行直接的引用
    //用来缓存每一项不布局中的views 以便快速访问
    public static class ViewHolder extends RecyclerView.ViewHolder {
        //holder对象应该包含每一项中视图的成员变量
        public TextView nameTextView;
        public Button messageButton;
        //构造方法接受每一项的布局作为参数,存储成员变量以便于访问
        public ViewHolder(View itemView) {
            super(itemView);
            nameTextView = (TextView) itemView.findViewById(R.id.contact_name);
            messageButton = (Button) itemView.findViewById(R.id.message_button);
        }

    }
    //首先创建一个存储联系人的成员变量
    private List<Contact> mContacts;
    //存储context变量
    private Context mContext;
    //传递联系人数组到构造方法中和
    public ContactsAdapter(Context context, List<Contact> contacts) {
        mContacts = contacts;
        mContext = context;
    }
    //为了方便的访问Context变量

    public Context getmContext() {
        return mContext;
    }
//加载item布局并且创造holder对象
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        //加载自定义布局
        View contactView = inflater.inflate(R.layout.item_contact, parent, false);
        //返回一个holder实例
        ViewHolder viewHolder = new ViewHolder(contactView);
        return viewHolder;
    }
    //通过holder将数据填充进项

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //得到数据的对象
        Contact contact = mContacts.get(position);
        //设置itemView的内容
        TextView textView = holder.nameTextView;
        textView.setText(contact.getName());
        Button button = holder.messageButton;
        button.setText("Message");
    }
    //返回项的数量

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

将适配器绑定到RecyclerView上

public class MainActivity extends AppCompatActivity {
    ArrayList<Contact> contacts;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView rvContacts = (RecyclerView) findViewById(R.id.rvContacts);
        //初始化联系人列表
        contacts = Contact.createContactList(20);
        //创建适配器
        ContactsAdapter adapter = new ContactsAdapter(this, contacts);
        //绑定适配器
        rvContacts.setAdapter(adapter);
        //设置布局g管理器
        rvContacts.setLayoutManager(new LinearLayoutManager(this));
    }
}

我们向增加数据需要将新增的数据加入到现有列表中并且对适配器进行通知,通知相关的方法
这里写图片描述
单独增加一个数据时

// Add a new contact
contacts.add(0, new Contact("Barney", true));
// Notify the adapter that an item was inserted at position 0
adapter.notifyItemInserted(0);

添加一个列表

 //现有项数
                int curSize = adapter.getItemCount();
                //添加项
                contacts.addAll(Contact.createContactList(1));
                adapter.notifyItemRangeChanged(curSize, contacts.size());

滑动向某一位置:recyclerView.scrollToPosition(0);
在底部增加项时通知适配器滑动到相应位置:

adapter.notifyItemInserted(contacts.size() - 1);  // contacts.size() - 1 is the last element position
rvContacts.scrollToPosition(mAdapter.getItemCount() - 1); // update based on adapter 

配置RecyclerView

  1. 外观:针对每项是否为同一高度进行优化:recyclerView.setHasFixedSize(true);
  2. 布局:我们可以设置项的布局为网格布局或者线性布局,并且设置各种属性
// Setup layout manager for items
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// Control orientation of the items
// also supports LinearLayoutManager.HORIZONTAL
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// Optionally customize the position you want to default scroll to
layoutManager.scrollToPosition(0);
// Attach layout manager to the RecyclerView
recyclerView.setLayoutManager(layoutManager);
// First param is number of columns and second param is orientation i.e Vertical or Horizontal
StaggeredGridLayoutManager gridLayoutManager = 
    new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
// Attach the layout manager to the recycler view
recyclerView.setLayoutManager(gridLayoutManager);
  1. 装饰:可以用来在网格布局或者交错布局中进行设置项与项之间的间距通过对RecyclerView.ItemDecoration进行设置。
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private final int mSpace;
    public SpacesItemDecoration(int space) {
        this.mSpace = space;
    }
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left = mSpace;
        outRect.right = mSpace;
        outRect.bottom = mSpace;
        // Add top margin only for the first item to avoid double space between items
        if (parent.getChildAdapterPosition(view) == 0)
            outRect.top = mSpace;
    }
}

使用:SpacesItemDecoration decoration = new SpacesItemDecoration(16);
mRecyclerView.addItemDecoration(decoration);
4. 动画:本身支持进入,移动和删除的动画相关类为ItemAnimaor 自动的动画效郭由DefaultItemAnimator ,目前最快的动画实现方式为使用第三方库recyclerview-animators library 网址为https://github.com/wasabeef/recyclerview-animators

//If you are using a RecyclerView 23.1.0 (released Oct 2015) or higher.

dependencies {
  // jCenter
  compile 'jp.wasabeef:recyclerview-animators:2.2.3'
}
//If you are using a RecyclerView 23.0.1 or below.

dependencies {
  // jCenter
  compile 'jp.wasabeef:recyclerview-animators:1.3.0'
}

简单使用:recyclerView.setItemAnimator(new SlideInUpAnimator());

后续还包括对于点击事件的处理。。。http://guides.codepath.com/android/Using-the-RecyclerView

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值