http://www.cnblogs.com/xfangs/html
歡迎在本文下方評論,小方很須要鼓勵支持!!!java
本系列教程僅供學習交流android
前言網絡
在上一篇文章中,咱們實現了ViewPager的基本功能,按照計劃,製做我們的電子書閱讀app須要使用ViewPager插入兩頁視圖,一個用來顯示當前書架,一個用來展現不一樣的分類。這一節,咱們將在被標記爲find的頁面上實現分類選項。app
涉及組件或框架:RecyclerView、Glide框架
首先·佈局ide
一樣的,在這裏,小方由於水平有限只能簡單介紹RecyclerView的基本使用方法,涉及到更深奧的操做部分,就無能爲力了。函數
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 6 <android.support.v7.widget.RecyclerView 7 android:id="@+id/recyler_view_find_book" 8 android:layout_margin="8dp" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent"/> 11 12 </LinearLayout>
沒有複雜的步驟,咱們只須要把RecyclerView加入到以前ViewPager的兩個佈局之一中,就完成了整個列表佈局。工具
固然,你也許會遇到一些意外。
這是說明咱們尚未引入RecyclerView這個庫,進入Design界面,從左邊的組件中找到RecyclerView,單擊,將會彈出選擇框。
在加入了庫以後,咱們就能看到RecyclerView正確無誤的顯示在界面上了。
適配器
此次咱們工做的主戰場在上一節提到的Fragment,也就是ViewPager的兩個頁面之一。
回顧一下代碼。
1 public static class FindBooksFragment extends Fragment { 2 3 public FindBooksFragment() { 4 } 5 6 @Override 7 public View onCreateView(final LayoutInflater inflater, ViewGroup container, 8 Bundle savedInstanceState) { 9 10 View rootView = inflater.inflate(R.layout.pager_book_find, container, false); 11 12 return rootView; 13 } 14 15 }
以前說了,ViewPager會在建立這個頁面的時候調用onCreateView這個函數,因此咱們在這裏進行初始化操做。
在這以前,咱們須要先完成RecyclerView的適配器,一樣的,這裏適配器起到將數據和頁面結合到一塊兒的做用,具體地說,假設一個列表中的項目能夠分爲三類,咱們就爲這三類元素分別設計佈局,而後將每一項的數據傳給適配器,適配器能夠根據數據選擇對應的佈局,而後把每一項顯示出來。
首先,新建一個類。
關於RecyclerView的適配器,網絡上已經有不少博客描述了, 隨意找一篇看的過去的文章,先大致瞭解一下。
。。。搜索時間。。。
瞭解事後,咱們知道須要爲列表項寫佈局,這在前面也間接提到了。
那麼,新建一個佈局文件
book_find_item.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:id="@+id/bookFind_cardview" 5 android:layout_width="match_parent" 6 android:layout_height="wrap_content" 7 android:layout_margin="4dp" 8 android:foreground="?android:attr/selectableItemBackground" 9 android:clickable="true"> 10 11 <ImageView 12 android:id="@+id/bookFind_image" 13 android:layout_width="match_parent" 14 android:layout_height="150dp" 15 android:scaleType="centerCrop" 16 tools:src="@color/cardview_dark_background"/> 17 18 <TextView 19 android:id="@+id/bookFind_class" 20 android:layout_width="match_parent" 21 android:layout_height="match_parent" 22 android:background="#00000000" 23 android:textColor="#FFFFFF" 24 android:textStyle="normal|bold" 25 android:textSize="14sp" 26 android:gravity="center" 27 tools:text="123"/> 28 29 </android.support.v7.widget.CardView>
在這裏,咱們又使用了一個新的組件,CardView,它體現了安卓最新設計風格,恰到好處的圓角、逼真的陰影、點擊特效、等等,有多種屬性可供調整。
尤爲要說的是上面代碼中加粗的字體,一個新的命名空間 tools ,在使用它以前,咱們首先要在最外層的部件上聲明。
只要打出前面幾個字母,android studio 就會自動補全好。
tools 命名空間提供了測試的效果,以他爲名號的屬性在程序運行期間是被忽略的,只供測試預覽使用,使得開發更加方便了。下圖就是咱們預覽時獲得的效果,
當程序運行起來時, 還會是如圖所示的樣子嗎?
(必然不是)
製做好了佈局文件,咱們就能夠開始對適配器進行編寫了。
首先製做一個接口,用來獲取點擊事件。
1 private OnItemClickListener listener; 2 3 public void setOnItemClickListener(OnItemClickListener listener) { 4 this.listener = listener; 5 } 6 7 public interface OnItemClickListener { 8 void onItemClick(View view, int position); 9 void onItemLongClick(View view, int position); 10 }
而後在適配器的類中再新建一個類。
1 static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { 2 View tocView; 3 private TextView textview_bookFindClass; 4 private ImageView imageView; 5 private OnItemClickListener listener; 6 7 public ViewHolder(View itemView, OnItemClickListener l) { 8 super(itemView); 9 tocView = itemView; 10 textview_bookFindClass = (TextView) itemView.findViewById(R.id.bookFind_class); 11 imageView = (ImageView) itemView.findViewById(R.id.bookFind_image); 12 listener = l; 13 itemView.setOnClickListener(this); 14 itemView.setOnLongClickListener(this); 15 } 16 17 18 @Override 19 public void onClick(View v) { 20 if (listener != null) { 21 listener.onItemClick(v, getAdapterPosition()); 22 } 23 } 24 25 @Override 26 public boolean onLongClick(View v) { 27 if (listener != null) { 28 listener.onItemLongClick(v, getAdapterPosition()); 29 } 30 return false; 31 } 32 }
可能略顯複雜,這個類的做用是緩存列表項,具體比較低層的東西小方就不太清楚了,上網搜了搜,就不現學現賣了,歡迎有興趣的同窗一塊兒討論。
ViewHolder 類繼承自 RecyclerView.ViewHolder,爲了實現點擊監聽,還要接入兩個接口,一個是單擊的接口,一個是長按的接口。
從構造函數開始一點一點理解,構造函數接收兩個參數,一個是每一項的View,一個是每一項的點擊監聽器。初始化組件以後,設置監聽器,按照以前設置的接口的設定,將View和位置傳給藉口。
若是還不是很清楚,那麼先將代碼複製過去,使用次數多了,天然就理解了。
而後,在AdapterBookFind這個類中,完成它的構造函數,這裏是根據須要自行設定的,在這裏咱們須要將分類名稱傳給適配器,顯示在每一項上,因此傳送了一個字符串列表。你也能夠根據本身的須要傳送想要傳送的數據。
1 private ArrayList<String> myCategory; 2 3 public AdapterBookFind(ArrayList<String> category) { 4 this.myCategory = category; 5 }
下面咱們須要重寫一個函數,用來獲取一個ViewHolder的實例。
1 private Context context; 2 @Override 3 public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) { 4 View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.book_find_item, parent, false); 5 context = parent.getContext(); 6 final ViewHolder holder = new ViewHolder(view, listener); 7 8 return holder; 9 }
在這裏,咱們又聲明瞭一個叫作context的變量,並初始化,具體做用後面再表。
1 @Override 2 public int getItemCount() { 3 return myCategory.size(); 4 }
相似ViewPager的適配器同樣,咱們一樣須要重寫取數目的函數,根據數據返回一個值。
立刻就到最後一步了,咱們將要對列表的每一項設置不一樣的內容。
1 @Override 2 public void onBindViewHolder(final ViewHolder holder, int position) { 3 holder.textview_bookFindClass.setText(myCategory.get(position)); 4 5 switch (position) { 6 case 0: 7 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 8 break; 9 case 1: 10 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 11 break; 12 case 2: 13 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 14 break; 15 case 3: 16 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 17 break; 18 case 4: 19 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 20 break; 21 case 5: 22 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 23 break; 24 case 6: 25 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 26 break; 27 case 7: 28 Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView); 29 break; 30 default: 31 32 break; 33 } 34 holder.imageView.setColorFilter(Color.parseColor("#55555555")); 35 36 }
由於咱們的佈局文件中只有兩個組件能體現數據的內容,TextView和ImageView。
第三行是根據不一樣的位置選擇不一樣的字符串進行設置,沒有難度。
在說switch以前,咱們先來看最後一行
holder.imageView.setColorFilter(Color.parseColor("#55555555"));
給imageView設置濾色,由於我想要在圖片之上顯示一個白色的文字,適當的使圖片變暗,能凸顯文字。
switch固然也能看得懂,可是出現了一個陌生的東西 Glide。
實際不難理解,這個switch的做用仍是根據不一樣的位置選擇不一樣的文件進行顯示,咱們固然可使用ImageView自帶的方法來設置圖片,可是ImageView只能設置本地或者APK之中的圖片資源,對於網絡圖片或者諸多不支持的圖片類型(如GIF)就毫無辦法,不只如此,當本地圖片較大時,還會不可避免的出現卡頓現象。
這時候Glide出現了,它能快速加載各類圖片,根據顯示大小自動對圖片進行壓縮,一樣一條語句,若是傳入圖片連接還能加載網絡圖片,並緩存。
Glide.with(context).load(R.mipmap.ic_launcher).into(holder.imageView);
如上面代碼所示的一句話,就能加載APK資源中的一張圖片,這裏咱們只有圖標一個文件,因此將圖標文件傳給了imageView。
不過若是你只是把剛剛的代碼複製粘貼到你的工程,你的程序應該會報錯,顯示沒有找到Glide這個東西,這是由於Glide不是官方提供的,咱們須要手動引入。
找到上面那個文件。
加入最後一行,選擇同步。
這樣,咱們就引入了Glide。
整合
1 public static class FindBooksFragment extends Fragment { 2 3 public FindBooksFragment() { 4 } 5 6 private RecyclerView recyclerView; 7 private StaggeredGridLayoutManager staggeredGridLayoutManager; 8 private AdapterBookFind bookAdapterBookFind; 9 10 @Override 11 public View onCreateView(final LayoutInflater inflater, ViewGroup container, 12 Bundle savedInstanceState) { 13 14 final ArrayList<String> bookClass = new ArrayList<>(); 15 bookClass.add("//玄幻"); 16 bookClass.add("//武俠"); 17 bookClass.add("//都市"); 18 bookClass.add("//歷史"); 19 bookClass.add("//遊戲"); 20 bookClass.add("//科幻"); 21 bookClass.add("//女生"); 22 bookClass.add("//全部"); 23 24 View rootView = inflater.inflate(R.layout.pager_book_find, container, false); 25 recyclerView = (RecyclerView) rootView.findViewById(R.id.recyler_view_find_book); 26 27 staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); 28 recyclerView.setLayoutManager(staggeredGridLayoutManager); 29 bookAdapterBookFind = new AdapterBookFind(bookClass); 30 recyclerView.setAdapter(bookAdapterBookFind); 31 32 bookAdapterBookFind.setOnItemClickListener(new AdapterBookFind.OnItemClickListener() { 33 @Override 34 public void onItemClick(View view, int position) { 35 Log.e(TAG, "onItemClick: 111" ); 36 } 37 38 @Override 39 public void onItemLongClick(View view, int position) { 40 Log.e(TAG, "onItemLongClick: 222" ); 41 } 42 }); 43 44 return rootView; 45 } 46 47 private static final String TAG = "FindBooksFragment"; 48 49 }
首先初始化咱們的字符串列表。StaggeredGridLayoutManager是咱們列表的佈局管理器,安卓提供了三種佈局管理器,用來實現不一樣的列表效果,多行列表,瀑布流列表,不一樣的滑動方向均可以進行設置,你們能夠百度其餘的佈局管理器。
因此在27-30行,咱們分別爲RecyclerView設置了列表管理器和適配器,32行開始,爲適配器設置點擊監聽器,我們暫時不設置功能,使用log工具將其輸出在Android Monitor(log語句有快捷鍵)。
效果
運行程序,你將見到
咱們又完成了新的一節,如今能夠嘗試更換不一樣的圖片,嘗試使用網絡圖片(不要忘記加入網絡訪問權限)。
未完待續...下一篇文章講述使用 litePal 完成書架,敬請期待!!!