【问题标题】:Using Android back button after delete an item with SwipeDismissListViewTouchListener使用 SwipeDismissListViewTouchListener 删除项目后使用 Android 后退按钮
【发布时间】: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


【解决方案1】:

在今天尝试了一下之后,似乎我用后退按钮解决了我的问题。从第二个活动返回时,我似乎忘记将适配器设置为 onResume 中的 list_view。把代码改成这样后

    @Override
        protected void onResume() {
            super.onResume();
            /* Do I have to do the same here like in onCreate? It does not work yet!*/
            Toast.makeText(this, "onResume is reached!", Toast.LENGTH_SHORT).show();

            if (file.exists()) {
                try {
                    tasks = parser.read(file);
                    if (tasks.isEmpty()) {
                        file.delete();
                        file.createNewFile();
                    }else {

 ==>>new code here      adapter = new TodoListAdapter(tasks, this);
 ==>>new code here      list_view.setAdapter(adapter);

                        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);
                }
            }

        }

一切正常。 我猜如果没有新代码,适配器会将旧 xml 文件中的值放到 list_view 中。

我想我必须在 android 上学到很多东西!

非常感谢所有试图帮助我的人!

无论您身在何处,都祝您有美好的一天

安德烈亚斯

【讨论】:

    猜你喜欢
    • 2020-04-19
    • 2013-08-17
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 2010-10-19
    • 2023-04-03
    • 2013-12-20
    • 1970-01-01
    相关资源
    最近更新 更多