1. 程式人生 > >PagerAdapter使用notifyDataSetChanged 但是檢視併為改變的原因。

PagerAdapter使用notifyDataSetChanged 但是檢視併為改變的原因。

PagerAdapter使用notifyDataSetChanged 但是有時資料併為改變的原因。
class ViewAdapter extends PagerAdapter{
    private List<View> list;
ViewAdapter(List<View> list){
        this.list = list;
}
    //返回view檢視的數目
@Override
public int getCount() {
        return list.size();
}
    // 當要顯示的檢視可以進行快取的時候,會呼叫這個方法進行顯示檢視的初始化,
// 我們將要顯示的View加入到ViewGroup中,然後作為返回值返回即可 @Override public Object instantiateItem(ViewGroup container, int position) { return super.instantiateItem(container, position); } //PagerAdapter只快取一定的檢視,如果滑動的檢視超出了快取的範圍,就會呼叫這個方法,將檢視銷燬 @Override public void destroyItem(ViewGroup container, int position,
Object object) { super.destroyItem(container, position, object); } // 來判斷顯示的是否是同檢視(物件),這裡我們將兩個引數相比較返回即可 @Override public boolean isViewFromObject(View view, Object object) { return false; } }

一個viewPager 的Adapter必須實現的四個方法。 當傳入listView時 檢視呼叫方法初始化,之後想要改變viewPager中的檢視,即需要改變傳入的listView值時,
之後再呼叫 adapter.notiyDatasetChange()。 改變所有的資料可以在實現PagerAdapter時,寫一個setList( ? extend List<T>)方法 中帶有notiyDatasetChange() 方法,這樣在外部改變值的時候直接改變listView即可。 例如:
public void setList(List<View>list) {
    this.list = list;
notifyDataSetChanged();
}

但實際上,傳入不同的listView 且呼叫了notifyDataSetChanged方法時,檢視有時並未改變。 這是為什麼呢? 我們來看一下關於notifyDataSetChange()的原始碼:
/**
 * This method should be called by the application if the data backing this adapter has changed
 * and associated views should update.
 */
public void notifyDataSetChanged() {
    synchronized (this) {
        if (mViewPagerObserver != null) {
            mViewPagerObserver.onChanged();
}
    }
    mObservable.notifyChanged();
}
private DataSetObserver mViewPagerObserver;

DataSetObserver 這個資料觀察者明顯是從ViewPager中去實現的
然後我去ViewPager中找了找這個mViewPagerObserver
private class PagerObserver extends DataSetObserver {
    PagerObserver() {
    }

    @Override
public void onChanged() {
        dataSetChanged();
}
    @Override
public void onInvalidated() {
        dataSetChanged();
}
}
找到他呼叫的位置
void setViewPagerObserver(DataSetObserver observer) {
    synchronized (this) {
        mViewPagerObserver = observer;
}
}
所以可以發現呼叫notifyDataSetChanged 時,會觸發ViewPager的 PagerObserver 的
dataSetChanged方法
dataSetChanged的原始碼描述如下
void dataSetChanged() {
    // This method only gets called if our observer is attached, so mAdapter is non-null.
final int adapterCount = mAdapter.getCount();
mExpectedAdapterCount = adapterCount;
    boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1
&& mItems.size() < adapterCount;
    int newCurrItem = mCurItem;
    boolean isUpdating = false;
    for (int i = 0; i < mItems.size(); i++) {
        final ItemInfo ii = mItems.get(i);
    //通過getItemPosition(Object object)的返回值來執行的後續操作,
        final int newPos = mAdapter.getItemPosition(ii.object);
    //可以發現當返回值為POSITION_UNCHANGED 直接跳出迴圈
        if (newPos == PagerAdapter.POSITION_UNCHANGED) {
            continue;
}
    //而為 PagerAdapter.POSITION_NONE 時,才繼續執行後續操作
        if (newPos == PagerAdapter.POSITION_NONE) {
            mItems.remove(i);
i--;
            if (!isUpdating) {
                mAdapter.startUpdate(this);
isUpdating = true;
}

            mAdapter.destroyItem(this, ii.position, ii.object);
needPopulate = true;
            if (mCurItem == ii.position) {
                // Keep the current item in the valid range
newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1));
needPopulate = true;
}
            continue;
}

        if (ii.position != newPos) {
            if (ii.position == mCurItem) {
                // Our current item changed position. Follow it.
newCurrItem = newPos;
}

            ii.position = newPos;
needPopulate = true;
}
    }

    if (isUpdating) {
        mAdapter.finishUpdate(this);
}

    Collections.sort(mItems, COMPARATOR);
    if (needPopulate) {
        // Reset our known page widths; populate will recompute them.
final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (!lp.isDecor) {
                lp.widthFactor = 0.f;
}
        }

        setCurrentItemInternal(newCurrItem, false, true);
requestLayout();
}
}
可以看到 mAdapter.getItemPosition(ii.object); 的返回值決定了後續的操作,而預設的PagerAdapter的實現類 getItemPosition(Object object)返回值為 PagerAdapter.POSITION_UNCHANGED;因此當未重寫getItemPosition(Object object )方法時,呼叫 notiydataSetChanged()方法他/她並未執行我們想要得到接過。 因此需要我們將getItemPosition(Object object重寫 將返回值寫成PagerAdapter.POSITION_NONE 它才會呼叫銷燬檢視的方法,之後得到我們想要的結果。
//為了內部檢視變換
@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
}
至此,再次執行程式即可得到你想要的接過。

相關推薦

PagerAdapter使用notifyDataSetChanged 但是檢視改變原因

PagerAdapter使用notifyDataSetChanged 但是有時資料併為改變的原因。 class ViewAdapter extends PagerAdapter{ pr

SQL之merge into 批量更新資料 Merge關鍵字是一個神奇的DML關鍵字它在SQL Server 2008被引入,它能將Insert,Update,Delete簡單的一句M

轉載http://www.cnblogs.com/ruiati/archive/2013/01/18/2866017.html     Merge關鍵字是一個神奇的DML關鍵字。它在SQL Server 2008被引入,它能將Insert,Up

寫一個函數計算參數n(n很大)時的值1-2+3-4+5-6+7……+n(考慮程序執行效率)

參數 color n) col sys class n-1 == code 1 private static void jisuan(int n) { 2 int sum=0; 3 if(n%2==0){ 4 sum=-(n/2)

SQL Server 檢測到基於一致性的邏輯 I/O 錯誤 pageid 不正確(應 1:1772,實際 0:0)在文件 'D:Program FilesMicrosoft SQL Ser

red 完成 sdn blank net tools ocl views 偏移 SQL Server 檢測到基於一致性的邏輯 I/O 錯誤 pageid 不正確(應為 1:1772,但實際為 0:0)。在文件 ‘D:\Program Files\Microsoft S

Webservice報錯客戶端發現響應內容類型“application/json;charset=UTF-8”,“text/xml”

san 有關 棧跟蹤 手動 cat mil not soap con 控制臺對接Webservice正常,同樣的方法在Web項目上報錯: 客戶端發現響應內容類型為“application/json;charset=UTF-8”,但應為“

scrollTop總原因;如何檢視滾動條的位置或者說滾動條的滾動距離(待完善)

1、document.body.scrollTop的值總為零的原因有一個功能需要判斷下拉的距離,設定頭部固定導航欄的顏色。 程式碼如下: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8">

jhipster生成的工程war包部署到tomcat中,tomcat正常啟動,一直不載入專案的問題原因

jhipster生成工程打成war包,可以直接採用java -jar war包命令執行。 如果要將其放到tomcat下webapps中執行,如果tomcat啟動成功,也將war包解壓開,但就是不載入工程。此問題困擾很長時間,最終發現是jdk版本問題導致。 出現此問題,需要檢

雷軍:順勢而,看起來不夠有情懷,這是成功的真諦

第一個你看到了電子商務的威力,我們用電子商務直銷的模式,去掉了渠道成本和銷售成本;第二個你看到了社交媒體的威力,我們用新媒體和自媒體營銷的方式包括口碑營銷的方式,去掉了營銷成本;第三個我們是最早把手機當電腦做的;第四個是小米更強大的,我們發動了粉絲群眾運動;第五個是獨特的使用者群定位和維護使用者群的方式,我們

Oracle資料庫新建使用者其建立一個檢視(示例)

1.建立使用者 //<1> 以sysdba管理員登入建立使用者smart/smart sqlplus /nolog conn /as sysdba; create user s

TextView 實現部分文字改變多種顏色單段或多段不同顏色的文欄位新增不同點擊事件

今天晨諾星空繼續給大家分享乾貨知識,福利來了,哈哈。如果你喜歡可以點個關注哦,男同胞關注了就是好哥們兒,哈哈,兄弟,有啥問題找我探討,保你解決,沒有什麼是一杯酒解決不了的,如果又就兩杯,哈哈,女同胞的話,除了帶給你點程式設計的營養與乾貨,別的估計也只剩以身相許了

什麽那麽多自學Python的後來都放棄了,原因

視頻 amp 大牛 並不是 推薦 技術分享 tro 公司 ref 目前信息化產業發展勢頭很好,互聯網就成為了很多普通人想要涉及的行業,因為相比於傳統行業,互聯網行業漲薪幅度大,機會也多,所以就會大批的人想要轉行來學習Python開發。目前來講市場上需要的Python人員非常

魂鬥羅、雙截龍你一定玩過,你知道什麽它要“山寨嗎?

施瓦辛格 好萊塢大片 福爾摩斯 人民網 拯救地球 “初代遊戲兩關縱深行進的軍事基地、第七關充滿機械利爪的工廠、《超級魂鬥羅》第四關巨大的升降梯,都契合了《終結者》(1984)、《機器戰警》(1987)以及《霹靂五號》(1986)等科幻電影對於機械與機器人的描繪。”看到網上這段文字時,我的腦

有感於微課數據同步多次 也與雲上的不一致問題,大家的思路不清楚是主要原因

bre get 數據 star enc 不一致 ble spa into import requests import json # pip install requests scheme_id=105887 start_num=0 limit_count

Web 應用程序項目 Himall.Web 已配置使用 IIS 無法訪問 IIS 元數據庫

權限 解決方法 使用 all 出現問題 無法 程序 bsp 點擊 Web應用程序項目XXXX已配置為使用IIS。無法訪問IIS元數據庫。您沒有足夠的特權訪問計算機上的IIS網站,xxxxiis 問題:Windows8下直接使用VS打開項目,出現問題:XXXX已配置為使用

當padding/margin的取值形式百分比時

基礎 https 技術分享 因此 w3c 就會 頁面 org 圖片加載 一個基礎卻又容易混淆的css知識點:當margin/padding取形式為百分比的值時,無論是left/right,還是top/bottom,都是以父元素的width為參照物的!也許你會說,left/r

哲學家們只是用不同的方式解釋世界,而問題在於改變世界

ilo 獲得 change swe com gate var chan 不同 這是馬克思的墓誌銘。在倫敦highgate公墓,用金字刻在大理石墓碑上。The philosophers have only interpreted the world in various w

UWP DEP0700: 應用程序註冊失敗[0x80073CF9] 另一個用戶已安裝此應用的未打包版本當前用戶無法將該版本替換打包版本

.cn 打包 ive 另一個 pan package 用戶 AC size 原文:UWP DEP0700: 應用程序註冊失敗。[0x80073CF9] 另一個用戶已安裝此應用的未打包版本。當前用戶無法將該版本替換為打包版本。最近電腦抽風,我在【應用程序和功能】中重置了以下我

Dual Path Networks(DPN)——一種結合了ResNet和DenseNet優勢的新型卷積網絡結構深度殘差網絡通過殘差旁支通路再利用特征,殘差通道不善於探索新特征密集連接網絡通過密集連接通路探索新特征,有高冗余度

哪裏 esc 數學 itemid tip 視覺 bat tlist badge 如何評價Dual Path Networks(DPN)? 論文鏈接:https://arxiv.org/pdf/1707.01629v1.pdf在ImagNet-1k數據集上,淺DPN超過

在js中if條件null/undefined/0/NaN/""表達式時,統統被解釋false,此外均true哦(官方原文如下:)

In if條件 對象 strong 表達 clas tro 數字 此外 Boolean 表達式 一個值為 true 或者 false 的表達式。如果需要,非 Boolean 表達式也可以被轉換為 Boolean 值,但是要遵循下列規則: 所有的對象都被當作 true。 當

環狀鏈表的相遇節點出發節點

第一次 點距 出發 兩個指針 思路 鏈表 距離 nbsp tar 題目: 一個環狀鏈表(收尾相連),兩個指針 head1 和 head2 從同一個節點出發,head1 每次 走一步,head2 每次走兩步,請證明,兩個指針第一次相遇於出發的節點 思路:假設兩個節點相