Android RecyclerView嵌套RecyclerView
阿新 • • 發佈:2017-06-19
eat inf idg create 首頁 ber mage asi adapt
原理
RecyclerView嵌套RecyclerView的條目,項目中可能會經常有這樣的需求,但是我們將子條目設置為RecyclerView之後,卻顯示不出來。自己試了很久,終於找到了原因:必須先設置子RecylcerView的高度。你要花精力確定出子RecyclerView裏面條目的高度,然後從而確定子RecyclerView的高度,設置給子RecylcerView,這樣做RecyclerView就可以正確顯示出子ReclyclerView。
效果
代碼
首頁布局就是一個豎直排列的RecyclerView
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recylcerview" android:layout_width="match_parent" android:layout_height="match_parent"/>
接下來在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<Integer> resourceList =newArrayList<>(); 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()); }
接下來看看RecyclerView的Adapter:
private class RecyclerViewAdapter extends RecyclerView.Adapter<BaseHolder>{ 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; } }
可以看出,我們一共有三種條目類型,第一種是水平滑動的子RecyclerView,第二種是GridView形的子RecyclerView,第三種就是正常的子條目,根據viewType來返回不同的ViewHolder,到這裏應該都沒什麽問題。
接下來就是各個類型的ViewHolder了,在Holder當中,我們要計算條目的高度然後設置給子RecyclerView
private class GridViewHolder extends BaseHolder<List<Integer>>{ private RecyclerView item_recyclerview; private final int ONE_LINE_SHOW_NUMBER = 3; private List<Integer> 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<Integer> 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<BaseHolder>{ @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(); } } }
其他代碼我就不貼了,想要看源碼的可以直接下載:
https://github.com/z593492734/nesting-recylcerview
總體來說,RecyclerView嵌套RecyclerView是很簡單的,而且也相當好用,希望這個demo可以給大家一些靈感。
Android RecyclerView嵌套RecyclerView