Android - 项目被插入数据库两次

时间:2017-10-11 08:16:57

标签: java android mobile

我正在制作一个清单应用程序,每当我删除清单然后创建一个新清单时,数据库会在新清单中创建项目的副本并将其显示在ListView中。

这是我打开并创建标签的类:

  import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.content.SharedPreferences;
import android.widget.TextView;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.lang.reflect.Type;

import static android.widget.AdapterView.*;

/*
Issues-
    After deleting an item, and adding a new item and then editing that item:
    listview has both the version edited after and before.

 */

public class MainActivity extends AppCompatActivity {
    ListView mainScreenListView;
    Button addChecklist;
    ArrayList<String> listOptions = new ArrayList<String>();

    ArrayAdapter<String> mainScreen;
    Button deleteDB;
    DatabaseHandler db;
    List tags;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Removes the action bar at the top of the screen
        getSupportActionBar().hide();
        setContentView(R.layout.activity_main);

        //Sets variables to xml elements
        db = new DatabaseHandler(getApplicationContext());
        mainScreenListView = (ListView) findViewById(R.id.listView);
        addChecklist = (Button) findViewById(R.id.addCheckList);
        deleteDB = (Button) findViewById(R.id.deleteDB);

        //Sets background color of the listview
        mainScreenListView.setBackgroundColor(Color.YELLOW);


        mainScreen = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, listOptions);
        mainScreenListView.setAdapter(mainScreen);

        tags = db.getAllTags();

        if (!tags.isEmpty()) {
            for (Object a : tags) {
                Tag tag = (Tag) a;
                listOptions.add(tag.getTagName());
                mainScreen.notifyDataSetChanged();


            }
        }

        registerForContextMenu(mainScreenListView);


        //Data is given to this method to move to the next activity when the Add Checklist button is pressed
        addChecklist.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(MainActivity.this, WriteList.class);
                startActivityForResult(i, 1);

            }
        });

        /*
            When any item in the ListView is clicked, this method retrieves the name of the item as a string
            and sends this info to the next activity
        */
        mainScreenListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent moveToWriteList = new Intent(MainActivity.this, WriteList.class);
                moveToWriteList.putExtra("title", mainScreenListView.getItemAtPosition(position).toString());
                startActivity(moveToWriteList);
            }
        });

        deleteDB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                db.deleteAll();
                listOptions.clear();

                mainScreen.notifyDataSetChanged();
            }
        });
    }

    /*
        This method retrieves any intent information sent back by the 2nd activity.
        This info is added into the Arraylist which is the displayed in the listview.
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1) {
            if (resultCode == RESULT_OK) {
                String title = data.getStringExtra("title");
                listOptions.add(title);
                tags = db.getAllTags();

                mainScreen.notifyDataSetChanged();


            }
        }

    }


    //Creates the contextual menu that allows the option to edit/delete an item
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);


        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.contextual_menu, menu);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {

        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();

        switch (item.getItemId()) {

            case R.id.edit:
                for (Object a : tags) {
                    Tag tag = (Tag) a;
                    if (tag.getTagName().equals(listOptions.get(info.position))) {
                        showInputBox(listOptions.get(info.position), info.position, tag.getId());
                    }
                }

                break;
            case R.id.delete:

                for (Object a : tags) {
                    Tag tag = (Tag) a;
                    if (tag.getTagName().equals(listOptions.get(info.position))) {

                        db.deleteTag(tag);

                        listOptions.remove(info.position);


                        mainScreen.notifyDataSetChanged();


                        break;
                    }
                }

                break;
        }
        return super.onContextItemSelected(item);
    }

    public void showInputBox(String oldItem, final int index, final long tag_id) {
        final Dialog dialog = new Dialog(MainActivity.this);
        dialog.setTitle("Input Box");
        dialog.setContentView(R.layout.input_box);
        TextView textMessage = (TextView) dialog.findViewById(R.id.txtmessage);
        textMessage.setText("Update Item");
        textMessage.setTextColor(Color.parseColor("#ff2222"));
        final EditText editText = (EditText) dialog.findViewById(R.id.txtinput);
        editText.setText(oldItem);
        Button bt = (Button) dialog.findViewById(R.id.btdone);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String newItem = editText.getText().toString();
                System.out.println("Showinputbox: index is: " + index);
                listOptions.set(index, newItem);
                int newTag_id = (int) tag_id;
                Tag tag = new Tag(newTag_id, newItem);
                db.updateTag(tag);
                mainScreen.notifyDataSetChanged();
                dialog.dismiss();
            }
        });
    }

}

当用户键入清单的标题然后输入项目时,会发生标签创建,但我意识到更好的方法是在MainActivity中创建它:

import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.support.annotation.RequiresPermission;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.List;


import static android.widget.AdapterView.*;

/*
    todo - refers to the the note object that is created whenever the user enters an item into the checklist
    tag- refers to the checklist as a whole ('Shopping', 'Gym', etc)

 */

public class WriteList extends AppCompatActivity {
    ArrayAdapter<String> listAdapter;
    ArrayList<String> listItems = new ArrayList<String>();
    ListView mainList;
    EditText title;
    EditText inputText;
    Button addItem;
    Button titleOK;
    DatabaseHandler db;
    long tag_id;

    List<Todo> list;
    private static final String logTag = "WriteList";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Removes the action bar at the top of the screen
        getSupportActionBar().hide();
        setContentView(R.layout.activity_write_list);


        //Sets variables to xml elements
        db = new DatabaseHandler(getApplicationContext());
        mainList = (ListView) findViewById(R.id.listView);
        title = (EditText) findViewById(R.id.title);
        inputText = (EditText) findViewById(R.id.inputText);
        addItem = (Button) findViewById(R.id.addItem);
        titleOK = (Button) findViewById(R.id.titleOK);

        //Sets background color of the listview
        mainList.setBackgroundColor(Color.parseColor("#ffff9d"));

        //Sets the hint to the EditText elements so the user knows what to type
        inputText.setHint("Enter an item...");
        title.setHint("Enter a title...");

        //Links Adapter to the ListView which shows the ArrayList items
        listAdapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, listItems);
        mainList.setAdapter(listAdapter);

        registerForContextMenu(mainList);

        Intent intent = getIntent();
        Bundle b = intent.getExtras();
        if (b != null) {
            String newTitle = (String) b.get("title");

            title.setText(newTitle);
            tag_id = db.getTagName(newTitle);

            //Retrieves all items connected with the checklist name (newTitle)
            list = db.getAllToDosByTag(newTitle);

            for (Todo todo : list) {
                listItems.add(todo.getNote());
            }

            listAdapter.notifyDataSetChanged();

        }

        //Saves the title into the DB by creating a row in the Tag Table
        titleOK.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String getTitle = title.getText().toString();

                Tag tag = new Tag(getTitle);
                tag_id = db.createTag(tag);


            }
        });

        //db.deleteAll();
        //Saves each todoNote item into the DB and displays in the ListView
        addItem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String input = inputText.getText().toString();
                Log.i(logTag, "Adding item to db...");
                if (null != input && input.length() > 0) {
                    listItems.add(input);

                    Todo todo = new Todo(input, 0);
                    long todo_id = db.createToDo(todo, tag_id);

                    listAdapter.notifyDataSetChanged();
                    inputText.getText().clear();
                }


            }
        });


    }

    //Creates the contextual menu that allows the option to edit/delete an item

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.contextual_menu, menu);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {

        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
            case R.id.edit:
                for (Object a : list) {
                    Todo todo = (Todo) a;
                    if (todo.getNote().equals(listItems.get(info.position))) {
                        showInputBox(listItems.get(info.position), info.position, todo.getId());
                    }
                }

                break;
            case R.id.delete:

                for (Object a : list) {
                    Todo todo = (Todo) a;
                    if (todo.getNote().equals(listItems.get(info.position))) {
                        db.deleteToDo(todo.getId());
                        listItems.remove(info.position);
                        listAdapter.notifyDataSetChanged();
                        break;
                    }
                }

                break;
        }

        return super.onContextItemSelected(item);
    }

    public void onBackPressed() {
        Log.i(logTag, "Back button pressed: going back to previous activity");
        Intent intent = new Intent();
        intent.putExtra("title", title.getText().toString());
        setResult(RESULT_OK, intent);
        finish();
    }

    public void showInputBox(String oldItem, final int index, final long todo_id) {
        final Dialog dialog = new Dialog(WriteList.this);
        dialog.setTitle("Input Box");
        dialog.setContentView(R.layout.input_box);
        TextView textMessage = (TextView) dialog.findViewById(R.id.txtmessage);
        textMessage.setText("Update Item");
        textMessage.setTextColor(Color.parseColor("#ff2222"));
        final EditText editText = (EditText) dialog.findViewById(R.id.txtinput);
        editText.setText(oldItem);
        Button bt = (Button) dialog.findViewById(R.id.btdone);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String newItem = editText.getText().toString();

                listItems.set(index, newItem);
                int newTodoID = (int) todo_id;
                Todo todo = new Todo(newTodoID, newItem, 0);
                db.updateToDo(todo);
                listAdapter.notifyDataSetChanged();
                dialog.dismiss();
            }
        });

        dialog.show();
    }

}

2 个答案:

答案 0 :(得分:0)

我认为您的问题发生是因为删除时,您不会从当前包含所有标记的tags变量中删除已删除的标记。在删除操作上,您还应从此列表中删除已删除的标记。我在switch

上重写了一下你的switch语句
case R.id.delete:

    Tag tagToBeDeleted = null;
    for (Object a : tags) {
        Tag tag = (Tag) a;
        if (tag.getTagName().equals(listOptions.get(info.position))) {
            tagToBeDeleted = tag;
            break;
        }
    }

    if(tagToBeDeleted != null) {
        tags.remove(tagToBeDeleted);
        db.deleteTag(tagToBeDeleted);
        listOptions.remove(info.position);
        mainScreen.notifyDataSetChanged();
    }

    break;

答案 1 :(得分:0)

The error lies in the Todo_Tags table. When you delete an item from a table, you should make sure that you are deleting that same item from any other tables if necessary otherwise it will cause issues when you are re-inserting any items.