效果圖:

RecyclerView嵌套RecyclerView

af63e1c8c88f445439b58b3ad8201436.png

RecyclerView嵌套ListView

f6aa151a7835e9a2643291960eb8c637.png

原理

RecyclerView嵌套RecyclerView的條目,項目中可能會經常有這樣的需求,但是我們將子條目設置為RecyclerView之后,卻顯示不出來。自己試了很久,終於找到了原因:必須先設置子RecylcerView的高度。你要花精力確定出子RecyclerView里面條目的高度,然后從而確定子RecyclerView的高度,設置給子RecylcerView,這樣做RecyclerView就可以正確顯示出子ReclyclerView。

代碼

首頁布局就是一個豎直排列的RecyclerView

android:id="@+id/recylcerview"

android:layout_width="match_parent"

android:layout_height="match_parent"/>1

2

3

4

5

6

接下來在MainActivity對該布局進行初始化,然后制造一些假數據

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

basicParamInit();

initData();

initRecyclerView();

}

private void basicParamInit() {

DisplayMetrics metric = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(metric);

screenWidth = metric.widthPixels;

}

private void initData() {

data = new DataInfor();

ArrayList resourceList =new ArrayList<>();

resourceList.add(R.drawable.aaa);

resourceList.add(R.mipmap.ic_launcher);

resourceList.add(R.drawable.aaa);

resourceList.add(R.mipmap.ic_launcher);

resourceList.add(R.drawable.aaa);

resourceList.add(R.mipmap.ic_launcher);

resourceList.add(R.drawable.aaa);

resourceList.add(R.mipmap.ic_launcher);

data.gridData = data.horizontalData = data.verticalData = resourceList;

}

private void initRecyclerView() {

recylcerview = (RecyclerView) findViewById(R.id.recylcerview);

recylcerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL,false));

recylcerview.setBackgroundResource(R.color.c_e0e0e2);

recylcerview.setAdapter(new RecyclerViewAdapter());

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

接下來看看RecyclerView的Adapter:

private class RecyclerViewAdapter extends RecyclerView.Adapter{

private final int HORIZONTAL_VIEW = 1000;

private final int VERTICAL_VIEW = 1001;

private final int GRID_VIEW = 1002;

@Override

public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType){

case HORIZONTAL_VIEW:

return new HorizontalViewHolder(R.layout.item_recyclerview,parent,viewType);

case GRID_VIEW:

return new GridViewHolder(R.layout.item_recyclerview,parent,viewType);

case VERTICAL_VIEW:

return new ItemViewHolder(R.layout.item_x2_imageview,parent,viewType);

}

return null;

}

@Override

public void onBindViewHolder(BaseHolder holder, int position) {

if(holder instanceof HorizontalViewHolder){

holder.refreshData(data.horizontalData,position);

}else if(holder instanceof GridViewHolder){

holder.refreshData(data.gridData,position);

}else if(holder instanceof ItemViewHolder){

holder.refreshData(data.verticalData.get(position - 2),position - 2);

}

}

@Override

public int getItemCount() {

return 2 + data.verticalData.size();

}

@Override

public int getItemViewType(int position) {

if(position == 0) return HORIZONTAL_VIEW;

if(position == 1) return GRID_VIEW;

return VERTICAL_VIEW;

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

可以看出,我們一共有三種條目類型,第一種是水平滑動的子RecyclerView,第二種是GridView形的子RecyclerView,第三種就是正常的子條目,根據viewType來返回不同的ViewHolder,到這里應該都沒什么問題。

接下來就是各個類型的ViewHolder了,在Holder當中,我們要計算條目的高度然后設置給子RecyclerView

private class HorizontalViewHolder extends BaseHolder>{

private RecyclerView hor_recyclerview;

private List data;

public HorizontalViewHolder(int viewId, ViewGroup parent, int viewType) {

super(viewId, parent, viewType);

hor_recyclerview = (RecyclerView) itemView.findViewById(R.id.item_recyclerview);

}

@Override

public void refreshData(List data, int position) {

this.data = data;

ViewGroup.LayoutParams layoutParams = hor_recyclerview.getLayoutParams();

//高度等於=條目的高度+ 10dp的間距 + 10dp(為了讓條目居中)

layoutParams.height = screenWidth/3 + dip2px(20);

hor_recyclerview.setLayoutParams(layoutParams);

hor_recyclerview.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL,false));

hor_recyclerview.setBackgroundResource(R.color.colorAccent);

hor_recyclerview.setAdapter(new HorizontalAdapter());

}

private class HorizontalAdapter extends RecyclerView.Adapter{

@Override

public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {

return new ItemViewHolder(R.layout.item_x2_imageview,parent,viewType);

}

@Override

public void onBindViewHolder(BaseHolder holder, int position) {

holder.refreshData(data.get(position),position);

}

@Override

public int getItemCount() {

return data.size();

}

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

水平的子RecyclerView的高度還是比較容易計算的,畢竟只有一行,高度相對來說是固定的。但是像GridView的高度是動態的,根據條目數量的不同,可能會有多行,所以我們需要先計算行數,然后每行的高度*行數才是子RecyclerView的高度

private class GridViewHolder extends BaseHolder>{

private RecyclerView item_recyclerview;

private final int ONE_LINE_SHOW_NUMBER = 3;

private List data;

public GridViewHolder(int viewId, ViewGroup parent, int viewType) {

super(viewId, parent, viewType);

item_recyclerview = (RecyclerView) itemView.findViewById(R.id.item_recyclerview);

}

@Override

public void refreshData(List data, int position) {

super.refreshData(data, position);

this.data = data;

//每行顯示3個,水平顯示

item_recyclerview.setLayoutManager(new GridLayoutManager(MainActivity.this,ONE_LINE_SHOW_NUMBER,LinearLayoutManager.HORIZONTAL,false));

ViewGroup.LayoutParams layoutParams = item_recyclerview.getLayoutParams();

//計算行數

int lineNumber = data.size()%ONE_LINE_SHOW_NUMBER==0? data.size()/ONE_LINE_SHOW_NUMBER:data.size()/ONE_LINE_SHOW_NUMBER +1;

//計算高度=行數*每行的高度 +(行數-1)*10dp的margin + 10dp(為了居中)

//因為每行顯示3個條目,為了保持正方形,那么高度應該是也是寬度/3

//高度的計算需要自己好好理解,否則會產生嵌套recyclerView可以滑動的現象

layoutParams.height = lineNumber *(screenWidth/3) + (lineNumber-1)*dip2px(10) + dip2px(10);

item_recyclerview.setLayoutParams(layoutParams);

item_recyclerview.setBackgroundResource(R.color.colorPrimary);

item_recyclerview.setAdapter(new GridAdapter());

}

private class GridAdapter extends RecyclerView.Adapter{

@Override

public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {

return new ItemViewHolder(R.layout.item_x2_imageview,parent,viewType);

}

@Override

public void onBindViewHolder(BaseHolder holder, int position) {

holder.refreshData(data.get(position),position);

}

@Override

public int getItemCount() {

return data.size();

}

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

總體來說,RecyclerView嵌套RecyclerView是很簡單的,而且也相當好用,希望這個demo可以給大家一些靈感。

有任何問題都可以聯系我:mengyuanzz@126.com

下面是我修改后的例子:

效果圖:

d57866ed531120fa55165e949982f8af.png

源碼下載:

轉載地址:

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐