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所有代碼,打包上傳了。能夠直接去下載,學習。看看一下後邊的複雜邏輯是如何實現的:

明天或者後天加入更多功能後,再把資源上傳吧,今天就到這裏了~

源碼下載地址

相關文章
相關標籤/搜索