安卓 - 项目入两次到数据库中



我正在制作一个清单应用程序,每当我删除清单然后创建一个新清单时,数据库都会创建新清单中项目的副本并将其显示在 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();
    }
}

我认为会出现您的问题,因为当您删除时,您不会从当前保存所有标签的 tags 变量中删除已删除的标签。在删除操作中,您还应该从此列表中删除已删除的标记。我重写了一点你的开关语句删除

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;

错误在于Todo_Tags表。从表中删除项目时,应确保在必要时从任何其他表中删除相同的项目,否则在重新插入任何项目时会导致问题。

最新更新