前一篇介紹了怎么從手機中讀取圖片文件,放入組件GridView實現網格效果的縮略圖顯示。
今天研究了對GridView中的子項(各張小圖片)進行刪除的操作,參考已有軟件,長按圖片跳出刪除確認框。
GridView長按事件為OnItemLongClickListener(),順便說一下單擊為OnItemClickListener()。
直接上代碼,長按縮略圖中某一張小圖后進行刪除操作(必須帶確認框):
1 gridviewImg.setOnItemLongClickListener(new GridView.OnItemLongClickListener() {//監聽事件 2 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 3 final View v = view; 4 final int p = position; 5 final Bundle savedInstanceState1 = savedInstanceState; 6 new AlertDialog.Builder(MainActivity.this) 7 .setTitle(R.string.long_click) 8 .setMessage(R.string.delete_firm) 9 .setPositiveButton(R.string.Ok, 10 new DialogInterface.OnClickListener() { 11 @Override 12 public void onClick(DialogInterface dialog, int which) { 13 File removeFile = new File(fullPathImg.get(p)); 14 if (removeFile.exists()) { 15 removeFile.delete(); 16 //refresh the gridview 17 //v.setVisibility(v.GONE); 18 adapterImg.notifyDataSetChanged(); 19 finish(); 20 Intent intent = new Intent(MainActivity.this, MainActivity.class); 21 startActivity(intent); 22 23 Intent media = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); 24 Uri contentUri = Uri.fromFile(removeFile); 25 media.setData(contentUri); 26 MainActivity.this.sendBroadcast(media); 27 //gridviewImg.postInvalidate(); 28 //gridviewImg.invalidate(); 29 //onCreate(savedInstanceState1); //failed 30 } 31 } 32 }) 33 .setNegativeButton(R.string.Cancel, 34 new DialogInterface.OnClickListener() { 35 @Override 36 public void onClick(DialogInterface dialog, int which) { 37 ; 38 } 39 } 40 ).show(); 41 return true; 42 } 43 });
雖然這段代碼做的事情很簡單,但有很多細節需要注意:
1、刪除GridView中的圖片時,實質是將SD卡中的真實圖片給刪除了,因此涉及到文件的操作,定位是根據傳入的position參數;
2、確認對話框使用的是DialogInterface,在其點擊響應事件中進行具體實現時不能直接使用GridView長按傳入的參數,如上面的position等,
系統提示是需要final修飾的變量才行。因此需要在開頭重新定義了對應的final變量來滿足要求;
1 final View v = view; 2 final int p = position; 3 final Bundle savedInstanceState1 = savedInstanceState;
3、剛開始進行實現文件刪除功能時,查閱的資料均是下面幾行代碼:
1 File removeFile = new File(fullPathImg.get(p)); 2 if (removeFile.exists()) { 3 removeFile.delete(); 4 }
其中fullPathImg再解釋一下,其為存放圖片完整路徑的ArrayList<String>變量,調用其get()方法(以索引作為參數)即可獲取圖片路徑。
判斷文件的存在性也非常重要,之后便是調用delete()方法進行刪除,但是發現了一個問題:
文件管理器中已經不存在刪除的圖片名稱,但是手機自帶圖片瀏覽器中仍然可以搜索到,電腦中打開手機對應文件夾也存在該文件,只不過是已損壞文件?
這是很不可思議的,接着又是一通查閱、提問,不得不說網上找的大部分文章都沒有提及,只到delete()為止。
后來在Android開源社區的提問得到了准確的回答,在對文件進行刪除或保存后,需要對系統進行更新,是通過廣播的形式來完成。
代碼也挺簡潔:
1 Intent media = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); 2 Uri contentUri = Uri.fromFile(removeFile); 3 media.setData(contentUri); 4 MainActivity.this.sendBroadcast(media);
就是這四行代碼,完成了手機文件信息的同步。當然,也可以是兩行:
1 Intent media = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(removeFile)); 2 MainActivity.this.sendBroadcast(media);
關於Intent和Uri的知識和用途太廣了,還得慢慢學習。
4、玩過相冊的朋友應該都清楚,再刪除一張圖片后,軟件會自動將那個空缺補上(更新GridView,當然手機自帶軟件不會,需要重新打開)。
其實這里面完成了兩件事情,第一,將GridView中的元素更新;第二,將顯示GridView的主界面更新。
代碼如下:
1 adapterImg.notifyDataSetChanged(); 2 finish(); 3 Intent intent = new Intent(MainActivity.this, MainActivity.class); 4 startActivity(intent);
finish()方法的作用是結束當前的Activity,GridView中的元素是由ImageAdapter類決定的,所以只需向后者發送數據改變的通知即可(notifyDataSetChanged())。
代碼中注釋部分是開始時嘗試更新GridView的方法,沒有達到預期的效果。
最后放上一張效果圖。