问题描述
我正在尝试在 Android Studio 中构建一个待办事项列表应用程序,该应用程序将列表保存为文本文件,然后当您再次打开应用程序时,如果有存储任务的文本文件,它将初始化应用程序中的数组列表使用这些数据。
在我不得不用存储的文件更新 arraylist 之前,它与 arraylist 及其适配器都运行良好。现在它打印但不是打印带有任务的字符串而是打印一个奇怪的内部内容,例如“com.example.todolist.MyData@fe7bcc9”
我环顾四周,并不能确定我是否可以使用同一个适配器两次(更新它?),而且通常任何有关您使用它的经验的信息都会非常有帮助。
主要java代码:
package com.example.todolist;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.EditText;
import android.view.Menu;
import android.view.MenuItem;
import android.util.Log;
import java.io.*;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
public class MainJava extends AppCompatActivity implements AdapterView.OnItemClickListener {
// 1. Some variables and deFinitions
ListView listView;
ArrayList<MyData> arrayList = new ArrayList<>();
MyAdapter adapter,adapter2;
private EditText taskEntered;
private int itemPos;
private final String file = "list.txt";
private String line;
private OutputStreamWriter out;
// 2. Method: The classic ON CREATE
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// locate the widgets: edit text (to get string) and list view (to put string)
taskEntered = (EditText) findViewById(R.id.enterTask);
listView = findViewById(R.id.listView);
// attach listener to list view
listView.setonItemClickListener(this);
taskEntered.setText("");
//hide title and icon in action bar EDIT TO HIDE SAVE AND CLOSE
ActionBar actionBar = getSupportActionBar();
actionBar.setdisplayShowTitleEnabled(false);
actionBar.setdisplayUselogoEnabled(false);
//open output stream
//try {
// out = new OutputStreamWriter(openFileOutput(file,MODE_PRIVATE)); // also try MODE_APPEND
// } catch (IOException e) {}
readFromFile();
}
// 3. Method: ON CREATE OPTIONS MENU
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu,menu);
return true;
}
// 4. Method: ON OPTIONS SELECTED
@Override
public boolean onoptionsItemSelected(MenuItem item) {
int itemID = item.getItemId(); // get id of menu item picked
switch (itemID) {
case R.id.add :
addNewTask(); // prints entered task in list view
return true;
case R.id.delete :
deleteTask();
return true;
case R.id.update :
updateTask();
return true;
case R.id.save :
savetoFile();
return true;
case R.id.close :
savetoFile();
finish();
default: super.onoptionsItemSelected(item);
}
return false;
}
// 5. Method: PRINT NEW TASK in list view and ADD NEW TASK to arrayList
public void addNewTask() {
// get string from the edit text
String taskString = taskEntered.getText().toString();
// create ArrayList values
arrayList.add(new MyData(arrayList.size() +1,taskString));
// TESTING: arrayList.add(new MyData(2," Robert"));
//create custom adapter and connect to ListView
adapter = new MyAdapter(this,arrayList);
listView.setAdapter(adapter);
taskEntered.setText(""); // clear edit text bar after adding item
}
// 5. Method:
public void addNewTask(String string) {
// create ArrayList values
arrayList.add(new MyData(arrayList.size() +1,string));
//create custom adapter and connect to ListView
adapter = new MyAdapter(this,arrayList);
listView.setAdapter(adapter);
}
// 6. Method: Listener,when you click on an item in list view it does this:
// listener is passed into the position of the item that was clicked?
public void onItemClick(AdapterView<?> parent,View v,int position,long id) {
itemPos = position;
// you click on an item in list view
String task = arrayList.get(position).getName(); // get name of task
int numTask = arrayList.get(position).getNum(); // get number of task
// set edit text field to show the item you just clicked
taskEntered.setText(numTask + " " + task);
}
// 7. Method: Delete a task
public void deleteTask() {
// remove the arrayList item in the position that was clicked
arrayList.remove(itemPos);
// loop through items and reassign numbers
for (int i=0; i < arrayList.size(); i++){
arrayList.get(i).setNum(i+1);
}
//create custom adapter and connect to ListView
adapter = new MyAdapter(this,arrayList);
listView.setAdapter(adapter);
taskEntered.setText(""); // clearing edit text widget
}
// 7. Method: Update a task
public void updateTask() {
// get string from the edit text
String taskString = taskEntered.getText().toString();
String updatedString= taskString.substring(2); // so that the task number is not repeated
arrayList.get(itemPos).setName(updatedString);
//create custom adapter and connect to ListView
adapter = new MyAdapter(this,arrayList);
listView.setAdapter(adapter);
taskEntered.setText(""); // clearing edit text widget
}
// 8. Method: Save contents of app to a file
public void savetoFile() {
try {
// writing!
//open output stream try catch
try {
out = new OutputStreamWriter(openFileOutput(file,MODE_PRIVATE)); // also try MODE_APPEND
} catch (IOException e) {}
// loop through items in ArrayList
for (int i=0; i < arrayList.size(); i++){
line = arrayList.get(i).toString(); // grab each line from the to do list
out.write(line + " \n"); // write each line on TEXT file
}
out.close(); // close output stream
} catch (IOException e) {
Log.e("IOTest",e.getMessage());
}
}
// 9. Method: Read from file
public void readFromFile() {
// check if file already exists,if not - finish,if yes - open stream and update app with that
// A) if file doesn't exist leave method
if ( !fileExists(this,"list.txt") ){
return;
}
// B) if file already exists,open a stream,read it,copy it to TodoList app
else {
arrayList.clear();
try {
// reading!
InputStream in = openFileInput(file); // open stream for reading from file
InputStreamReader isr = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(isr);
String str = null;
// loop to read lines from file and print in app
while ((str = reader.readLine()) != null) { // str = each line in the text file OR MAYBE THIS STRING IS THE RAW CODE FROM EACH LINE
addNewTask(str);
//str.toString();
//arrayList.add(new MyData(arrayList.size() +1,str)); // create ArrayList value of the string in the text file
// adapter = new MyAdapter(this,arrayList); // create custom adapter and connect to ListView
//listView.setAdapter(adapter);
}
reader.close(); //close input stream
} catch (IOException e) {
Log.e("IOTest",e.getMessage());
}
}
}
// 10. Method: Check if file exists
public boolean fileExists(Context context,String filename) {
File file = context.getFileStreamPath(filename);
if(file == null || !file.exists()) {
return false;
}
return true;
}
}
Adapter.java 代码:
package com.example.todolist;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
/*
ADAPTER
inflate xml file called row.xml
get references (id's) for widgets in row.xml
add each value on arrayList to its widget
*/
public class MyAdapter extends ArrayAdapter {
private Context context;
private ArrayList<MyData> arrayList;
private TextView listNum,name,contactNum;
// calling 3 arg constructor of parent class and storing values stored in
public MyAdapter(Context context,ArrayList<MyData> arrayList) {
super(context,arrayList);
this.context = context;
this.arrayList = arrayList;
}
// all the action is in this getView method
// calls layout inflater class and gives it the layout of the row
@Override
public View getView(int position,View convertView,ViewGroup parent) {
// call inflater to create a View from an xml layout file
convertView = LayoutInflater.from(context).inflate(R.layout.row,parent,false);
// get references for row widgets
listNum = convertView.findViewById(R.id.listNum); // id´s of widgets in MyAdapter.java
name = convertView.findViewById(R.id.task);
// ArrayList provides values that go along in a row when getView is finished it goes through entire ArrayList and
listNum.setText(" " + arrayList.get(position).getNum());
name.setText(arrayList.get(position).getName());
return convertView;
}
}
我的数据代码:
package com.example.todolist;
public class MyData {
private int listNum;
private String name;
//constructors
public MyData(int num,String name) {
this.listNum = num;
this.name = name;
}
//accessors and mutators
public int getNum() {
return listNum;
}
public void setNum(int num) {
this.listNum = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
解决方法
请在您的 MyData 类中添加此方法。
@Override
public String toString() {
return listNum+","+ name;
}
这是完整的课程,只需复制并粘贴即可
public class MyData {
private int listNum;
private String name;
//constructors
public MyData(int num,String name) {
this.listNum = num;
this.name = name;
}
//accessors and mutators
public int getNum() {
return listNum;
}
public void setNum(int num) {
this.listNum = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return listNum+","+ name;
}
}