您的位置:首页 > 其它

ListView局部刷新的问题

2016-06-03 16:23 671 查看
有时候,我们需要更改ListView中某一个Item样式,假如这个时候使用notifydatasetChanged去刷新整个界面是没有必要的,今天我们看看如何只刷新指定条目的Item.



public class ListAdapter extends BaseAdapter {

private List<Model> datas;
private Context context;

private UpdateCallback updateCallback;

public UpdateCallback getUpdateCallback() {
return updateCallback;
}

public void setUpdateCallback(UpdateCallback updateCallback) {
this.updateCallback = updateCallback;
}

public ListAdapter(Context context) {
datas = new ArrayList<Model>();
this.context = context;
}

public void addData(Model model) {
datas.add(model);
notifyDataSetChanged();
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return datas.size();
}

@Override
public Object getItem(int pos) {
// TODO Auto-generated method stub
return datas.get(pos);
}

@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(final int pos, View convertView, ViewGroup viewGroup) {
final Model model = datas.get(pos);
ViewHolder viewHolder = null;
if (null == convertView) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.list_item_layout, null);
viewHolder.pb = (ProgressBar) convertView
.findViewById(R.id.pb_show);
viewHolder.btn = (Button) convertView.findViewById(R.id.btn);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
convertView.setTag(viewHolder);
}
viewHolder.btn.setText(model.getName());
viewHolder.btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(null != updateCallback){
updateCallback.startProgress(model,pos);
}
}
});
viewHolder.pb.setProgress(0);
// cache the view
return convertView;
}

public static class ViewHolder {
ProgressBar pb;
Button btn;
}
}


public class MainActivity extends Activity implements UpdateCallback{
ListView listview;
private ListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
afterViews();
}

void afterViews() {
adapter = new ListAdapter(this);
adapter.setUpdateCallback(this);
listview.setAdapter(adapter);
initDatas();
}

private void initDatas() {
for(int i = 0;i<100;i++){
Model model = new Model(i, "<Click> --> ");
adapter.addData(model);
}
}

@Override
public void startProgress(final Model model,final int position) {
/** start the Thread to update the Progress*/
new Thread(new Runnable() {

@Override
public void run() {
for(int i = 0;i<=100;i++){
updateProgressInUiThread(model, i,position);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}

void updateProgressInUiThread(Model model,int progress,int position){
updateProgressPartly(progress,position);
}
private void updateProgressPartly(int progress,int position){
int firstVisiblePosition = listview.getFirstVisiblePosition();
int lastVisiblePosition = listview.getLastVisiblePosition();
//在看见范围内才更新进度条
if(position>=firstVisiblePosition && position<=lastVisiblePosition){
//获取指定位置view对象
View view = listview.getChildAt(position - firstVisiblePosition);
if(view.getTag() instanceof ListAdapter.ViewHolder){
//获取指定view对应的ViewHolder
ListAdapter.ViewHolder vh = (ListAdapter.ViewHolder)view.getTag();
vh.pb.setProgress(progress);
}
}
}
}


总结一下ListView局部刷新如何实现:

1.获取到当前可见的第一个条目和最后一个条目的位置

2.判断我们要更新的条目的位置是不是在这个范围内,这么做是为了防止ListView的复用问题

3.通过getChildAt方法获取ListView指定位置的条目View对象

4.通过这个view对象的getTag方法获取ViewHolder对象

5.更新数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: