最近項(xiàng)目中用到了點(diǎn)擊顯示下拉列表龄恋,列表呀當(dāng)然要用list顯示啊疙驾,當(dāng)然也可以不用,有人說(shuō)郭毕,可以簡(jiǎn)單粗暴的用死布局直接剛它碎。好了,那個(gè)說(shuō)直接剛的人你可以閉嘴了显押,數(shù)據(jù)是后臺(tái)返的扳肛,是變化的,這樣只能用列表來(lái)動(dòng)態(tài)的顯示數(shù)據(jù)乘碑,再加上后來(lái)還加入了一個(gè)點(diǎn)擊顏色變化的需求挖息,遂才引出這篇文章,List列表的局部更新兽肤。
一套腹、RecyclerView局部刷新
????RecyclerView的局部刷新是有區(qū)分的,有數(shù)據(jù)的刷新和 item 結(jié)構(gòu)的刷新资铡,局部的 item 插入电禀、刪除、移動(dòng)刷新方法都是結(jié)構(gòu)的刷新笤休。而 notifyItemChanged尖飞、notifyItemRangeChanged 方法屬于數(shù)據(jù)的刷新。
1. 數(shù)據(jù)刷新
數(shù)據(jù)刷新還分全部刷新和局部刷新店雅,
全部刷新:**notifyDataSetChanged()**,**notifyItemChanged(int)**;
局部刷新:**notifyItemRangeChanged(int,int)**(從指定位置開始刷新指定個(gè)item)政基,
**notifyItemChanged(int, Object)**。
這里notifyItemChanged底洗,第二個(gè)參數(shù)控制刷新全部還是局部腋么,如:
@Override
public void onBindViewHolder(MyViewHolder holder, final int position, List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
if (payloads.isEmpty()){
//全部刷新
}else {
//局部刷新
}
}
這里主要講刷新指定item。
2. item 結(jié)構(gòu)刷新
結(jié)構(gòu)刷新分:插入亥揖、移動(dòng)珊擂、移除一個(gè)并自動(dòng)刷新
插入:notifyItemInserted(int)
用法:
/**
* 添加并更新數(shù)據(jù),同時(shí)具有動(dòng)畫效果
*/
public void addDataAt(int position, DataBean data) {
mDatas.add(position, data);
notifyItemInserted(position);//更新數(shù)據(jù)集费变,注意如果用adapter.notifyDataSetChanged()將沒有動(dòng)畫效果
}
移動(dòng):notifyItemMoved(int)
移除:notifyItemRemoved(int)
用法:
/**
* 移除并更新數(shù)據(jù)摧扇,同時(shí)具有動(dòng)畫效果
*/
public void removeDataAt(int position) {
mDatas.remove(position);
notifyItemRemoved(position);
}
二、ListView局部刷新
非notifyDataSetChanged方式挚歧。
方法一:更新對(duì)應(yīng)view的內(nèi)容
item點(diǎn)擊事件{
datas.set(position, "改變當(dāng)前位置數(shù)據(jù)" + position);
updateSingle(position);//要更新的位置
}
/**
*
* @param position 要更新的位置
*/
private void updateSingle(int position) {
/**第一個(gè)可見的位置**/
int firstVisiblePosition = listView.getFirstVisiblePosition();
/**最后一個(gè)可見的位置**/
int lastVisiblePosition = listView.getLastVisiblePosition();
/**在看見范圍內(nèi)才更新扛稽,不可見的滑動(dòng)后自動(dòng)會(huì)調(diào)用getView方法更新**/
if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
/**獲取指定位置view對(duì)象**/
View view = listView.getChildAt(position - firstVisiblePosition);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(datas.get(position));
}
}
方法二:通過(guò)ViewHolder去設(shè)置值
/**
* 找出對(duì)應(yīng)的ViewHolder,通過(guò)ViewHolder去設(shè)置值
*
* @param position 要更新的位置
*/
private void updateOne(int position) {
/**第一個(gè)可見的位置**/
int firstVisiblePosition = listView.getFirstVisiblePosition();
/**最后一個(gè)可見的位置**/
int lastVisiblePosition = listView.getLastVisiblePosition();
/**在看見范圍內(nèi)才更新滑负,不可見的滑動(dòng)后自動(dòng)會(huì)調(diào)用getView方法更新**/
if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
/**獲取指定位置view對(duì)象**/
View view = listView.getChildAt(position - firstVisiblePosition);
/**通過(guò)ViewHolder找出緩存的對(duì)應(yīng)控件**/
TextView textView = CommonViewHolder.get(view, R.id.textView);
textView.setText(datas.get(position));
}
}
方法三:調(diào)用一次getView()方法
這種方法是調(diào)用適配器對(duì)應(yīng)的getView方法在张,用它里面的代碼對(duì)界面進(jìn)行刷新盘寡。這也是google在IO大會(huì)上推薦的做法
item點(diǎn)擊事件{
datas.set(position, "改變當(dāng)前位置數(shù)據(jù)" + position);
updateItem(position);//要更新的位置
}
/**
* 調(diào)用一次getView()方法夷磕;Google推薦的做法
*
* @param position 要更新的位置
*/
private void updateItem(int position) {
/**第一個(gè)可見的位置**/
int firstVisiblePosition = listView.getFirstVisiblePosition();
/**最后一個(gè)可見的位置**/
int lastVisiblePosition = listView.getLastVisiblePosition();
/**在看見范圍內(nèi)才更新笙纤,不可見的滑動(dòng)后自動(dòng)會(huì)調(diào)用getView方法更新**/
if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
/**獲取指定位置view對(duì)象**/
View view = listView.getChildAt(position - firstVisiblePosition);
commonAdapter.getView(position, view, listView);
}
}
最后宵蛀,參考鏈接:
DylanAndroid的csdn博客