Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之PullToRefresh的Click點擊事件的監聽實現長按刪除Item

Android開發之PullToRefresh的Click點擊事件的監聽實現長按刪除Item

編輯:關於Android編程

本文為原創博客,出自http://blog.csdn.net/minimicall

到今天為止,搜芽的賣家版本應該來說已經基本完成,攻堅克難的一路過來。速度也控制的比較好。

項目過程進度

\


\

\

從任務分配量上來看,基本還是我個人英雄主義。接下來這樣不行。但暫時也沒辦法,師弟還需要一個學習的過程。智質不錯,而且態度端正。相信搜芽買家,他就可以承擔更多的開發任務了。


<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+vdPPwsC0vfjI69X9zOKjrMu1ztLDx7XEUHVsbFRvUmVmcmVzaLXEteO798rCvP6ho8bkyrWjrM7SysfP69f2s6SwtL34yOvJvrP9tcShozwvcD4KPHA+vPvQp7n7zbyho7WxyLvV4rj2ysfO0tf2s/bAtNauuvO1xMHLo6y1q9f2s/bAtLK7yN3S16GjPC9wPgo8aDI+0Ke5+828PC9oMj4KPHA+z8jJz9CnufvNvDwvcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20141029/2014102908560645.png" alt="\">


這個時候,用戶長按某個item,進入刪除選中模式。

\

這個時候ActionBar上的菜單發生了變化,變成了一個全選和刪除。


我們還可以點擊ActionBar全選來選擇所有Item

\

當然,你可以取消全選這個時候,你也可以單機某個Item取消該項。

選中了,然後按刪除菜單,就是那個垃圾桶圖標即可。就會刪除,刪除同步至服務器。

問題出先了。發現點擊無效。。!

問題排查

網上很多方法。

第一個比較有用的是:http://www.tuicool.com/articles/ria6Zf


記錄下自己所犯的錯誤,在寫ListView的點擊事件時OnItemClickListener,onItemClick方法沒有執行,導致ListView條目點擊事件失效,檢查發現百度上有很多不同的答案,但究其本質都是ListView的Item搶占焦點或者Item沒有獲取焦點甚至沒有綁定上OnItemClickListener監聽事件,而我所犯的錯誤是在ListView的Item布局中引入了一個Style,在Style中有一項true,正是這一項導致所有Item都要搶占焦點,所以ListView的點擊事件失效,在我去掉這一項之後ListView確實正常工作了。需要引以為戒的是,在androidl應用開發中,焦點沒有獲取或者其他組件搶占焦點的事情經常發生,我們可以在代碼中,xml布局中,甚至Style中定義時候搶占焦點,在一般情況下,這個設置並不會造成什麼異常,但我需要注意重要的組件在合適的時機必須拿到焦點,否則會產生意想不到的後果,比如我的ListView。一般組件獲取焦點可以使用一下方法:

[java] view plain copy
  1. View.setFocusable( true ),對應xml : android:focusable= "true" .
  2. View.setFocusableInTouchMode( true ),對應xml : android:focusableInTouchMode= "true" .

    注意:這兩個屬性要同時使用。

    兩者的意思是讓組件可以獲得焦點。不過有些區別,前者執行false條件後,在執行true,還是不能獲取焦點。後者執行上述過程,還是能獲取焦點。
    當你加入上述代碼後,在創建activity時,調用對應view的requestFocus(),(requestFocus()需要在setContentView之後執行 )這樣就可以獲得焦點了。當editText失去焦點了,也就不會有軟鍵盤了

    但針對ListView還可以使用 android:descendantFocusability 屬性, 下面我們來看一下 android:descendantFocusability用法簡析

    以下摘自: http://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html

    開發中很常見的一個問題,項目中的listview不僅僅是簡單的文字,常常需要自己定義listview,自己的Adapter去繼承BaseAdapter,在adapter中按照需求進行編寫,問題就出現了,可能會發生點擊每一個item的時候沒有反應,無法獲取的焦點。原因多半是由於在你自己定義的Item中存在諸如ImageButton,Button,CheckBox等子控件(也可以說是Button或者Checkable的子類控件),此時這些子控件會將焦點獲取到,所以常常當點擊item時變化的是子控件,item本身的點擊沒有響應。

    這時候就可以使用descendantFocusability來解決啦,API描述如下:

    android:descendantFocusability

    Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.

    Must be one of the following constant values.

    該屬性是當一個為view獲取焦點時,定義viewGroup和其子控件兩者之間的關系。

    屬性的值有三種:

    beforeDescendants:viewgroup會優先其子類控件而獲取到焦點

    afterDescendants:viewgroup只有當其子類控件不需要獲取焦點時才獲取焦點

    blocksDescendants:viewgroup會覆蓋子類控件而直接獲得焦點

    通常我們用到的是第三種,即在Item布局的根布局加上android:descendantFocusability=”blocksDescendants”的屬性就好了,至此listview點擊的靈異事件告一段落。心得:遇到不會不懂的地方除了網上查詢資料之外,也可以多多去嘗試每種屬性的作用,多閱讀官方文檔(我始終覺得還是讀原文的比翻譯的理解的會更好)

    第二個比較有意的是:

    http://blog.csdn.net/kankankankan2222/article/details/7693190

    如果ListView中的單個Item的view中存在checkbox,button等view,會導致ListView.setOnItemClickListener無效,

    事件會被子View捕獲到,ListView無法捕獲處理該事件.

    解決方法:

    在checkbox、button對應的view處加android:focusable="false"
    android:clickable="false"android:focusableInTouchMode="false"

    其中focusable是關鍵

    從OnClickListener調用getSelectedItemPosition(),Click 和selection 是不相關的,Selection是通過D-pad or trackball 來操作的,Click通常是點擊操作的。

    我犯得錯是自己在getView裡面不小心設置了對Click的監聽導致的。已經被我注釋掉了

    //    private class ClickListner implements OnClickListener {
    //        private int position;
    //
    //        private ClickListner(int position) {
    //            this.position = position;
    //        }
    //
    //        @Override
    //        public void onClick(View v) {
    //        	Log.d(TAG,"xxxxxxxxxxx");
    //            MCloth cloth = mCloths.get(position);
    //            if (!isEnabled(position)) {
    //                return;
    //            }
    //            Context context = v.getContext();
    //            //DetailActivity.launch(context, movie, Referer.NEW_ARRIVIAL);
    //        }
    //    }
    接下來我講一下,如何實現PullToRefresh來實現長按進入刪除選中模式。

    長按進入刪除模式

    首先,在需要初始化View各種監聽的地方,我們開一個函數。如下,相信大家都熟悉,

    	private void setupViews(View rootView) {
    		mListView = (PullToRefreshListView) rootView
    				.findViewById(R.id.cloths_lv);
    		mListView.setMode(PullToRefreshBase.Mode.BOTH);
    		((ViewGroup) mListView.getParent()).addView(mErrorView);
    		mListView.setEmptyView(mErrorView);
    		mClothManageAdapter = new ClothManageAdapter(getActivity(),
    				getImageFetcher());
    		mListView.setAdapter(mClothManageAdapter);
    		((MainActivity) getActivity()).getIndicator().setOnTabSelectedListener(
    				mTabSelectdListener);
    		mProgressBar = (ProgressBar) rootView.findViewById(R.id.pb_progress);
    
    		setListViewRefresh();
    		setLongClickListener();
    	}

    我們把注意力放到setLongClickListener上,這個是我封的一個private方法,如下:

    	private void setLongClickListener() {
    		Log.d(TAG, "setLongClick");
    		mListView.getRefreshableView().setOnItemClickListener(
    				mOnItemClickListener);//單擊事件的監聽
    		mListView.getRefreshableView().setChoiceMode(
    				ListView.CHOICE_MODE_MULTIPLE_MODAL);//選擇模式選為可多選
    		mListView.getRefreshableView().setMultiChoiceModeListener(
    				mMutilChoiceListener);//多選監聽
    
    	}
    好,我們再進一步看單擊時間的監聽

    	private final OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
    
    		@Override
    		public void onItemClick(AdapterView parent, View view, int position,
    				long id) {
    			if (mActionMode == null) {//還沒有按長按的時候,走這裡。
    				Log.d(TAG, "onItemClick,mActionMode is null");
    			} else {//已經有了一次長按之後,進入了選擇模式,走這裡
    				Log.d(TAG, "onItemClick,mActionMode is  not null, select item "
    						+ position + " to select");
    				mListView.getRefreshableView().setItemChecked(position, true);
    
    			}
    		}
    	};
    
    好,我們看我們很關鍵的多選監聽。直接上代碼

    	private final MultiChoiceModeListener mMutilChoiceListener = new MultiChoiceModeListener() {
    		@Override
    		public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    			Log.d(TAG, "onCreateActionMode, mode:" + mode + ",menu:" + menu);
    			mActionMode = mode;
    			getActivity().getMenuInflater().inflate(
    					R.menu.menu_favorite_delete, menu);//加載菜單到ActionBar中
    
    			return true;
    		}
    
    		@Override
    		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    			return false;
    		}
    
    		@Override
    		public void onDestroyActionMode(ActionMode mode) {
    			mActionMode = null;
    		}
    
    		@Override
    		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    			switch (item.getItemId()) {//菜單點擊事件
    			case R.id.menu_delete: // 刪除
    				Log.d(TAG,"delete menu");
    				List deleted = new ArrayList();
    				SparseBooleanArray checked = mListView.getRefreshableView()
    						.getCheckedItemPositions();
    				for (int i = 0; i < checked.size(); i++) {
    					Log.d(TAG, "get from Adapter("+checked.keyAt(i)+","+checked.valueAt(i)+")");
    					if (checked.valueAt(i)) {
    						deleted.add(mClothManageAdapter.getItem(checked
    								.keyAt(i)));
    					}
    				}
    //				for (MCloth cloth : deleted) {
    //					if(cloth != null){
    //						//Log.d(TAG, "deleting the cloth id="+cloth.id+" in remote server now");
    //						 WEBInterface1.DelCloth(cloth.id);
    //					}
    //				}
    				new DeleteClothTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, deleted);
    				mClothManageAdapter.remove(deleted);
    
    				mode.finish();
    				loadData(true);
    				break;
    			case R.id.menu_selectall: // 全選
    				if (mIsSelectAll) {
    					item.setTitle("取消全選");
    					mIsSelectAll = false;
    
    				} else {
    					item.setTitle("全選");
    					mIsSelectAll = true;
    				}
    				for (int i = 0; i < mListView.getRefreshableView().getCount(); i++) {
    					mListView.getRefreshableView().setItemChecked(i,
    							!mIsSelectAll);
    				}
    				break;
    			}
    			return true;
    		}
    
    		@Override
    		public void onItemCheckedStateChanged(ActionMode mode, int position,
    				long id, boolean checked) {
    			setActionModeTitle(mode, mListView.getRefreshableView()
    					.getCheckedItemCount());
    		}
    
    	};
    
    	private void setActionModeTitle(ActionMode mode, int count) {
    		Log.d(TAG, "setActionModeTitile,mode:" + mode + ",count:" + count);
    		mActionMode.setTitle("選中" + count + "個布料");
    	}
    這樣
    核心的代碼就是上面了,實現了長按刪除的,效果不錯吧。不懂的可以聯系我。希望我們的搜芽產品能夠一天天的長成大樹。晚安。有想加入我們團隊的,也可以聯系我。我會給你力所能及的幫助,也期待大家的愉快合作。










  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved