天天看点

Android Recyclerview粘性头部 简单实现

引言

最近好久没写代码了,都是一直在维护之前的项目,由于工作的需要,学习重心最近放在了Js的学习上。以至于,我有个需求要写个Recyclerview列表,我竟然一下子忘记怎么写了,我只能去网上搜索相关的使用方法,后来才觉得写笔记的重要性,一方面自己看自己写的笔记,容易理解,二方面可以帮助到一些开发者遇到和我一样的问题。分享即是收获。

推荐

  1. Recyclerview 的简单使用 http://blog.csdn.net/baidu_31956557/article/details/51908346
  2. Recyclerview 的分类型使用 http://blog.csdn.net/baidu_31956557/article/details/51921158

主题

之前看到过一款购物类的软件,有一个功能,这个功能具体效果:

Android Recyclerview粘性头部 简单实现

我想,这种效果大家一定不陌生吧,我们的手机联系人列表,省市级列表,等等,我这里用到是网上的一个第三方库的方式来实现这种效果。

实现步骤

1.首先以第三方库的方式,在项目中导入库。

库的下载地址:https://github.com/sdsjk/RecyclerView_Head
           

2.编写布局文件,这里只显示一个Recyclerview控件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#aa000000"
    >
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recylerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
           

3 编写java代码,java代码负责控件的初始化,数据的准备,控件适配器的填充等。这里我们来序列化一下步骤:

  1. 控件的初始化
  2. 列表数据源的获取
  3. 设置适配器(重点)
  4. 事件的绑定

    代码的思路结构也是按照上面的步骤

package pushsummary.jzs.com.recyclerview_head;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
    private RecyclerView recylerview;
    private String url = "http://api.funwear.com/mbfun_server/index.php?m=BrandMb&a=getAppBrandListWithSort&osVersion=22&appName=youfanguanfang&source=android&osName=YQ601&version=v4.2.2&deviceId=00000000-35fa-0db9-0da8-19f962cce3ff&cid=1&token=&osCode=android";
    private List<DataBean.DataEntity.BrandInfoEntity> alldata = new ArrayList<>();
    private DataAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        1.控件的初始化
        initView();
        //2.数据的请求
        initData();
        //3.设置适配器
        adapter = new DataAdapter(this, alldata);
        recylerview.setAdapter(adapter);
        adapter.addBean(alldata, this);
        recylerview.setLayoutManager(new LinearLayoutManager(this));

        StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(adapter);
        recylerview.addItemDecoration(headersDecor);
    }
    private void initData() {

        RequestQueue requestQueue = Volley.newRequestQueue(this);
        StringRequest request = new StringRequest(url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.e("TAG", "请求数据成功" + response);

                //解析数据
                Gson s = new Gson();
                DataBean data = s.fromJson(response, DataBean.class);
                for (int i = ; i < data.getData().size(); i++) {
                    alldata.addAll(data.getData().get(i).getBrandInfo());
                }

                Log.e("TAG", "数据的长度" + alldata.size());
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        requestQueue.add(request);
    }

    private void initView() {
        recylerview = (RecyclerView) findViewById(R.id.recylerview);
    }
}
           

设置Adapte和普通的使用adapter有所不同,必须的使用下面代码

adapter.addBean(alldata, this);

StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(adapter);

 recylerview.addItemDecoration(headersDecor);
           

使用的知识有:

1. Volley使用

2. Gson使用
           

4.抽象适配器的编写,首先这里我们现在自定义一个去集成

RecyclerView.Adapter<VH>

的抽象类。

代码

package pushsummary.jzs.com.recyclerview_head;

import android.content.Context;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
主要就是数据的设置,和数据的添加,然后来更新适配器
*/

public abstract class HeadAdapter<VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH> {
    private ArrayList<String> items = new ArrayList<String>();
    public List<DataBean.DataEntity.BrandInfoEntity> data;
    public Context context;

    public HeadAdapter() {
        setHasStableIds(true);
    }



    public void addBean(List<DataBean.DataEntity.BrandInfoEntity> data, Context context) {
        this.data = data;
        this.context = context;
        notifyDataSetChanged();
    }

    public void add(int index, String object) {
        items.add(index, object);
        notifyDataSetChanged();
    }

    public void addAll(Collection<? extends String> collection) {
        if (collection != null) {
            items.addAll(collection);
            notifyDataSetChanged();
        }
    }

    public void addAll(String... items) {
        addAll(Arrays.asList(items));
    }

    public void clear() {
        items.clear();
        notifyDataSetChanged();
    }

    public void remove(String object) {
        items.remove(object);
        notifyDataSetChanged();
    }

    public String getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return data.get(position).getBranD_NAME().hashCode();
    }

    @Override
    public int getItemCount() {

        return data.size();
    }
}
           

5.Recyclerview适配器的编写,Recyclerview适配器去集成刚才自定的抽象类HeadAdapter,然后去集成第

三库的StickyRecyclerHeadersAdapter接口。

package pushsummary.jzs.com.recyclerview_head;

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 com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter;

import java.util.List;

/**
 * Created by a on 2016/11/14.
 */
public class DataAdapter extends HeadAdapter implements StickyRecyclerHeadersAdapter {
    Context mcontext;
    List<DataBean.DataEntity.BrandInfoEntity> mdata;

    public DataAdapter(Context context, List<DataBean.DataEntity.BrandInfoEntity> data) {
        mcontext = context;
        mdata = data;

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(mcontext, R.layout.list_list_view, null);

        return new Myhead1(view);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        Myhead1 myhead1 = (Myhead1) holder;
        myhead1.tv_item_name.setText(mdata.get(position).getEname());
        myhead1.tv_item_ename.setText(mdata.get(position).getCname());
    }

    /**
     * 返回要显示的头部ID
     * @param position the position of the view to get the header ID of
     * @return
     */
    @Override
    public long getHeaderId(int position) {
        return mdata.get(position).getFirst_letter().charAt();
    }


    /**
     * 加载要显示的头部布局
     * @param parent the view to create a header view holder for
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.quik_item, parent, false);
        return new Myhead(view);
    }

    /**
     * 设置显示的内容
     * @param holder the view holder
     * @param position the adapter position
     */
    @Override
    public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder, int position) {
        Myhead myhead = (Myhead) holder;
        myhead.tv_item_word.setText(mdata.get(position).getFirst_letter());
    }

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

    class Myhead1 extends RecyclerView.ViewHolder {
        TextView tv_item_name;
        TextView tv_item_ename;

        public Myhead1(View itemView) {
            super(itemView);
            tv_item_name = (TextView) itemView.findViewById(R.id.tv_item_name);
            tv_item_ename = (TextView) itemView.findViewById(R.id.tv_item_ename);

        }
    }

    /**
     * 头部适配器
     */
    class Myhead extends RecyclerView.ViewHolder {

        private TextView tv_item_word;

        public Myhead(View itemView) {
            super(itemView);
            tv_item_word = (TextView) itemView.findViewById(R.id.tv_item_word);

        }
    }


}
           

接下来就是我们要显示的每条布局文件

6.头部布局文件

<?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="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_item_word"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:background="#000000"
        android:gravity="center_vertical"
        android:paddingLeft="14dp"
        android:text="A"
        android:textColor="#ffffff"
        android:textSize="16sp" />



</LinearLayout>
           

7.内容显示的布局

<?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="43dp"

    android:orientation="horizontal">
    <TextView
        android:textColor="#ffffff"
        android:layout_width="wrap_content"
        android:layout_height="43dp"
        android:text="nick"
        android:textSize="13sp"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:id="@+id/tv_item_name"
        />
    <TextView
        android:textColor="#cccccc"
        android:layout_marginLeft="43dp"
        android:id="@+id/tv_item_ename"

        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:text="MICK"
        android:textSize="13sp"

        />
</LinearLayout>
           

做到这里以上效果及可以实现了,我们总结下以上实现的步骤:

  1. 新建项目,导入第三方库
  2. 编写显示的布局文件(Recyclerview)
  3. 编写activity文件。主要结构 01.控件的初始化,02.数据获取,03.适配器的设置
  4. 编写抽象类适配器
  5. Recyclerview适配的编写
  6. 适配器布局文件头部
  7. 适配器布局文件内容

    项目源码地址:https://github.com/sdsjk/RecyclerView_Head

如果对有什么写的不恰当的地方,欢迎指出,如果对你有用的话,就赞个吧O(∩_∩)O哈!