【发布时间】:2015-03-17 04:58:44
【问题描述】:
我在ListView 中有一个ArrayList<>,所以我需要一个适配器。列表项保存到另一个活动中的文件,并在我的CuteCollection.java 活动运行后从我的 SD 卡加载。我在每个列表项上放了一个OnItemLongClickListener,这样当我单击它时,该项目不仅会从列表(适配器)中删除,还会从 SD 卡中删除。但是,在我的ListView 中显示标题时,我不需要完整的文件名,所以我使用substring 去掉了文件扩展名,效果很好。但随后出现了一个新问题......我的点击监听器不会从我的 SD 卡中删除文件(因为它需要完整的文件名和扩展名才能知道要删除哪个文件)。为了解决这个问题,我使用了文件的标题,并通过StringBuilder,将.txt 扩展名添加回了字符串。但是现在它只会从文件中删除一项,而不会再删除。在我搞砸删除扩展之前,它工作正常。我可以删除任何列表项,方法是长按它并按确定。
有人知道为什么它只工作一次,然后就不再删除了吗?它会从列表中删除任何项目(适配器),但是当我重新运行活动时,旧的项目会再次加载(除了我删除的第一个项目)。这告诉我 SD 卡只删除了一张。我需要能够删除尽可能多的内容。感谢您的帮助。
更新:
我同时记录了singleFile 和sb.toString(),看起来sb.toString() 在第二次长按时也有第一个长按文件名。 singleFile 文件名对于两次点击都有 2 个唯一的文件名,因为列表中当前有 2 个文件。
点击前:
Value of singleFile is: /storage/emulated/0/Documents/CuteWords/Poem_40.txt
Value of singleFile is: /storage/emulated/0/Documents/CuteWords/Poem_89.txt
第一次点击:
Value of sb.toString() is: Poem_89.txt
第二次点击:
Value of sb.toString() is: Poem_89.txt
下面是我的片段:
TextTab.java 这是我的 CuteCollection.java 活动中的单个选项卡。
package org.azurespot.cutecollection;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import org.azurespot.R;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class TextTab extends Fragment {
private ArrayList<PoemListItem> poems = new ArrayList<>();
private ListViewPoemAdapter adapter;
private ListView listView;
String[] allSDCardFiles = null;
StringBuilder text;
PoemListItem wordsFromFile;
StringBuilder sb = new StringBuilder();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.text_tab, container, false);
adapter = new ListViewPoemAdapter(getActivity(), poems);
// Attach the adapter to a ListView
listView = (ListView) v.findViewById(R.id.text_list_view);
listView.setAdapter(adapter);
// read contents of SD card
loadSDCard();
// add the default icon/lines remaining to ArrayList, if less than 24 files on SD card
for (int i = 0; i < (24 - allSDCardFiles.length); i++) {
PoemListItem sampleItem = new PoemListItem(" ", " ");
adapter.add(sampleItem);
adapter.notifyDataSetChanged();
i++;
}
setupListViewListener();
return v;
}
private void loadSDCard(){
// gets directory CuteWords from sd card
File baseDir = Environment.getExternalStorageDirectory();
File cuteWordsDir = new File(baseDir, "/Documents/CuteWords");
// lists all files in CuteWords, loads in Files[] array
File[] files = cuteWordsDir.listFiles();
for (File singleFile : files) {
//Read text from file, put each line into StringBuilder
text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(singleFile));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
// get full file name with ext. and text in file
wordsFromFile = new PoemListItem(singleFile.getName(), text.toString());
// get only name from title (not file extension)
String withExt = wordsFromFile.getTitle();
String justTitle = withExt.substring(0, withExt.length() - 4);
wordsFromFile.setTitle(justTitle);
adapter.add(wordsFromFile);
adapter.notifyDataSetChanged();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// get number of files in CuteWords directory
allSDCardFiles = new String[files.length];
}
// so you can edit any of the list items
private void setupListViewListener() {
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter,
View item, int pos, long id){
}
});
// to delete an item
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> aView, View item,
final int pos, long id) {
new AlertDialog.Builder(getActivity())
.setTitle("Delete")
.setMessage("Delete these cute words?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// delete from adapter
poems.remove(pos);
adapter.notifyDataSetChanged();
// add extension back on file name
sb.append(wordsFromFile.getTitle() + ".txt");
// get file name then delete it
File file = new File(Environment.getExternalStorageDirectory(),
"/Documents/CuteWords/" + sb.toString());
file.delete();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
return true;
}
});
}
}
【问题讨论】:
-
你能在第一次点击和第二次点击时记录文件名并在此处发布
-
哪一个,
wordsFromFile.getTitle或singleFile? -
好的,我都做了,而且监听器上的文件名两次都具有相同的值。但为什么呢?
-
你确定你点击的不同位置的值总是不同的
-
是的,他们是。我尝试将 4 个项目添加到我的列表中并长按将它们全部删除,所有 4 个具有相同的文件值,这是我删除的第一个。更奇怪的是,我删除的越多,该值就会在 1 次单击时重复多个文件。
D/TAG﹕ Value of sb is: Poem_75.txtPoem_75.txtPoem_75.txtPoem_75.txt其实说得通,一定要加上那个文件名,而不是替换它。我可能需要在每次点击开始时删除StringBuilder。
标签: android file-io arraylist android-sdcard onitemlongclicklistener