使用 RecyclerView 控制元件實現瀑布流
阿新 • • 發佈:2019-01-17
RecyclerView相比於ListView, 在回收重用時更具有靈活性, 也就是低耦合, 並且提供了擴充套件. 載入多個檢視時, 應該多用RecyclerView代替ListView.
那麼我們來看看這東西應該怎麼用? 比如生成一個瀑布流的檢視.
首先我們從一個HelloWorld寫起, 看看如何構建一個RecyclerView.
依賴
Gradle配置, 新增RecyclerView庫的依賴.
Java1 | compile'com.android.support:recyclerview-v7:+' |
佈局
佈局檔案
Java1234 | <android.support.v7.widget.RecyclerViewandroid:id="@+id/test_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/> |
程式碼
LayoutManager: 管理RecyclerView的結構.
Adapter: 處理每個Item的顯示.
ItemDecoration: 新增每個Item的裝飾.
ItemAnimator: 負責新增\移除\重排序時的動畫效果.
JavaLayoutManager\Adapter是必須, ItemDecoration\ItemAnimator是可選.
123456789101112 | /** * 初始化RecyclerView * * @param recyclerView 主控制元件 */privatevoidinitRecyclerView(RecyclerView recyclerView){recyclerView.setHasFixedSize(true);// 設定固定大小initRecyclerLayoutManager(recyclerView);// 初始化佈局initRecyclerAdapter(recyclerView);// 初始化介面卡initItemDecoration(recyclerView);// 初始化裝飾initItemAnimator(recyclerView);// 初始化動畫效果} |
LayoutManager
管理RecyclerView的佈局結構.
Java12345 | privatevoidinitRecyclerLayoutManager(RecyclerView recyclerView){// 錯列網格佈局recyclerView.setLayoutManager(newStaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));} |
提供了多種LayoutManager, 瀑布流使用錯列網格佈局.
Adapter
介面卡, 處理RecyclerView的Item事務.
Java1234 | privatevoidinitRecyclerAdapter(RecyclerView recyclerView){mAdapter=newMyAdapter(getData());recyclerView.setAdapter(mAdapter);} |
對於Adapter, 我們需要展開來說, 先看看類.
Java123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 | publicclassMyAdapter extendsRecyclerView.Adapter<MyViewHolder>{privateList<DataModel>mDataModels;privateList<Integer>mHeights;MyAdapter(List<DataModel>dataModels){if(dataModels==null){thrownewIllegalArgumentException("DataModel must not be null");}mDataModels=dataModels;mHeights=newArrayList<>();}@OverridepublicMyViewHolder onCreateViewHolder(ViewGroup parent,intviewType){View itemView=LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_view,parent,false);returnnewMyViewHolder(itemView);}@OverridepublicvoidonBindViewHolder(MyViewHolder holder,intposition){DataModel dataModel=mDataModels.get(position);// 隨機高度, 模擬瀑布效果.if(mHeights.size()<=position){mHeights.add((int)(100+Math.random()*300));}ViewGroup.LayoutParams lp=holder.getTvLabel().getLayoutParams();lp.height=mHeights.get(position);holder.getTvLabel().setLayoutParams(lp);holder.getTvLabel().setText(dataModel.getLabel());holder.getTvDateTime().setText(newSimpleDateFormat("yyyy-MM-dd",Locale.ENGLISH).format(dataModel.getDateTime()));}@OverridepublicintgetItemCount(){returnmDataModels.size();}publicvoidaddData(intposition){DataModel model=newDataModel();model.setDateTime(getBeforeDay(newDate(),position));model.setLabel("No. "+(int)(newRandom().nextDouble()*20.0f));mDataModels.add(position,model);notifyItemInserted(position);}publicvoidremoveData(intposition){mDataModels.remove(position);notifyItemRemoved(position);}/** * 獲取日期的前一天 * * @param date 日期 * @param i 偏離 * @return 新的日期 */privatestaticDate getBeforeDay(Date date,inti){Calendar calendar=Calendar.getInstance();calendar.setTime(date);calendar.add(Calendar.DAY_OF_YEAR,i*(-1));returncalendar.getTime();}} |
onCreateViewHolder建立ViewHolder.
onBindViewHolder繫結每一項資料.
getItemCount返回列表長度.
RecyclerView強制使用ViewHolder.
Java1234567891011121314151617181920 | publicclassMyViewHolder extendsRecyclerView.ViewHolder{privateTextView mTvLabel;// 標籤privateTextView mTvDateTime;// 日期publicMyViewHolder(View itemView){super(itemView);mTvLabel=(TextView)itemView.findViewById(R.id.item_text);mTvDateTime=(TextView)itemView.findViewById(R.id.item_date);}publicTextView getTvLabel(){returnmTvLabel;}publicTextView getTvDateTime(){returnmTvDateTime;}} |
在onCreateViewHolder方法, 建立類; 在onBindViewHolder方法, 繫結資料.
DataModel
Java123456789101112131415161718192021 | publicclassDataModel{privateStringmLabel;privateDate mDateTime;publicStringgetLabel(){returnmLabel;}publicvoidsetLabel(Stringlabel){mLabel=label;}publicDate getDateTime(){returnmDateTime;}publicvoidsetDateTime(Date dateTime){mDateTime=dateTime;}} |
ItemDecoration
項的裝飾, 比如ListView中的分割線, 在本例中, 左右兩條粉線.
Java123 | privatevoidinitItemDecoration(RecyclerView recyclerView){recyclerView.addItemDecoration(newMyItemDecoration(this));} |
ItemDecoration, 注意parent和child的使用方式.