Android22-ListView常用優(yōu)化技巧

1. 使用ViewHolder模式提高效率

  1. 定義一個內(nèi)部類ViewHolder
  2. 在getView()方法中通過視圖緩存機制來重用緩存即可偿凭。

設(shè)置item間的分隔線

注:這里可以把分隔線設(shè)置為一個顏色而叼,也可以設(shè)置為一個圖片資源神凑。

android:divider="@android:color/darker_gray" 
android:dividerHeight="10dp"

以下代碼可以把分隔線設(shè)置為透明:

android:divider="@null"

隱藏ListView的滾動條

android:scrollbars="none"

取消ListView的Item點擊效果

android:listSelector="#00000000"
android:listSelector="@android:color/transarent"

動態(tài)修改ListView

mData.add("new");
mAdapter.notifyDataSetChanged();

如上代碼店展,當修改了Adapter的映射List之后,只需要調(diào)用Adapter的notifyDatasetChanger()方法耘子,通知ListView修改數(shù)據(jù)源即可液南,需注意的是在使用mAdapter.notifyDataSetChanged()方法時,必須保證傳進Adapter的數(shù)據(jù)List是同一個List而不能是其他對象枚赡。

遍歷ListView中的所有Item

for (int i = 0; i < mListView.getChildCount(); i++) {
  View view = mListView.getChildAt(i);
}

處理空ListView

setEmptyView()方法可以在ListView中無數(shù)據(jù)時設(shè)置一個默認的顯示布局氓癌,而當ListView有數(shù)據(jù)的時候則不會顯示,代碼示例如下:

ListView listView = (ListView)findViewById(R.id.listView);
listView.setEmptyView(findViewById(R.id.empty_view));

ListView滑動監(jiān)聽

  • 使用OnTouchListener()來實現(xiàn)滑動監(jiān)聽
mListView.setOnTouchListener(new View.OnTouchListener() {
       switch(event.getAction()) {
           case MotionEvent.ACTION_DOWN:
               //觸摸時的操作
               break;
           case MotionEvent.ACTION_MOVE:
               //移動時的操作
               break;
           case MotionEvent.ACTION_UP:
               //手指離開屏幕時的操作
               break;
       }
});
  • 使用OnScrollListener()來實現(xiàn)滑動監(jiān)聽

OnScrollListener是AbsListView中的監(jiān)聽事件贫橙,它封裝了很多與ListView相關(guān)的信息贪婉。以下是OnScrollListener的一般使用方法。

mListView.setOnScrollListener(new OnScrollListener() {
       @Override
       public void onScrollStateChanged(AbsListView view, int scrollState) {
           switch (scrollState) {
               case OnScrollListener.SCROLL_STATE_IDLE:
                   //滑動停止時
                   Log.d("Test", "SCROLL_STATE_IDLE");
                   break;
               case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                   //正在滾動時
                   Log.d("Test", "SCROLL_STATE_TOUCH_SCROLL");
               case OnScrollListener.SCROLL_STATE_FLING:
                   //手指拋開時 
                   //在離開后卢肃,ListView由于慣性繼續(xù)滑動
                   Log.d("Test", SCROLL_STATE_FLING);
                   break;
           }
       }
       /*
       * view: 當前的ListView
       * firstVisibleItem: 當前能看見的第一個Item的ID疲迂,包括顯示一小半的Item
       * visibleItemCount: 當前能看見的Item總數(shù)
       * totalItemCount: 整個ListView的Item總數(shù)。
       */
       @Override
       public void onScroll(AbsListView view, 
       int firstVisibleItem,
       int visibleItemCount, 
       int totalItemCount) {
           //滾動時一直調(diào)用
           Log.d("Test", "onScroll");
       }
})
  • 判斷是否滾動到最后一行
if (firstVisibleItem + visibleItemCount == totalItemCount&&totalItem-Count>0) {
       //滾動到最后一行
}
  • 判斷滾動的方向
if (firstVisibleItem > lastVisibleItemPosition) {
       //上滑
} else if (firstVisibleItem < lastVisibleItemPosition){
       //下滑
}
lastVisibleItemPosition = firstVisibleItem;
  • 獲取可視區(qū)域內(nèi)的Item
//獲取可視區(qū)域內(nèi)最后一個Item的id
mListView.getLastVisiblePosition();
//獲取可視區(qū)域內(nèi)第一個Item的id
mListView.getFirstVisiblePosition();

ListView常用擴展

具有彈性的ListView


   //控制滑到邊緣到處理方法
   @Override
   protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
       return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxOverDistance, isTouchEvent);
   }

根據(jù)滑動方向莫湘,自動隱藏toolbar

public class ScrollHideList extends AppCompatActivity {

   private Toolbar mToolbar;
   private ListView mListView;
   private String[] mstr = new String[20];
   private int mTouchSlop;
   private float mFirstY;
   private float mCurrentY;
   private int direction;
   private ObjectAnimator mAnimator;
   private boolean mShow = true;

   View.OnTouchListener myTouchListener = new View.OnTouchListener() {
       @Override
       public boolean onTouch(View v, MotionEvent event) {
           switch (event.getAction()) {
               case MotionEvent.ACTION_DOWN:
                   mFirstY = event.getY();
                   break;
               case MotionEvent.ACTION_MOVE:
                   mCurrentY = event.getY();
                   if (mCurrentY - mFirstY > mTouchSlop) {
                       direction = 0;//down
                   } else if (mFirstY - mCurrentY > mTouchSlop) {
                       direction = 1;//up
                   }
                   if (direction == 1) {
                       if (mShow) {
                           toolbarAnim(1);//hide
                           mShow = !mShow;
                       }
                   } else if (direction == 0) {
                       if (!mShow) {
                           toolbarAnim(0);//show
                           mShow = !mShow;
                       }
                   }
                   break;
               case MotionEvent.ACTION_UP:
                   break;
           }
           return false;
       }
   };

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.scroll_hide);
       mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
       mToolbar = (Toolbar) findViewById(R.id.toolbar);
       mListView = (ListView) findViewById(R.id.listview);
       for (int i = 0; i < mstr.length; i++) {
           mstr[i] = "Item" + i;
       }
       View header = new View(this);
       header.setLayoutParams(new AbsListView.LayoutParams(
               AbsListView.LayoutParams.MATCH_PARENT,
               (int) getResources().getDimension(
                       R.dimen.abc_action_bar_default_height_material)));
       mListView.setAdapter(new ArrayAdapter<String>(ScrollHideList.this, android.R.layout.simple_expandable_list_item_1,
               mstr));
       mListView.setOnTouchListener(myTouchListener);
   }

   private void toolbarAnim(int flag) {
       if (mAnimator != null && mAnimator.isRunning()) {
           mAnimator.cancel();
       }
       if (flag == 0){
               mAnimator = ObjectAnimator.ofFloat(mToolbar, "translationY", mToolbar.getTranslationY(),0);
       } else {
               mAnimator = ObjectAnimator.ofFloat(mToolbar, "translationY", mToolbar.getTranslationY(),-mToolbar.getHeight());
       }
       mAnimator.start();
   }
}

動態(tài)改變ListView布局

public class FocusListViewAdapter extends BaseAdapter {

   private List<String> mData;
   private Context mContext;
   private int mCurrentItem;

   public FocusListViewAdapter(Context context, List<String> data) {
       this.mContext = context;
       this.mData = data;
   }

   public int getCount() {
       return mData.size();
   }

   public Object getItem(int position) {
       return mData.get(position);
   }

   public long getItemId(int position) {
       return position;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {
       LinearLayout layout = new LinearLayout(mContext);
       layout.setOrientation(LinearLayout.VERTICAL);
       if (mCurrentItem == position) {
           layout.addView(addFocusView(position));
       } else {
           layout.addView(addNormalView(position));
       }
       return layout;
   }

   public void setmCurrentItem(int currentItem) {
       this.mCurrentItem = currentItem;
   }

   private View addFocusView(int i) {
       ImageView iv = new ImageView(mContext);
       iv.setImageResource(R.mipmap.ic_launcher);
       return iv;
   }

   private View addNormalView(int i) {
       LinearLayout layout = new LinearLayout(mContext);
       layout.setOrientation(LinearLayout.HORIZONTAL);
       ImageView iv = new ImageView(mContext);
       iv.setImageResource(R.mipmap.ic_launcher);
       layout.addView(iv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
       TextView tv = new TextView(mContext);
       tv.setText(mData.get(i));
       layout.addView(tv,new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
       layout.setGravity(Gravity.CENTER);
       return layout;
   }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尤蒿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子逊脯,更是在濱河造成了極大的恐慌优质,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件军洼,死亡現(xiàn)場離奇詭異巩螃,居然都是意外死亡,警方通過查閱死者的電腦和手機匕争,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門避乏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甘桑,你說我怎么就攤上這事拍皮〈醵#” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵铆帽,是天一觀的道長咆耿。 經(jīng)常有香客問我,道長爹橱,這世上最難降的妖魔是什么萨螺? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮愧驱,結(jié)果婚禮上慰技,老公的妹妹穿的比我還像新娘。我一直安慰自己组砚,他們只是感情好吻商,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著糟红,像睡著了一般艾帐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上改化,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天掩蛤,我揣著相機與錄音,去河邊找鬼陈肛。 笑死揍鸟,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的句旱。 我是一名探鬼主播阳藻,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼谈撒!你這毒婦竟也來了腥泥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤啃匿,失蹤者是張志新(化名)和其女友劉穎蛔外,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溯乒,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡夹厌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了裆悄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矛纹。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖光稼,靈堂內(nèi)的尸體忽然破棺而出或南,到底是詐尸還是另有隱情孩等,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布采够,位于F島的核電站肄方,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吁恍。R本人自食惡果不足惜扒秸,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冀瓦。 院中可真熱鬧,春花似錦写烤、人聲如沸翼闽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽感局。三九已至,卻和暖如春暂衡,著一層夾襖步出監(jiān)牢的瞬間询微,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工狂巢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撑毛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓唧领,卻偏偏與公主長得像藻雌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子斩个,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容