【发布时间】:2017-09-20 05:26:44
【问题描述】:
在我的应用 (API 17) 中使用后退按钮时遇到问题。我的项目中有两个活动: ListView 从 xml 文件中读取项目的主要活动。
第二个活动正在读取相同的 xml 文件,但仅使用已由主要活动检查并保存的项目。
如果我在第二个活动中从 ListView 中删除一个项目,并在滑动时保存 xml 文件后使用应用程序的菜单返回到主活动,则该项目现在未选中。这是因为 xml 文件在刷卡后已更改,并且“isDone”的值从 true 设置为 false。
到目前为止一切顺利!
但如果我使用 Android 后退按钮返回,已删除的项目仍处于选中状态。
什么地方出了错?
我想这与活动的生命周期有关。但我想不通。我是否必须再次阅读 onResume 中更改和保存的 xml 文件?我假设在使用第二个活动的后退按钮后主活动开始时会再次读取它。
而我真正不明白的是: 当我调试代码时,我可以看到在第二个活动中滑动项目并将更改后的 isDone 值保存到 xml 后,xml 文件没有被更改。这对我来说似乎有点奇怪。
任何帮助都可以!
主要活动:
package com.wbapps.wbshoppinglist;
/**
* Created by Andreas on 9/4/2017.
*/
import android.support.v7.app.ActionBar;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MainActivity extends AppCompatActivity {
/*wb, 19Sep,2017: not yet
public static final int REQUEST_ID = 1;
*/
ImageButton imgbtnAddItem;
Button btn_create_shopping_list;
EditText input;
//object for the ListView from activity_main.xml
ListView list_view;
List<Task> tasks;
TodoListAdapter adapter;
XmlParser parser;
File file;
ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
file = new File(Environment.getExternalStorageDirectory(), "tasks.xml");
parser = new XmlParser();
tasks = new ArrayList<Task>();
//file.delete();
if (file.exists()) {
try {
tasks = parser.read(file);
if (tasks.isEmpty()) {
file.delete();
file.createNewFile();
}else {sortList();}
} catch (XmlPullParserException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
try {
file.createNewFile();
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
}
//Initialize the variables
imgbtnAddItem = (ImageButton) findViewById(R.id.add_task_button);
btn_create_shopping_list = (Button) findViewById(R.id.create_shopping_list);
/* findViewById(R.id.list_view).requestFocus(); */
input = (EditText) findViewById(R.id.input_task);
/* id list_view identifies the listview from the activity_main.xmll */
list_view = (ListView) findViewById(R.id.list_view);
registerForContextMenu(list_view);
//tasks = new ArrayList<Task>();
adapter = new TodoListAdapter(tasks, this);
list_view.setAdapter(adapter);
//To swipe away an litem from the list
SwipeDismissListViewTouchListener touchListener =
new SwipeDismissListViewTouchListener(
list_view,
new SwipeDismissListViewTouchListener.DismissCallbacks() {
@Override
public boolean canDismiss(int position) {
return true;
}
@Override
public void onDismiss(ListView listView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
tasks.remove(position);
adapter.notifyDataSetChanged();
}
}
});
list_view.setOnTouchListener(touchListener);
//set the onClickListener for the button
imgbtnAddItem.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (input.getText().length() > 0) {
/* wb, 16Sep2017: look if the new item is already in the list */
Boolean itemfound = false;
for (int i = 0; i<tasks.size(); i++){
if (tasks.get(i).getTaskContent().equalsIgnoreCase(input.getText().toString())){
itemfound = true;
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("This item is already in the list!");
AlertDialog dialog = builder.create();
dialog.show();
break;
}
}
if (itemfound == false){
tasks.add(new Task(input.getText().toString(), false));
adapter.notifyDataSetChanged();
sortList();
input.setText("");
}
}
}
});
btn_create_shopping_list.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//startActivity(new Intent(MainActivity.this, ShoppingListActivity.class));
Boolean selected = false;
Task taskTmp;
for (int i = 0; i < tasks.size(); i++) {
taskTmp = tasks.get(i);
if (taskTmp.isDone()) {
selected = true;
break;
}
}
if (selected) {
Intent intent = new Intent(getApplicationContext(), ShoppingListActivity.class);
startActivity(intent);
/* startActivityForResult(intent, REQUEST_ID); */
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("No items for shopping list selected!");
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
@Override
protected void onPause() {
super.onPause();
//wb, Sep 13, 2017:
//before doing something else - like calling a new activity - write the altered list to
//the data sourc file tasks.xml file
try {
parser.write(tasks, file);
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
protected void onResume() {
super.onResume();
/* Do I have to do the same here like in onCreate? It does not work yet!*/
if (file.exists()) {
try {
tasks = parser.read(file);
if (tasks.isEmpty()) {
file.delete();
file.createNewFile();
}else {sortList();}
} catch (XmlPullParserException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
try {
file.createNewFile();
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.actions, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_clear_all:
clearDonetasks();
this.adapter.notifyDataSetChanged();
break;
case R.id.action_delete_done_tasks:
deleteDonetasks();
this.adapter.notifyDataSetChanged();
break;
case R.id.action_delete_all:
this.tasks.clear();
this.adapter.notifyDataSetChanged();
break;
}
return super.onOptionsItemSelected(item);
}
//wb, 15 Sep, 2017: take out the hook from checkbox
public void clearDonetasks() {
for (int i = 0; i < tasks.size(); i++) {
if (tasks.get(i).isDone()) {
tasks.get(i).setIsDone(false);
}
}
}
public void deleteDonetasks() {
for (int i = 0; i < tasks.size(); i++) {
if (tasks.get(i).isDone()) {
tasks.remove(i);
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = (int) info.id;
switch (item.getItemId()) {
case R.id.context_delete:
this.tasks.remove(position);
this.adapter.notifyDataSetChanged();
return true;
case R.id.context_edit:
createEditDialog(tasks.get(position));
return true;
default:
return super.onContextItemSelected(item);
}
}
public void createEditDialog(final Task task) {
LayoutInflater li = LayoutInflater.from(MainActivity.this);
View dialogView = li.inflate(R.layout.edit_dialog, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder.setView(dialogView);
final EditText inputText = (EditText) dialogView.findViewById(R.id.edit_dialog_input);
inputText.setText(task.getTaskContent());
final TextView dialogMessage = (TextView) dialogView.findViewById(R.id.edit_dialog_message);
alertDialogBuilder
.setCancelable(true)
.setPositiveButton("Save",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
task.setTaskContent(inputText.getText().toString());
sortList();
adapter.notifyDataSetChanged();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
final AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
/* wb, 18Sep2017: sort the tasks list */
public void sortList() {
Collections.sort(tasks, new Comparator<Task>() {
@Override
public int compare(Task content1, Task content2) {
/* return o1.getTaskContent().compareTo(o2.getTaskContent()); */
/* ignore case sentsitivity */
return content1.getTaskContent().compareToIgnoreCase(content2.getTaskContent());
}
});
}
}
第二个活动:
package com.wbapps.wbshoppinglist;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by Andreas on 9/4/2017.
*/
public class ShoppingListActivity extends AppCompatActivity {
/*wb, 19Sep2017: Not yet
public static final String RETVAL_KEY = "RETURN STRING";
*/
ListView shopping_list_view;
List<Task> tasks, shoppingTasks;
TodoListAdapter adapter;
XmlParser parser;
File file;
ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shoppinglist);
file = new File(Environment.getExternalStorageDirectory(), "tasks.xml");
parser = new XmlParser();
tasks = new ArrayList<Task>();
shoppingTasks = new ArrayList<Task>();
if (file.exists()) {
try {
tasks = parser.read(file);
if (tasks.isEmpty()) {
Toast.makeText(this, "No Items in Shopping List", Toast.LENGTH_SHORT).show();
//file.delete();
//file.createNewFile();
} else {
/*
Collections.sort(tasks, new Comparator<Task>() {
@Override
public int compare(Task o1, Task o2) {
return o1.getTaskContent().compareTo(o2.getTaskContent());
}
});
*/
addDonelistitems();
}
} catch (XmlPullParserException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
try {
file.createNewFile();
} catch (IOException ex) {
Toast.makeText(this, "Task File not existing!", Toast.LENGTH_SHORT).show();
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
}
//create an instance for the view of the lauout
shopping_list_view = (ListView) findViewById(R.id.shoppingListView);
registerForContextMenu(shopping_list_view);
adapter = new TodoListAdapter(shoppingTasks, this);
shopping_list_view.setAdapter(adapter);
SwipeDismissListViewTouchListener touchListener =
new SwipeDismissListViewTouchListener(
shopping_list_view,
new SwipeDismissListViewTouchListener.DismissCallbacks() {
@Override
public boolean canDismiss(int position) {
return true;
}
@Override
public void onDismiss(ListView listView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
//wb, 15Sep: With swipe an item uncheck the checkbox for this item in the file for the shopping items
for (int i = 0; i < tasks.size(); i++) {
if (tasks.get(i).getTaskContent() == shoppingTasks.get(position).getTaskContent()) {
tasks.get(i).setIsDone(false);
try {
parser.write(tasks, file);
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
shoppingTasks.remove(position);
adapter.notifyDataSetChanged();
}
}
});
shopping_list_view.setOnTouchListener(touchListener);
}
@Override
public void onBackPressed() {
/* I jaust added a toas there to see if I will reach here */
Toast.makeText(this, "we are in onBackPressed", Toast.LENGTH_SHORT).show();
finish();
}
public void addDonelistitems() {
for (int i = 0; i < tasks.size(); i++) {
if (tasks.get(i).isDone() == true) {
shoppingTasks.add(tasks.get(i));
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = (int) info.id;
switch (item.getItemId()) {
case R.id.context_delete:
this.tasks.remove(position);
this.adapter.notifyDataSetChanged();
return true;
case R.id.context_edit:
createEditDialog(tasks.get(position));
return true;
default:
return super.onContextItemSelected(item);
}
}
public void createEditDialog(final Task task) {
LayoutInflater li = LayoutInflater.from(ShoppingListActivity.this);
View dialogView = li.inflate(R.layout.edit_dialog, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ShoppingListActivity.this);
alertDialogBuilder.setView(dialogView);
final EditText inputText = (EditText) dialogView.findViewById(R.id.edit_dialog_input);
inputText.setText(task.getTaskContent());
final TextView dialogMessage = (TextView) dialogView.findViewById(R.id.edit_dialog_message);
alertDialogBuilder
.setCancelable(true)
.setPositiveButton("Save",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
task.setTaskContent(inputText.getText().toString());
adapter.notifyDataSetChanged();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
final AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
}
【问题讨论】:
-
禁用后退按钮,否则您需要为android后退按钮实现onactivityresult,并首先在该通知适配器中。
-
你试过 super.onBackPressed() 而不是 finish() ;
-
对不起 Sai,但我不明白如何处理这个 super.onBackPressed。只是代替完成()。在我的方法“public void onBackPressed()”中?那应该是什么结果?在 xml 文件中为 isDone 值获取正确的值有什么帮助?
标签: android android-lifecycle back-button