RecyclerView新增動態多個HeaderView 和FooterView
因專案需求寫了查詢資料寫了一個介面卡基類
package com.example.asus.recyclerviewheader; import android.content.Context; import android.support.v4.util.SparseArrayCompat; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.lang.reflect.Constructor; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; /** * base rycAdapter class */ public abstract class BaseRycAdapter<VH extends BaseRycAdapter.BaseViewHolder, T> extends RecyclerView.Adapter<VH> { private Context baseCxt; protected List<T> dataLists; //預設itemView 點選事件開關 private boolean itemViewClickToggle = true; // 設定大是為避免與itemType型別多時導致可能出現重複 private static final int BASE_ITEM_TYPE_HEADER = 100000; private static final int BASE_ITEM_TYPE_FOOTER = 200000; private SparseArrayCompat<View> headerViews = new SparseArrayCompat<>(); private SparseArrayCompat<View> footerViews = new SparseArrayCompat<>(); private ViewGroup mViewGroup; public void addHeaderView(View view) { headerViews.put(headerViews.size() + BASE_ITEM_TYPE_HEADER, view); } public void addFooterView(View view) { footerViews.put(footerViews.size() + BASE_ITEM_TYPE_FOOTER, view); } public View getHeaderView(int index) { return (index >= 0 && headerViews.size() > index) ? headerViews.valueAt(index) : null; } public View getFooterView(int index) { return (index >= 0 && footerViews.size() > index) ? footerViews.valueAt(index) : null; } public void removeHeaderView(int index) { headerViews.removeAt(index); } public void removeFooterView(int index) { footerViews.removeAt(index); } @Override public int getItemViewType(int position) { if(isHeaderViewPos(position)) return headerViews.keyAt(position); else if(isFooterViewPos(position)) return footerViews.keyAt(getFootersCount() + position - getItemCount()); return super.getItemViewType(position); } @Override public int getItemCount() { return headerViews.size() + dataLists.size() + footerViews.size(); } abstract class BaseViewHolder extends RecyclerView.ViewHolder { BaseViewHolder(View itemView) { super(itemView); if(isNormalItemView(itemView)) initItemView(itemView); } abstract void initItemView(View itemView); } @SuppressWarnings("WeakerAccess") private boolean isNormalItemView(View itemView) { return !(headerViews.indexOfValue(itemView) != -1 || footerViews.indexOfValue(itemView) != -1); } /** * GridLayoutManager佈局時“Head”和“Foot”處理 */ @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if(manager instanceof GridLayoutManager) { final GridLayoutManager gridManager = ((GridLayoutManager)manager); gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return getItemViewType(position) >= BASE_ITEM_TYPE_HEADER ? gridManager.getSpanCount() : 1; } }); } } /** * StaggeredGridLayoutManager佈局時“Head”和“Foot”處理 */ @Override public void onViewAttachedToWindow(VH holder) { super.onViewAttachedToWindow(holder); ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams(); if(lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) { StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams)lp; p.setFullSpan(getItemViewType(holder.getLayoutPosition()) >= BASE_ITEM_TYPE_HEADER); } } private boolean isHeaderViewPos(int position) { return position < getHeadersCount(); } private boolean isFooterViewPos(int position) { return position >= getItemCount() - getFootersCount(); } public int getHeadersCount() { return headerViews.size(); } public int getFootersCount() { return footerViews.size(); } @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { mViewGroup = parent; baseCxt = parent.getContext(); return getVHolder(viewType); } @Override public void onBindViewHolder(final VH holder, int position) { //判斷位置是頭或者尾部則直接返回 if(getItemViewType(position) >= BASE_ITEM_TYPE_HEADER) return; if(onItemClickListener != null && itemViewClickToggle) holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(itemViewClickToggle) onItemClickListener.onItemClick(holder.itemView, (holder.getLayoutPosition() - headerViews.size())); } }); onBindViewData(holder, (holder.getLayoutPosition() - headerViews.size())); } /** * 子類通過該方法設定item顯示資料 * * @param holder 泛型VH * @param position item position */ abstract void onBindViewData(VH holder, int position); /** * 反射獲取ViewHolder * * @param viewType itemView 型別 * @return 對應型別ViewHolder */ @SuppressWarnings("unchecked") private VH getVHolder(int viewType) { try { View itemView; if(headerViews.get(viewType) != null) itemView = headerViews.get(viewType); else if(footerViews.get(viewType) != null) itemView = footerViews.get(viewType); else { LayoutInflater inflater = LayoutInflater.from(baseCxt); itemView = inflater.inflate(getLayoutResId(), mViewGroup, false); } Class aClass = getClass(); Type genType = aClass.getGenericSuperclass(); Type[] params = ((ParameterizedType)genType).getActualTypeArguments(); Class vhClass = (Class)params[0]; Constructor constructor = vhClass.getDeclaredConstructor(aClass, View.class); return (VH)constructor.newInstance(this, itemView); } catch(Exception e) { e.printStackTrace(); return null; } } /** * 獲取itemView,子類實現 */ public abstract int getLayoutResId(); public List<T> getDataLists() { return dataLists; } public void setDataLists(List<T> dataLists) { this.dataLists = dataLists; } //點選監聽,可自行新增長按 interface OnItemClickListener { void onItemClick(View view, int position); } public boolean isItemViewClickToggle() { return itemViewClickToggle; } public void setItemViewClickToggle(boolean itemViewClickToggle) { this.itemViewClickToggle = itemViewClickToggle; } public OnItemClickListener getOnItemClickListener() { return onItemClickListener; } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } private OnItemClickListener onItemClickListener; }
使用時繼承並實現方法即可
package com.example.asus.recyclerviewheader; import android.view.View; import android.widget.TextView; /** * demo Adapter */ public class MainRycAdapter extends BaseRycAdapter<MainRycAdapter.MainViewHolder, BaseData> { // public class BaseData implements Serializable // { // private String baseDataStr = ""; // // public String getBaseDataStr() // { // return baseDataStr; // } // // public void setBaseDataStr(String baseDataStr) // { // this.baseDataStr = baseDataStr; // } // } /** * 設定正常資料 * * @param holder holder * @param position position */ @Override void onBindViewData(MainViewHolder holder, int position) { BaseData dataStr = dataLists.get(position); holder.textView.setText(dataStr.getBaseDataStr()); } /** * itemView layout */ @Override public int getLayoutResId() { return R.layout.item; } /** * ViewHolder */ class MainViewHolder extends BaseRycAdapter.BaseViewHolder { TextView textView; public MainViewHolder(View itemView) { super(itemView); } @Override void initItemView(View itemView) { textView = (TextView)itemView.findViewById(R.id.item_tv); } } }
在Activity中新增
Activity佈局就一個RecyclerView 沒什麼特別的地方,還有個問題就是儘量不要用滾動條巢狀的問題解決HeaderView這種問題,因為巢狀會導致item無法重用,資料越多問題越大。package com.example.asus.recyclerviewheader; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.CountDownTimer; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView)findViewById(R.id.ryc); ArrayList<BaseData> baseDatas = new ArrayList<>(); for(int i = 0; i < 4; i++) { BaseData baseData = new BaseData(); baseData.setBaseDataStr(("data" + i)); baseDatas.add(baseData); } final MainRycAdapter myAdapter = new MainRycAdapter(); myAdapter.setDataLists(baseDatas); for(int i = 0; i < 2; i++) { TextView head = new TextView(this); head.setText("head_i-" + i); head.setGravity(Gravity.CENTER); head.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 30)); TextView foot = new TextView(this); foot.setText("foot_i-" + i); foot.setGravity(Gravity.CENTER); foot.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100)); myAdapter.addHeaderView(head); myAdapter.addFooterView(foot); } myAdapter.setOnItemClickListener(new BaseRycAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Log.e("TAG", "click position = " + position); } }); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new RecycleViewDivider(this, GridLayoutManager.VERTICAL)); //recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); //recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)); recyclerView.setAdapter(myAdapter); new CountDownTimer(2000, 2000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { int headersCount = myAdapter.getHeadersCount(); for(int i = 0; i < headersCount; i++) { View headerView = myAdapter.getHeaderView(i); if(i != 0) { headerView.setBackgroundColor(Color.RED); ViewGroup.LayoutParams layoutParams = headerView.getLayoutParams(); layoutParams.height = 200; headerView.setLayoutParams(layoutParams); ((TextView)headerView).setText("延時操作更改文字顯示 - - index = " + i); } } myAdapter.removeHeaderView(0); myAdapter.notifyItemRemoved(0); } }.start(); } }
相關推薦
RecyclerView新增動態多個HeaderView 和FooterView
因專案需求寫了查詢資料寫了一個介面卡基類package com.example.asus.recyclerviewheader; import android.content.Context; import android.support.v4.util.SparseArr
ListView中動態顯示隱藏HeaderView和FooterView
roi ron mas relative 監聽事件 isp 刪除 listen 具體實現 ListView中動態顯示和隱藏Header&Footer 解決思路: 直接設置HeaderView和FooterView.setVisibility(View.GONE)無效
android_為recyclerView新增headerView和footerView以及recyclerview的重新整理
緊接著上一篇 新增head和foot headerAndFooterWrapper = new HeaderAndFooterWrapper(adapter); TextView t1 = new TextView(this); t1.setText("Heade
Android 為RecyclerView新增HeaderView和FooterView
對於新增headerView或者footerView其實HeaderView實際上也是Item的一種,只不過顯示在頂部的位置,那麼我們完全可以通過為其設定ItemType來完成。有了思路以後,接下來考慮一些細節。介面卡public class TimeTablesAdapte
RecyclerView新增HeaderView和FooterView
好了,現在問題來了,假設我們現在已經完成了RecyclerView的編寫,忽然有個需求,需要在列表上加個HeaderView,此時我們該怎麼辦呢?開啟我們的Adapter,然後按照我們上述的原理,新增特殊的ViewType,然後修改程式碼完成。這是比較常規的做法了,但是有個問題是,如果需要新增多個viewT
高效能的給RecyclerView加上HeaderView和FooterView
原始碼地址:https://github.com/bravinshi/AdvancedRecyclerView自己寫的是對於他人的改進,修復了若干問題。建議閱讀之前先讀一下這兩篇文章1,http://blog.csdn.net/lmj623565791/article/det
【Appnium+C#+Winform自動化測試系列】一、獲取本機連接的設備、啟動多個Appnium和獲取本機啟動的Appnium
net 系列 () 定向 目的 res listening toa 路徑 本系列內容,準備根據所完成的項目為基線,一步一步的把整個設計和實現過程梳理。 先從基本的一些環境問題入手,梳理清楚關於手機設備和Appnium。因為我們在後面的建立Appnium連接時,需要
Git 合並多個commit 和 cherry-pick的使用
-c mit article -abort 開始 撤銷 修改 進入 錯誤 合並多個commit 1、三個commit合並 git rebase -i commit_id 其中,-i 的參數是不需要合並的 commit 的 hash 值,這裏指的是第一條 c
多個if和一個ifelse的區別
scanf 我們 lse 的區別 成績 輸入 學生 解決 多個 一個程序的要求如下,輸入一個學生的數學成績,如果大於等於60,那麽就輸出good,如果小於60那麽輸出not good int a scanf_s("%d",&a) if(a>=60) { p
grep 同時滿足多個關鍵字和滿足任意關鍵字 grep 同時滿足多個關鍵字和滿足任意關鍵字
grep 同時滿足多個關鍵字和滿足任意關鍵字 grep 同時滿足多個關鍵字和滿足任意關鍵字 ① grep -E "word1|word2|word3" file.txt
grep 同時滿足多個關鍵字和滿足任意關鍵字
href class grep -E 滿足 之一 多個 small targe content grep 同時滿足多個關鍵字和滿足任意關鍵字 ① grep -E "word1|word2|word3" file.txt 滿足任意條件(word1、wor
蘋果電視服務明年下半年推出 將登陸100多個國家和地區
據國外媒體援引三位訊息靈通人士的話稱,蘋果計劃明年在超過100個國家和地區推出自己傳聞已久的電視訂閱服務。有分析認為,蘋果在推出這一服務後很快就將成為諸如亞馬遜和Netflix等公司的強勁競爭對手。 據悉,蘋果將首先在 2019 年上半年率先在美國推出這一服務,然後在未來數月將
oracle新增配置多個埠監聽
原來配置:listener.ora檔案如下: LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-L9P3QTT)(PORT = 1521)) (ADDRESS = (PROTOCO
JS為變速移動新增任意多個屬性值包括回撥函式
//封裝新增任意多個屬性的函式 //fn這個引數是為這個函式新增的回撥函式 function changeAll(ele,json,fn){ //每次都清除一次定時器 clearInterval(ele.timed); //設定定時器 ele.timed=se
nginx實現對映多個域名和負載均衡
當前我有2個網站,都需要部署上去,但是無奈,雲服務只有一臺,在買一臺的話就又太費錢,所以利用了nginx的多域名配置,從而實現利用一個 ip 訪問不同的域名,也節省了開支 配置方法也相對比較簡單,在nginx.conf配置檔案中 配置多個server 即可 user nob
第二十一講 多執行緒——多執行緒間的通訊——多個生產者和消費者
首先,試著思考一下執行如下程式,看會得出什麼結果。 // 描述資源 class Res { private String name; // 資源名稱 private int count = 1; // 資源編號 // 定義標記。
第二十二講 多執行緒——多執行緒間的通訊——多個生產者和消費者的升級解決方案
這裡我也是採用循序漸進的方式來講解JDK1.5版本中提供的多執行緒升級解決方案,希望能更加容易地讓大家接受。 為了解決多生產多消費的效率低下這一核心問題,在這兒我就告訴大家勢必要用到JDK1.5中jav
Object.defineProperties 新增一個/多個屬性到物件;修改已有屬性
語法: object.defineProperties(object, descriptors) 作用:除了可以用建構函式和字面量的方式為物件設定屬性,也可以使用 object.defineProperties來新增/設定物件屬性。 引數: object 必
[筆記]jsp 前臺展示多個PDF和JPG
之前是從前臺接收了一個檔案ID引數 這個功能的開發人員將各類檔案ID放在了一起,使用^隔開 檔案包括jpg、png、pdf 思路: 後臺接收-查詢對應檔案流-判斷檔案型別-前臺展示 程式碼
如何在IDEA中一個Tomcat啟動多個專案和多個Tomcat啟動多個專案
一、瞭解archive war包和exploded war包的區別 我們在使用IDEA在Tomcat中部署專案時會出現兩個選擇,分別是archive war和exploded war,如下圖: 只是從字面上理解一個是歸檔的,一個是分解的,具體有什麼區別呢?我們分別來看一下部署的效果。