我在ArrayList<>
中有一个ListView
,所以我需要一个适配器。列表项目将保存到另一个活动的文件中,并在我的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;
}
});
}
}
答案 0 :(得分:0)
最后弄明白了。它只删除一次因为我没有在每次删除后再次刷新写入文件。因此,在我的情况下,我需要在删除文件后立即运行loadSDCard()
方法。我在AlertDialog
之后的file.delete()
框的末尾添加了方法调用。所以它与最终的pos
变量无关。基本上,您写入删除文件,因此您有一个新列表。否则它会认为您的旧列表已到位并且不会更改位置。重写实际上重新创建了列表。
// 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 ArrayList first
poems.remove(pos);
adapter.notifyDataSetChanged();
// get file name then delete it
File file = new File(Environment.getExternalStorageDirectory(),
"/Documents/CuteWords/" + wordsFromFile.getTitle());
file.delete();
// after each item delete, must refresh load so can delete again
loadSDCard();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
dialog.cancel();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
return true;
}
});