Android 结合实际项目学会ListView局部刷新和相关知识《一》

转载本专栏博客,请注明出处:道龙的博客html

最近在公司参与的项目中有一个界面须要作局部UI更新处理,把其化烦为简为Demoi形式写在这里。咱们仍是运行该Demo,知道ListView局部刷新的使用场景:(受时间限制,本篇就介绍这么多功能,下一篇会在这个Demo中加入更多的功能)java


能够看到,点击每一个Item的时候,ListView上的CheckBox会选中或取消选中。这里面用到知识点就是ListView的局部刷新,局部的意思就是脱离ListView,在每一个Item位置进行更新UI操做。那么就从头一步步的学习如何实现这个功能:eclipse

1、实现基本功能。

模拟数据源,把最基本的功能先跑起来:ide

布局、自定义样式、自定义选择器都很简单,过多的代码就再也不写了,文章只贴出业务逻辑重要的代码(文章最后会给出源代码可自行下载;因为实习公司使用的IDE仍是Eclipse,本篇是基于eclipse写的)
布局

主活动中代码也很常规简单:学习

public class MainActivity extends Activity {

    private ListView mListView;
    List<ItemBean> mDatas = new ArrayList<ItemBean>();
	private MyAdapter adapter;


	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.listview);
        initData();
        adapter = new MyAdapter();
        mListView.setAdapter(adapter);
    }

	/**模拟数据*/
    private void initData() {
    	ItemBean mItemBean = null;
    	for (int i = 0; i < 40; i++) {
    		//集合添加20个对象
    		mItemBean = new ItemBean();
    		mItemBean.setText("学习ListView局部刷新"+i);
    		mItemBean.setResIcon(R.drawable.directory_icon);
    		mDatas.add(mItemBean);
		}
	}
    
    private class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			if(mDatas != null){
				return mDatas.size();
			}
			return 0;
		}

		@Override
		public Object getItem(int position) {
			if(mDatas != null){
				return mDatas.get(position);
			}
			return null;
		}

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

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			if(convertView == null){
				holder = new ViewHolder();
				convertView = View.inflate(getApplicationContext(), R.layout.file_item, null);
				holder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
				holder.tvText = (TextView) convertView.findViewById(R.id.tv_name);
				holder.ivOption = (ImageView) convertView.findViewById(R.id.iv_option);
				convertView.setTag(holder);
			}else{
				holder = (ViewHolder) convertView.getTag();
			}
			
			//拿到数据
			ItemBean mItem = (ItemBean) getItem(position);
			//设置数据
			holder.ivIcon.setImageResource(mItem.getResIcon());
			holder.tvText.setText(mItem.getText());
			return convertView;
		}
		
		class ViewHolder{
			ImageView ivIcon;
			TextView tvText;
			ImageView ivOption;
		}
    	
    }
}
此时运行程序:


接下来就对上边的常规代码作一下修饰了:测试

2、进入编辑模式

咱们长按item的时候,但愿整个布局改变一下进入编辑模式,让复选框图标展现,对应位置上ImageView图标消失,就能够这么写。spa

首先写一个方法,来控制布局的改变:.net

private boolean isEdit;
    /**开始编辑模式*/
	private void startEditMode() {
		isEdit = true;//标志位置为true
		//进入编辑模式,要改变IListView的界面
		adapter.notifyDataSetChanged();
	}
	
	/**结束编辑模式*/
	private void stopEditMode(){
		isEdit = false;
	}

而后加入长按item的点击事件:code

        mListView.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id) {
				startEditMode();
				return true;//返回true后,mListView.setOnItemClickListener就不会再去调用
			}
		});

3、ListView中CheckBox选中取消,实现局部的刷新

定义一个item局部刷新的方法:

/**定义一个item局部刷新的方法*/
		public void updateItemView(View ItemView){
			CheckBox itemCb = (CheckBox) ItemView.findViewById(R.id.cb_checkbox);
			if(itemCb.isChecked()){
				//点击item,从选中状态调到未选中状态
				itemCb.setChecked(false);
			}else{
				itemCb.setChecked(true);
			}
		}

在item的点击事件的时候,调用这个方法,便可完成checkbox的选中与取消:

mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if(isEdit){
					//若是是编辑模式
					adapter.updateItemView(view);
				}else{
					//不是编辑模式,点击item作其余逻辑处理
					Toast.makeText(getApplicationContext(), "当前item"+position, 0).show();
				}
			}
		});
目前咱们仅仅是实现了界面的刷新,可是cb的选中与取消要记录起来,点击了哪一个item也要记录起来,这样才能作接下来的操做,选中cb执行什么样的任务,所以咱们须要使用javabean,记录每次点击选中cb的操做:

具体的局部刷新修改后的方法以下:

/**定义一个item局部刷新的方法*///position,为了拿到当前item的对象,记录状态
		public void updateItemView(View ItemView,int position){
			position = position - mListView.getHeaderViewsCount();
			ItemBean itemBean = mDatas.get(position);
			CheckBox itemCb = (CheckBox) ItemView.findViewById(R.id.cb_checkbox);
			if(itemCb.isChecked()){
				//点击item,从选中状态调到未选中状态
				itemCb.setChecked(false);
				//记录当前item未选中状态
				itemBean.setChecked(false);
			}else{
				itemCb.setChecked(true);
				//记录当前item选中状态
				itemBean.setChecked(true);
			}
			
			//经过集合把选中的item的对象itemBean记录起来
			List<ItemBean> selectDatas = new ArrayList<ItemBean>();
			for (ItemBean info : mDatas) {
				if(info.isChecked()){//当前的item是选中的
					selectDatas.add(info);
				}
			}
			
			/**测试局部刷新*/
			for (ItemBean itemBean2 : selectDatas) {
				System.out.println(itemBean2.getText());
			}
		}
而后该方法确定要被调用咯,在哪里调用?点击item的时候嘛,那就在注册item的点击事件稍做修改就能够了:

mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if(isEdit){
					//若是是编辑模式
					adapter.updateItemView(view,position);
				}else{
					//不是编辑模式,点击item作其余逻辑处理
					Toast.makeText(getApplicationContext(), "当前item"+position, 0).show();
				}
			}
		});

可是这个时候仍是有许多问题的,好比第二页的数据会复用第一页的数据,那就先解决这个bug。

只须要在getView里面,对item上边的cb从新复制就能够了。

                              if(isEdit){//是编辑模式
				// Ui层面进入编辑模式
				holder.checkBox.setVisibility(View.VISIBLE);
				holder.ivOption.setVisibility(View.GONE);
				
				/**解决复用问题,对每个item上的cb都从新赋值*/
				if (mItem.isChecked()) {
					holder.checkBox.setChecked(true);
				} else {
					holder.checkBox.setChecked(false);
				}
				
			}else{
				holder.checkBox.setVisibility(View.GONE);
				holder.ivOption.setVisibility(View.VISIBLE);
			}

4、根据是否编辑状态,修改顶部标题栏文本信息

接下来的逻辑稍微复杂,就是经过当前状态,来修改顶端的标题栏状态。

首先,长按进入编辑模式的时候,要显示当前选中多少个。须要一个标志位mSelectedCount。进入编辑模式,显示标题:

//修改标题栏
		mTextView.setText(String.format("已选择了%d个", mSelectedCount));

那对于标志的增长减小要放到,updateItemView里面

if(itemCb.isChecked()){
				//点击item,从选中状态调到未选中状态
				itemCb.setChecked(false);
				//记录当前item未选中状态
				itemBean.setChecked(false);
				
				mSelectedCount --;
			}else{
				itemCb.setChecked(true);
				//记录当前item选中状态
				itemBean.setChecked(true);
				
				mSelectedCount ++;
			}
因为逻辑稍微复杂,也不是要介绍局部刷新这个技术点的范围了,就再也不继续往下写了。我把Demo所有代码,打包上传了。能够直接去下载,学习。看看一下后边的复杂逻辑是如何实现的:

明天或者后天加入更多功能后,再把资源上传吧,今天就到这里了~

源码下载地址

相关文章
相关标签/搜索