我想在顯示數據時更新RecyclerView
,在我的情況下,我顯示帶或不帶標籤的圖像。RecyclerView - 獲取所有現有視圖/查看者
默認情況下,我在創建視圖持有人時設置了標籤的可見性,這很好,但我希望用戶在顯示RecyclerView
時通過菜單更改標籤可見性,所以我想手動更新可見性RecyclerView
中的所有現有視圖。
我能以某種方式獲得所有現有Views
嗎?我需要所有,不僅是可見的,我不希望以後回收View
不更新...
我想在顯示數據時更新RecyclerView
,在我的情況下,我顯示帶或不帶標籤的圖像。RecyclerView - 獲取所有現有視圖/查看者
默認情況下,我在創建視圖持有人時設置了標籤的可見性,這很好,但我希望用戶在顯示RecyclerView
時通過菜單更改標籤可見性,所以我想手動更新可見性RecyclerView
中的所有現有視圖。
我能以某種方式獲得所有現有Views
嗎?我需要所有,不僅是可見的,我不希望以後回收View
不更新...
在adaptater類:
Boolean isVisible = false;
public CustomAdapter(boolean isVisible) {
this.isVisible= isVisible;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
...
if (isVisible){
//setVisibility(View.VISIBLE)
}else{
//setVisibility(View.INVISIBLE
}
}
public void updateVisibility(boolean newValue){
isVisible= newValue;
}
在Activity
要更新其中適配器被實例化的價值:
adapter.updateVisibility(false);
adapter.notifydataSetChanged();
所有現有的視圖是可見的,加上一些視圖緩存由RecyclerView
。您可以訪問所有可見View
就像那樣:
View child;
for (int i = 0; i < mRecycler.getChildCount(); i++) {
child = mRecycler.getChildAt(i);
//In case you need to access ViewHolder:
mRecycler.getChildViewHolder(child);
}
即使你訪問緩存View
就是他們不是在綁定到數據還沒有,所以你不會知道,如果標籤應該是可見或不可見。只需在onBindViewHolder
中設置其餘Views
的標籤可見性即可。
View
的其餘部分根本不存在,所以即使它們對所有人都是相同的標籤可見性狀態,您也無法更改任何關於它們的內容。
這是行不通的,如果我這樣做,並不是所有的緩存視圖都會返回... – prom85
我在哪裏寫了這個信息,讓您可以訪問**緩存的**視圖?無論如何,訪問它們都沒有意義。只需修改** visible **視圖,就像我上面所說的那樣,其餘的應該在'RecyclerView'需要時在'onBindViewHolder'中修改。 – InTwoMinds
您編寫了「加上緩存的一些視圖」...我沒有看到您繼續只引用可見視圖。如果我修改視圖,我也必須修改所有緩存的視圖。當'RecyclerView'回收一個緩存視圖時,我希望它已經具有標籤所需的可見性,這樣我就不必一直將其設置在'onBindView'中......否則我不需要直接修改視圖並且只能在'onBindView'上只做這個... – prom85
首先,你需要獲得顯示各方面的意見指數,然後你需要去在每個,並使用每個視圖的viewHolder:
final int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
final int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; ++i) {
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
...
}
編輯:它似乎並不總是返回您可能要處理的所有ViewHolders。這似乎是一個更穩定的解決方案:
for (int childCount = recyclerView.getChildCount(), i = 0; i < childCount; ++i) {
final ViewHolder holder = recyclerView.getChildViewHolder(mRecyclerView.getChildAt(i));
...
}
這是「獲取所有現有視圖/查看者」問題的正確答案,以及我所需要的。非常感謝! –
如果說明如何獲得對layoutManager變量的引用,此答案會更有幫助。 –
@JasonTyler爲了使用一個RecyclerView,你總是創建一個LayoutManager實例,所以你之前有它。這裏有一種方法來創建它,像垂直列表一樣工作(但同樣需要選擇使用哪一個):LayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false) –
notifyDataSetChanged()
不方便。我只是嘗試看我把日誌,RV結合更多的項目是不可見的,事實上,我發現沒有辦法對它們進行檢索。我結束了對緩存在Set
或List
那些ViewHolders在onBindViewHolder()
和非緩存他們onViewRecycled()
:
private Set<AbstractViewHolder> mBoundViewHolders = new HashSet<>();
private int mVisibility = View.VISIBILE;
// So you can have access from the Activity/Fragment
public Set<AbstractViewHolder> getAllBoundViewHolders() {
return Collections.unmodifiableSet(mBoundViewHolders);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) {
// Binding code
...
holder.view.setVisibility(mVisibility);
// Caching VH
mBoundViewHolders.add((AbstractViewHolder) holder);
}
@Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
// Uncaching VH
mBoundViewHolders.remove(holder);
}
// Your method becomes
public void updateVisibility(int visibility) {
mVisibility = visibility;
for (AbstractViewHolder holder : mBoundViewHolders) {
holder.updateVisibility(visibility);
}
}
實現你的接口或抽象ViewHolder這樣你就可以打電話給你的方法。 通過這種方式,您可以訪問您的ViewHolder內容。
這是我在做FlexibleAdapter取消選擇的項目不調用notifyItemRangeChanged()
。如果用戶有動畫,所有的都會被執行,當我調用我的方法toggleActivation()
時,還會加上背景變化。
如果您知道更好的方法來檢索所有綁定的VH,請告訴我。
如果不是添加和刪除到集合中,我只是將所有ViewHolders存儲在onCreateViewHolder中會發生什麼? –
@androiddeveloper在我的庫中,它不能工作,因爲VH尚未創建。但是您可以嘗試查看適配器中發生的情況。 – Davidea
@Davidea我以前沒有給你這個答案!良好的解決方法的人! –
所有上述解決方案只給出可見的持有者,但實際上有2-3個其他持有者被綁定但不可見。爲了讓那些爲好, 最簡單的,我能想到的準確的方式來獲得所有的持有人是:
int lastBoundHolderPosition = -1;
int lastDetachedHolderPosition = -1;
public void onBindViewHolder(final MyViewHolder holder, int position) {
lastBoundHolderPosition = position;
//Your implementation
}
public void onViewDetachedFromWindow(MyViewHolder holder){
lastDetachedHolderPosition = holder.holder.getAdapterPosition();
}
當你想所有的適配器可見(加約束,但不可見):
if(lastDetachedHolderPosition == -1){
for(pos = 0; pos <= lastDetachedHolderPosition; pos++){
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(pos);
}
}else{
if(lastBoundHolderPosition > lastDetachedHolderPosition){ //Scroll down
//get all the bound holders
for(int pos = lastDetachedHolderPosition + 1; pos <= lastBoundHolderPosition; pos++){
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(pos);
}
}else{ //Scroll up
//get all the bound holders
for(int pos = lastBoundHolderPosition ; pos <= lastDetachedHolderPosition-1; pos++){
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(pos);
}
}
}
如何在不滾動的情況下獲取查看者?例如,點擊按鈕? –
@androiddeveloper編輯,以滿足這一要求。 –
hmmm ...另一個類似的方法是擁有一組ViewHolders,這也可以避免調用「findViewHolderForAdapterPosition」。可以更短,可能會更有效一點。不是? –
您是否有任何參數知道標籤是否可見或不在onBindViewHolder中?你應該檢查這個參數。更新菜單中的參數並設置adapter.notifyDataSetChanged – Chol
我正在閱讀首選項,所以我想這樣做一次,而不是總是......我可以用適配器內部的布爾值來做到這一點,沒有想想實際上...... – prom85
這個參數對於所有的項目都是一樣的嗎?或者可以根據項目有所不同? – Chol