RecyclerView詳細介紹-----多item佈局(三)
1.前言
前面兩篇文章主要介紹了recyclerview的基本使用,接下來介紹複雜一點的需求。
我們之前用listview的時候肯定遇到itemType>1的時候,我們定義多套item佈局,藉助getItemViewType()實現多套佈局。但是如果像淘寶首頁,上面是listview的一個一個item,下面確是一個GridView的話,我們如何實現呢?當然之前有人會把GridView用ListView來實現,及一個Listview的item來代替GridView的兩個item,只是資料集我們要自己做處理,總之很麻煩。現在有了recyclerview,這些就變得很簡單。
2.實現效果
上圖既有listview的列表,下方又有gridview,如何實現呢?
3.具體實現過程:
1)跟listview一樣,recyclerview藉助getItemViewType(int position)實現多套佈局判斷,然後根據itemtype實現多套佈局的建立跟賦值,具體程式碼如下:
public class MultiItemAdapter extends RecyclerView.Adapter<MultiItemAdapter.ViewHolder> {
public static final int ONE_TEXT_VIEW_TYPE = 0 ;
public static final int TWO_TEXT_VIEW_TYPE = 1;
public static final int GRID_VIEW_TYP = 2;
private ArrayList<Person> data;
private Context context;
public MultiItemAdapter(Context context, ArrayList<Person> data) {
this.data = data;
this.context = context;
}
@Override
public int getItemViewType(int position) {
if (data.get(position).getType() == ONE_TEXT_VIEW_TYPE) {
return ONE_TEXT_VIEW_TYPE;
} else if (data.get(position).getType() == TWO_TEXT_VIEW_TYPE) {
return TWO_TEXT_VIEW_TYPE;
} else if (data.get(position).getType() == GRID_VIEW_TYP) {
return GRID_VIEW_TYP;
}else {
return ONE_TEXT_VIEW_TYPE;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemView = null;
switch (viewType) {
case ONE_TEXT_VIEW_TYPE:
itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_one, null);
break;
case TWO_TEXT_VIEW_TYPE:
itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_two, null);
break;
case GRID_VIEW_TYP:
itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_three, null);
break;
}
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
int itemViewType = getItemViewType(position);
switch (itemViewType) {
case ONE_TEXT_VIEW_TYPE:
showOneTextView(holder, position);
break;
case TWO_TEXT_VIEW_TYPE:
showTwoTextView(holder, position);
break;
case GRID_VIEW_TYP:
showGridView(holder, position);
break;
}
}
/**
* 賦值
*
* @param holder
* @param position
*/
private void showOneTextView(ViewHolder holder, int position) {
TextView textview = (TextView) holder.findViewById(R.id.item_text);
textview.setText(data.get(position).getName());
}
private void showTwoTextView(ViewHolder holder, int position) {
TextView item_text_one = (TextView) holder.findViewById(R.id.item_text_one);
TextView item_text_two = (TextView) holder.findViewById(R.id.item_text_two);
item_text_one.setText(data.get(position).getName());
item_text_two.setText(data.get(position).getType() + "");
}
private void showGridView(ViewHolder holder, int position) {
TextView textview = (TextView) holder.findViewById(R.id.item_text);
textview.setText(data.get(position).getName());
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
//自定義的ViewHolder,持有每個Item的的所有介面元素
public static class ViewHolder extends RecyclerView.ViewHolder {
private Map<Integer, View> mCacheView;
public ViewHolder(View itemView) {
super(itemView);
mCacheView = new HashMap<>();
}
public View findViewById(int resId) {
View view;
if (mCacheView.containsKey(resId)) {
view = mCacheView.get(resId);
} else {
view = itemView.findViewById(resId);
mCacheView.put(resId, view);
}
return view;
}
}
}
這裡需要說一下,ViewHolder 我們這邊統一做了封裝,抽出findViewById方法,內部做了快取處理,而簡單的具體例項化交給各個具體item,方便使用。
2)我們知道普通的listview只有一列,而gridview是多列,recyclerview如何做到呢?其實是用到了layoutManager.setSpanSizeLookup方法.
public class MultiItemActivity extends AppCompatActivity {
/**
* view
*/
private RecyclerView recyclerView;
/**
* 用來確定每一個item如何進行排列擺放,何時展示和隱藏
*/
private GridLayoutManager layoutManager;
/**
* 介面卡
*/
private MultiItemAdapter mAdapter;
private ArrayList<Person> data = new ArrayList<Person>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
/**
* 初始化佈局元件
*/
private void initView() {
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//建立預設的線性LayoutManager
layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
//如果可以確定每個item的高度是固定的,設定這個選項可以提高效能
recyclerView.setHasFixedSize(true);
}
/**
* 初始化資料
*/
private void initData() {
for (int i = 0; i < 10; i++) {
Person person = new Person();
person.setName(i + "abc" + 1);
if (i < 3) {
person.setType(MultiItemAdapter.ONE_TEXT_VIEW_TYPE);
} else if (i < 6) {
person.setType(MultiItemAdapter.TWO_TEXT_VIEW_TYPE);
} else {
person.setType(MultiItemAdapter.GRID_VIEW_TYP);
}
data.add(person);
}
//建立並設定Adapter
mAdapter = new MultiItemAdapter(this, data);
recyclerView.setAdapter(mAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (mAdapter.getItemViewType(position)
== MultiItemAdapter.GRID_VIEW_TYP) {
return 1;
} else {
return 2;
}
}
});
}
}
在上面的基本設定中,我們的spanCount為2,setSpanSizeLookup可以讓你根據position來設定spanCount,spanCount可以想象成佈局裡面的weight(比重),原先通過layoutManager = new GridLayoutManager(this, 2);設定成一個item佔比為2,那麼如果根據setSpanSizeLookup設定的spanCount為1的話,那麼一行就是2列,這樣才能滿足一行的比重為2;如果spanCount為2的話,則說明一行一列。
通過上面的程式碼,我們就輕鬆的實現了多itemtype甚至listview跟gridview混合的情況。
4.完整程式碼下載地址如下所示:
歡迎一起交流討論
群號:469890293
相關推薦
RecyclerView詳細介紹-----多item佈局(三)
1.前言 前面兩篇文章主要介紹了recyclerview的基本使用,接下來介紹複雜一點的需求。 我們之前用listview的時候肯定遇到itemType>1的時候,我們定義多套item佈局,藉助getItemViewType()實現多套佈局。但是如果像
recyclerView 實現複雜的item佈局(如淘寶、京東、商城類首頁)
前言 現在各種電商如火如荼,首頁頁面設計也頗有色彩。 之前專案也是一個電商類購物app,主頁設計了好幾套樣式。 其中一個樣式如下圖相似涉及到: 輪播廣告圖banner、viewPager的輪播、沉浸式狀態列、 recyclerView的item的複雜分割
詳細介紹Java虛擬機(JVM)
委托 article log flow 包括 源代碼 filename method 獨立 1. JVM生命周期 啟動。啟動一個Java程序時,一個JVM實例就產生了,任何一個擁有public static void main(String[] args)函數的class
Java多線程(三)SimpleDateFormat
spa bsp sdf java多線程 ext add println turn static 多線程報錯:java.lang.NumberFormatException: multiple points SimpleDateFormat是非線程安全的,在多線程情況下會有
多線程編程之Linux環境下的多線程(三)
del mutex 我們 後退 post linux環境 ini tro create 前面兩篇文章都講述了Linux環境下的多線程編程基礎知識,也附帶了典型實例。本文主要比較一下Linux環境與Windows環境下的多線程編程區別。 看待技術問題要瞄準其本質,不管是W
python多進程(三)
Go 分別是 開始 取數 monit box get() duplex red 消息隊列 消息隊列”是在消息的傳輸過程中保存消息的容器。 消息隊列最經典的用法就是消費者和生成者之間通過消息管道來傳遞消息,消費者和生成者是不通的進程。生產者往管道中寫消息,消費者從管道中讀
java多線程(三)
http acc system tle 線程編程 getname 定時 raw size 本文主要接著前面多線程的兩篇文章總結Java多線程中的線程安全問題。 一.一個典型的Java線程安全例子 1 public class ThreadTest { 2 3
多線程(三):檢索線程對象
rgs main 停止 單獨 () read div 替代 主線程 class Program9 { //檢索線程對象 //停止所有前臺線程後,運行時將停止所有後臺線程,並關閉。 static Object obj
linux 核心模組程式設計之編譯多個原始檔(三)
編譯擁有多個原始檔的核心模組的方式和編譯一個原始檔的方式差不多,我們先來看下我們需要的檔案都有哪些。 首先是main.c檔案 #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE
java 多執行緒(三)
1、java 中任何物件都可以作為鎖 2、同步程式碼執行完成後會自動釋放掉 3、happend-before 4、類鎖和物件鎖相互幾乎不影響,不存在競爭 5、私有鎖和物件鎖不存在競爭,相互不影響 6、一個執行緒一旦呼叫wait()就釋放了所以的鎖,一個等待執行緒被notify()喚醒,不會立刻進入喚
Ansible劇本介紹及使用演示(三)--技術流ken
Ansible劇本編寫說明 一. 縮排 yaml 的縮排要求比較嚴格。一定不能使用tab鍵 注意:編寫yaml檔案,就忘掉shell的tab吧。 二. 冒號 每個冒號
Android RecyclerView優雅實現複雜列表佈局(二)
轉載:https://blog.csdn.net/huang3513/article/details/62046528 前言 學習了(一)中那個RecyclerView的一些基礎知識,如果沒有具體看懂可以再返回看不一樣的RecyclerView優雅實現複雜列表佈局(一),那麼接下來我們就在(
Android RecyclerView優雅實現複雜列表佈局(一)
轉載:https://blog.csdn.net/huang3513/article/details/62044688 前言 在多彩佈局不斷呈現的今天,多佈局混合排布成為一個時尚,今天就結合Holder實現RecyclerView複雜列表佈局。 效果圖如下(三種佈局): 
深入理解Java多執行緒(三)
關於java多執行緒的概念以及基本用法:java多執行緒基礎 3, 執行緒間通訊 執行緒在作業系統中是獨立的個體,經過特殊的處理,執行緒間可以實現通訊,進而成為一個整體,提高CPU利用率 3.1,等待/通知機制 等待:wait()方法作用是使當前執
Python多執行緒(三)
引言 在前面的章節我們介紹了使用執行緒和不使使用執行緒的對比例項,並且引入了鎖的概念,這節課我們來了解一下更高階的threading模組。 threading 在threading模組中不
Android學習筆記——Layout佈局(三)
1:什麼是Layout? (1)Layout:介面佈局,為應用程式提供介面結構 (2)控制Activity中空間的大小、位置、顏色等屬性的方法 2:Layout與ViewGroup之間的關係 (1)ViewGroup是一個容器,而這個容器是繼承於View的。 (2)ViewGro
Django之模型層,單,多表操作(三)
一:多表操作之增、刪、改 1.1:增: 一對多: 方式1: publish_obj=Publish.objects.get(nid=1) book_obj=Book.objects.create(title="海爾兄弟",publi
多執行緒(三)Future和Callable
package a; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import
MFC多文件(三):文件與檢視繫結
多文件系列 MFC多文件(一):檢視中獲取文件指標 MFC多文件(二):文件中獲取檢視指標 MFC多文件(三):文件與檢視繫結 問題 如題。 解決方法: 1、MFC多文件工程,手動新增CNaviM