天天看點

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哈!