1. 程式人生 > >XRecyclerview巢狀XRecyclerview佈局顯示不全

XRecyclerview巢狀XRecyclerview佈局顯示不全

前言

  這篇文章是在筆者生病用手機寫的,可能寫的比較粗糙,希望讀者能夠海涵。大家在開發中經常會遇到recyclerview巢狀recyclerview的需求,或者把recyclerview作為頭佈局新增到recyclerview中,今天我們來說一下後者。

正題

  比如說頭部是一個不固定條目數量的列表,具體展示多少條目根據伺服器返回的資料來定,而外層也是一個列表。所以這個時候就用到我們所說的recyclerview作為頭佈局新增到recyclerview中了。這裡我為了方便使用的是XRecyclerview,github上的一個開源控制元件,很好用的。程式碼如下:

package com.example.xxm.xrecyclerviewtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private XRecyclerView rlv;
    private List<String> data;
    private List<String> headData;

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

        rlv = findViewById(R.id.xrlv);
        initData();
        setMainAdapter();
        setHeadAdapter();
    }

    /**
     * 模擬假資料
     */
    private void initData() {
        data = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            data.add("我是條目    "+i);
        }
        //頭部資料
        headData = new ArrayList<>();
        headData.add("頭部-------------------1");
        headData.add("頭部-------------------2");
        headData.add("頭部-------------------3");
        headData.add("頭部-------------------4");
    }

    /**
     * 設定整體adapter
     */
    private void setMainAdapter(){
        LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        rlv.setLayoutManager(manager);
        MainAdapter adapter = new MainAdapter(this, data);
        rlv.setAdapter(adapter);
    }

    /**
     * 設定頭佈局的adapter
     */
    private void setHeadAdapter() {
//        View view = LayoutInflater.from(this).inflate(R.layout.item_head,(ViewGroup) rlv.getParent(),false);
        View view = LayoutInflater.from(this).inflate(R.layout.item_head,(ViewGroup) this.findViewById(android.R.id.content),false);

        XRecyclerView xRecyclerView = view.findViewById(R.id.rlv);
        LinearLayoutManager manager2 = new LinearLayoutManager(this);
        manager2.setOrientation(LinearLayoutManager.VERTICAL);
        xRecyclerView.setLayoutManager(manager2);
        HeadAdapter headAdapter = new HeadAdapter(this, headData);
        xRecyclerView.setAdapter(headAdapter);
        //新增頭佈局
        rlv.addHeaderView(view);
    }
}

你們可以觀察到在setHeadAdapter這個方法中,我填充頭部佈局的時候使用了LayoutInflater的方式,而且inflate第二引數是不同的,如果這段程式碼在adapter中去寫,大家肯定都熟記於心了,那就是這個樣子的:

@Override
    public HeadViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
        return new HeadViewHolder(view);
    }

但是在別的類中,這個parent該用什麼代替呢?第二個引數的意思指外層控制元件,第三個引數如果指定true,item的寬高則有效,false則無效。如果你不設定這個parent,就會變成下面這個樣子:


出現這種效果肯定會想到是不是佈局檔案中設定寬度出現了問題,我的item寬度,外層的XRecyclerview的寬度都是填充父窗體,但是依然沒有效果,所以諮詢了一些人,他們使用的是固定的寫法,也就是第二種方式。我在這個類中通過了兩種方式獲取這個parent,第一種是通過(ViewGroup)rlv.getParent(),第二種是一種固定的寫法,設定之後效果是這個樣子的:


其中的佈局檔案是一樣的,只是這個parent引數不同

結束語

  希望可以解決一些人和遇到這個類似的問題,那麼我這篇文章就沒有白寫,自己也會加深一些印象。