<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 探究Android中Listview顯示錯(cuò)亂問題

          探究Android中Listview顯示錯(cuò)亂問題

          作者: 時(shí)間:2016-09-12 來源:網(wǎng)絡(luò) 收藏

          問題

          本文引用地址:http://www.ex-cimer.com/article/201609/304307.htm

          最近在項(xiàng)目中遇到過一個(gè)很棘手的問題,就是ListView在滑動(dòng)后就莫名其妙的顯示錯(cuò)亂,網(wǎng)上查閱資料后問題很容易的就解決了,但是對(duì)于問題產(chǎn)生的原因仍是一知半解,所以不甘心的我定下心來,狠讀源碼,終于理清了其中的”奧秘“。

          由來

          一般的關(guān)于Adapter中g(shù)etView的寫法不外乎以下形式:

          @Override

          public View getView(int position, View convertView, ViewGroup parent) {

          ViewHolder holder;

          if (convertView == null) {

          convertView = mLayout.inflate(R.layout....);

          holder = new ViewHolder();

          holder.textView = (TextView) convertView

          .findViewById(R.id.textview);

          ... ...

          convertView.setTag(holder);

          } else {

          holder = (ViewHolder) convertView.getTag();

          }

          holder.textView.setText(mText + position);

          return convertView;

          }

          在Android源碼中關(guān)于getView方法的實(shí)現(xiàn)就是采用的以上形式,如ArrayAdapter等。因?yàn)檫@種寫法的好處也是顯而易見的,如果該position的convertview曾經(jīng)被加載過,在數(shù)據(jù)集合未被改動(dòng)的前提下,系統(tǒng)會(huì)自動(dòng)將該position的convertview緩存起來,避免重復(fù)加載耗費(fèi)資源。

          然后問題就來了,當(dāng)時(shí)我就”自作小聰明“,覺得當(dāng)convertview==null時(shí)只是做了item布局的加載以及相關(guān)控件ID的綁定操作,為什么連內(nèi)容的加載操作也放入其中呢,這樣下次加載緩存是就省去內(nèi)容set的操作了,然后就出現(xiàn)了滑動(dòng)ListView后數(shù)據(jù)顯示錯(cuò)位的問題-。-。

          原因

          后來看源碼發(fā)現(xiàn),原來AbListView中獲取getView()和滑動(dòng)操作是異步進(jìn)行的,其中滑動(dòng)操作在一個(gè)FlingRunnable的支線程中運(yùn)行,所以這就導(dǎo)致了在ListView在滑動(dòng)時(shí)可能已經(jīng)滑動(dòng)到了第十行,但可能第二行的數(shù)據(jù)這時(shí)就被直接使用了,這就是導(dǎo)致數(shù)據(jù)加載錯(cuò)亂的根本原因。

          附上源碼中對(duì)FlingRunnable的注釋:

          /**

          * Responsible for fling behavior. Use {@link #start(int)} to

          * initiate a fling. Each frame of the fling is handled in {@link #run()}.

          * A FlingRunnable will keep re-posting itself until the fling is done.

          *

          */

          private class FlingRunnable implements Runnable {

          /**

          * Tracks the decay of a fling scroll

          */

          private final OverScroller mScroller;

          ... ...

          }

          解決方法

          所以唯一的解決方法就是只在convertview中緩存該ChildView的layout,但ChildView 中的數(shù)據(jù)必須每次都重新獲取并加載。其實(shí)ListView數(shù)據(jù)加載及數(shù)據(jù)緩存是比較復(fù)雜的(幾個(gè)相關(guān)的類加起來上完行=。=),所以以后有機(jī)會(huì)還是要好好研讀源碼,這樣才能更加透徹的理解原理。



          關(guān)鍵詞:

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();