Java 如何从附加的线性布局(Android)中删除和编辑特定(sqlite db)行

Java 如何从附加的线性布局(Android)中删除和编辑特定(sqlite db)行,java,android,sqlite,android-sqlite,Java,Android,Sqlite,Android Sqlite,我正在Android Studio中制作一个应用程序,我在一些方法上遇到了一些问题,如果代码不好,很抱歉,我是一名CS学生,第一次制作类似的东西 删除有错误的方法 我想创建一个方法来删除一个choosen行并更新数据库表的视图。我的方法,只是删除它,但有错误。我所说的错误是指:每当我单击要删除的行,然后单击“删除”按钮时,应用程序就会重新启动。它实际上从数据库中删除了该行 编辑(找不到进行编辑的方法) 这个编辑方法应该是,类似于我已经拥有的INSERT方法,我认为它可以完全工作,但是它从一个特定

我正在Android Studio中制作一个应用程序,我在一些方法上遇到了一些问题,如果代码不好,很抱歉,我是一名CS学生,第一次制作类似的东西

  • 删除有错误的方法 我想创建一个方法来删除一个choosen行并更新数据库表的视图。我的方法,只是删除它,但有错误。我所说的错误是指:每当我单击要删除的行,然后单击“删除”按钮时,应用程序就会重新启动。它实际上从数据库中删除了该行
  • 编辑(找不到进行编辑的方法) 这个编辑方法应该是,类似于我已经拥有的INSERT方法,我认为它可以完全工作,但是它从一个特定的choosen行获取数据,并打开活动,这样我就可以编辑任何我想要的内容 下面是一些我已经拥有的方法的代码

    //this is my onCreate method, if you need it
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
    
            oAPABD = new AjudanteParaAbrirBD(this);
            oSQLiteDB = oAPABD.getWritableDatabase();
            LinearLayout oLL = (LinearLayout)findViewById(R.id.llsv);
    
    
            Cursor oCursor = oSQLiteDB.query(
                    oAPABD.TABLE_NAME,
                    new String[]{"*"},
                    null,
                    null,
                    null,
                    null,
                    null,
                    null);
    
            boolean bCarryOn = oCursor.moveToFirst();
    
            while (bCarryOn){
                LinearLayout oLL1 = (LinearLayout)getLayoutInflater().inflate(R.layout.lines1,null);
                oLL1.setId(oCursor.getInt(0)*10+8);
    
                TextView oED1 = (TextView) oLL1.findViewById(R.id.ED1);
                TextView oED2 = (TextView) oLL1.findViewById(R.id.ED2);
                TextView oED3 = (TextView) oLL1.findViewById(R.id.ED3);
    
                oED1.setId(oCursor.getInt(0)*10+2);
                oED1.setText(oCursor.getInt(0)+"");
    
                //COL 2 = ITENS
                //DESCRIPTION OF COL2 ITEM LIST MISSING
    
                oED2.setId(oCursor.getInt(0)*10+3);
                oED2.setText(oCursor.getInt(2)+"");
                oED3.setId(oCursor.getInt(0)*10+4); //repetido 10+4;
                oED3.setText(oCursor.getString(3));
    
                oLL.addView(oLL1);
                bCarryOn = oCursor.moveToNext();
            }
    
    
        }
    //INSERT NEW method
        public void novoPedido(View v){
            Intent intento1 = new Intent(Main2Activity.this, activityPedido.class );
            intento1.putExtra("acao","novoPedido");
            intento1.putExtra("count",(getLastID()+1)+"");
            intento1.putExtra("currentTime",currentTime);
    
            startActivityForResult(intento1, iRequest_Code1);
        }
    
    //EDIT method
        public void editPedido(View v){
            Intent intento2 = new Intent(Main2Activity.this, activityPedido.class );
            intento2.putExtra("acao","editarPedido");
    
    //not implemented
    
            startActivityForResult(intento2,iRequest_Code2);
        }
    
    //DELETE method
        public void deletePedido(View v){
    
            //oSQLiteDB.delete(oAPABD.TABLE_NAME, "id = ?" + choosenRowID/10,null);
            oSQLiteDB.execSQL("DELETE FROM " + oAPABD.TABLE_NAME + " WHERE " + oAPABD.COL1 + "=\"" + choosenRowID/10 + "\"");
            oSQLiteDB.close();
    
            LinearLayout oLL1 = (LinearLayout)findViewById(choosenRowID+8);
            ((LinearLayout) oLL1.getParent()).removeView(oLL1);
        }
    
    //decided to go with activityResult like this (only inser method included)
        protected void onActivityResult(int iReqCode, int iResultCode, Intent iResult){
            oAPABD = new AjudanteParaAbrirBD(this);
            oSQLiteDB = oAPABD.getWritableDatabase();
    
            if( (iReqCode == iRequest_Code1) && (iResultCode == RESULT_OK)){    //ADICIONAR
                String id = iResult.getStringExtra("id");
                String listaItens = iResult.getStringExtra("itens");
                String mesa = iResult.getStringExtra("mesa");
                String cliente = iResult.getStringExtra("cliente");
    
                LastID = Integer.parseInt(id);
    
                ContentValues oCV = new ContentValues();
                oCV.put(oAPABD.COL1, id );
                //oCV.put(oAPABD.COL2, listaItens);
                oCV.put(oAPABD.COL3, mesa);
                oCV.put(oAPABD.COL4, cliente);
    
                oSQLiteDB.insert(oAPABD.TABLE_NAME,null,oCV);
    
                //Toast.makeText(this, "Pedido adicionado com sucesso!", Toast.LENGTH_SHORT).show();
            }else if((iReqCode == iRequest_Code2) && (iResultCode == RESULT_OK)){ //EDITAR
    
            }else if((iReqCode == iRequest_Code3) && (iResultCode == RESULT_OK)){ //REMOVER
                //Toast.makeText(this, "Pedido removido com sucesso!", Toast.LENGTH_SHORT).show();
            }else{
                //Toast.makeText(this, "Ups! Algo correu mal...", Toast.LENGTH_SHORT).show();
            }
        }
    
    在我的另一个活动中,我用来插入并返回结果的活动定义如下:

    public class activityPedido extends Activity {
        AjudanteParaAbrirBD oAPABD;
        SQLiteDatabase oSQLiteDB;
        TextView tvAction;
        EditText etInfo1,etInfo2,etInfo3,etCliente,etEmpregado,etPedido;
        ImageButton bSaveNew,bSaveEdit;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_pedido);
    
            Intent iCameFromAct2 = getIntent();
            String action = iCameFromAct2.getStringExtra("acao");
            String currentTime = iCameFromAct2.getStringExtra("currentTime");
            tvAction = (TextView)findViewById(R.id.tAction);
            etInfo1 = (EditText)findViewById(R.id.etInfo1);
            bSaveNew = (ImageButton)findViewById(R.id.bSaveNew);
            bSaveEdit = (ImageButton)findViewById(R.id.bSaveEdit);
            etInfo3 = (EditText)findViewById(R.id.etInfo3);
            etPedido = (EditText)findViewById(R.id.etPedido);
    
            if (action.equals("novoPedido")){
                tvAction.setText("Novo Pedido");
                etInfo3.setText(currentTime);
                bSaveEdit.setVisibility(View.GONE);
    
                etInfo1.setText(iCameFromAct2.getStringExtra("count"));
                etInfo1.setInputType(InputType.TYPE_NULL);
            }
            if (action.equals("editarPedido")){
                tvAction.setText("Editar Pedido");
                bSaveNew.setVisibility(View.GONE);
    
            }
            if (action.equals("removerPedido")){
                tvAction.setText("Remover Pedido");
            }
    
        }//onCreate
    
    /*Using this to make the "same button" with 2 different onClick methods:
    saveNew(save data when clicked ADD NEW in the previous activity)
    and saveEdit(bellow)
    which I haven't yet done anything to it and is the one I really needed help,
    because I can't figure out out to make it)*/
        public void saveNew(View v){
            etInfo1 = (EditText)findViewById(R.id.etInfo1);
            etInfo2 = (EditText)findViewById(R.id.etInfo2);
            etCliente = (EditText)findViewById(R.id.etCliente);
            etPedido = (EditText)findViewById(R.id.etPedido);
    
            Intent iResult = new Intent();
            iResult.putExtra("id",etInfo1.getText().toString());
            iResult.putExtra("mesa",etInfo2.getText().toString());
            iResult.putExtra("cliente",etCliente.getText().toString());
            iResult.putExtra("itens",etPedido.getText().toString());
    
            setResult(RESULT_OK, iResult);
            super.finish();
        }
    
        public void saveEdit(View v){
            etInfo1 = (EditText)findViewById(R.id.etInfo1);
            etInfo2 = (EditText)findViewById(R.id.etInfo2);
            etCliente = (EditText)findViewById(R.id.etCliente);
            etPedido = (EditText)findViewById(R.id.etPedido);
    
    
            super.finish();
        }
        public void goBack(View v){
            finish();
        }
    }
    
    
    在LogCat中添加注释中询问的错误:

    2019-11-20 14:31:10.355 14923-14923/pmd.di.ubi.pedidunchos_2 E/AndroidRuntime: FATAL EXCEPTION: main
        Process: pmd.di.ubi.pedidunchos_2, PID: 14923
        java.lang.IllegalStateException: Could not execute method for android:onClick
            at android.view.View$DeclaredOnClickListener.onClick(View.java:5652)
            at android.view.View.performClick(View.java:6615)
            at android.view.View.performClickInternal(View.java:6592)
            at android.view.View.access$3100(View.java:786)
            at android.view.View$PerformClick.run(View.java:25951)
            at android.os.Handler.handleCallback(Handler.java:873)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:201)
            at android.app.ActivityThread.main(ActivityThread.java:6815)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
         Caused by: java.lang.reflect.InvocationTargetException
            at java.lang.reflect.Method.invoke(Native Method)
            at android.view.View$DeclaredOnClickListener.onClick(View.java:5647)
            at android.view.View.performClick(View.java:6615) 
            at android.view.View.performClickInternal(View.java:6592) 
            at android.view.View.access$3100(View.java:786) 
            at android.view.View$PerformClick.run(View.java:25951) 
            at android.os.Handler.handleCallback(Handler.java:873) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:201) 
            at android.app.ActivityThread.main(ActivityThread.java:6815) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewParent android.widget.LinearLayout.getParent()' on a null object reference
            at pmd.di.ubi.pedidunchos_2.Main2Activity.deletePedido(Main2Activity.java:134)
            at java.lang.reflect.Method.invoke(Native Method) 
            at android.view.View$DeclaredOnClickListener.onClick(View.java:5647) 
            at android.view.View.performClick(View.java:6615) 
            at android.view.View.performClickInternal(View.java:6592) 
            at android.view.View.access$3100(View.java:786) 
            at android.view.View$PerformClick.run(View.java:25951) 
            at android.os.Handler.handleCallback(Handler.java:873) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:201) 
            at android.app.ActivityThread.main(ActivityThread.java:6815) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
    2019-11-20 14:31:10.437 1371-1830/? E/InputDispatcher: channel '55262fd pmd.di.ubi.pedidunchos_2/pmd.di.ubi.pedidunchos_2.Main2Activity (server)' ~ Channel is unrecoverably broken and will be disposed!
    2019-11-20 14:31:10.450 1371-1830/? E/InputDispatcher: channel 'c67c606 pmd.di.ubi.pedidunchos_2/pmd.di.ubi.pedidunchos_2.MainActivity (server)' ~ 
    Channel is unrecoverably broken and will be disposed!
    
    删除有错误的方法我想创建一个方法来删除一个选项 行并更新数据库表的视图。我的方法是 只删除它,但有错误。我所说的错误是指:每当我点击 我要删除的行,然后单击删除按钮,应用程序 它重新启动。它实际上从数据库中删除了该行

    删除工作但随后崩溃的原因是,在使用
    ((LinearLayout)oLL1.getParent())获取计算/数据驱动的LinearLayout的父视图时,尝试获取空指针异常(NPE)。removeView(oLL1)因此该行已被删除

    如果在行
    ((LinearLayout)oLL1.getParent())上放置断点,则移除视图(oLL1)并在调试模式下运行并尝试删除,然后会出现调试窗口,如果您使用该窗口检查变量,您可能会看到oLL1为null,或者如果您拆分
    ((LinearLayout)oLL1.getParent())。removeView(oLL1)编码为两条语句((LinearLayout)oLL1.getParent()的结果为空

    如果(我的解释/假设是onClicked视图是呈现给用户的列表中的一个按钮,而不是单个按钮),因此要删除行的视图(假设线性布局是单击按钮的父级),那么您应该获取并删除单击按钮的父级

    i、 e.使用传递给
    deletePedido
    方法的
    v
    然而,我相信您基本上是在尝试重新发明众所周知的轮子,如果您不尝试管理自己的视图列表,而是使用ListViewRecyclerView来管理数据列表中行的处理,事情将大大简化

    ListView示例 下面的示例允许您插入、编辑和删除表中的行。注意,insert是模拟的,而不是调用另一个活动edit,它除了包含注释外,什么都不做 -简而言之,如果您使用id(假设它是的别名)),则只需将id传递给活动,然后它就可以检索整行

    已尝试使示例与您问题中假设的目标相似

    首先,主要活动布局:-

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <TextView
            android:id="@+id/current"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!">
        </TextView>
    
        <ListView
            android:id="@+id/olv1"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="0dp">
        </ListView>
    
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <Button
                android:id="@+id/insert"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="ADD NEW">
            </Button>
            <Button
                android:id="@+id/delete"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="DELETE SELECTED">
            </Button>
            <Button
                android:id="@+id/edit"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="EDIT SELECTED">
            </Button>
        </LinearLayout>
    </LinearLayout>
    
    • 您应该看到一些代码类似于活动中使用的一些代码。但是,这些方法可以从具有AjudanteParaAbrirBB实例的任何地方调用
    把它们放在一起就是主活动。java:-

    public class AjudanteParaAbrirBD extends SQLiteOpenHelper {
    
        public static final String DBNAME = "ajudante_para_abrir_BD";
        public static final int DBVERSION = 1;
        public static final String TABLE_NAME = "mytable";
        public static final String COL_ID = BaseColumns._ID;
        public static final String COL_ACAO = "acao";
        public static final String COL_COUNT = "count";
        public static final String COl_CURRENTTIME = "currentTime";
        public AjudanteParaAbrirBD(Context context) {
            super(context, DBNAME, null, DBVERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            String crt_table_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
                    "(" +
                    COL_ID + " INTEGER PRIMARY KEY, " +
                    COL_ACAO + " TEXT," +
                    COL_COUNT + " INTEGER, " +
                    COl_CURRENTTIME + " TEXT " +
                    ")";
            db.execSQL(crt_table_sql);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    
        public long insert(String acao, long count, String currentTime) {
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues cv = new ContentValues();
            cv.put(COL_ACAO,acao);
            cv.put(COL_COUNT,count);
            cv.put(COl_CURRENTTIME,currentTime);
            return db.insert(TABLE_NAME,null,cv);
        }
    
        public int update(long id, String acao, long count, String currentTime) {
            int rv = -1;
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues cv = new ContentValues();
            if (acao != null && acao.length() > 0) {
                cv.put(COL_ACAO,acao);
            }
            if (count > -1) {
                cv.put(COL_COUNT,count);
            }
            if (currentTime != null && currentTime.length() > 0) {
                cv.put(COl_CURRENTTIME,currentTime);
            }
            if (cv.size() > 0) {
                rv = db.update(
                        TABLE_NAME,cv,
                        COL_ID + "=?",
                        new String[]{String.valueOf(id)}
                        );
            }
            return rv;
        }
    
        public int delete(long id) {
            SQLiteDatabase db = this.getWritableDatabase();
            return db.delete(
                    TABLE_NAME,
                    COL_ID + "=?",
                    new String[]{String.valueOf(id)}
                    );
        }
    
        public Cursor getAll() {
            SQLiteDatabase db = this.getWritableDatabase();
            return db.query(
                    TABLE_NAME,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null
            );
        }
    
        public String getCurrentSelection(long id) {
            String rv = "Nothing to Select";
            String derivedColumn = "dr";
            SQLiteDatabase db = this.getWritableDatabase();
            Cursor csr = db.query(TABLE_NAME,new String[]{
                    "'ACAO is '||" + COL_ACAO +
                            "||' Count='||" + COL_COUNT +
                            "||' CurrentTime='||" + COl_CURRENTTIME +
                            "||' ID='||" + COL_ID +
                            " AS " + derivedColumn},
                    COL_ID + "=?",new String[]{String.valueOf(id)},
                    null,null,null
            );
            if (csr.moveToFirst()) {
                rv = csr.getString(csr.getColumnIndex(derivedColumn));
            }
            csr.close();
            return rv;
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        ListView dblist;
        TextView currentSelection;
        Button add,edit,delete;
        SimpleCursorAdapter adapter;
        AjudanteParaAbrirBD DBHelper;
        Cursor csr;
        long current_id = -1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            currentSelection = this.findViewById(R.id.current);
            dblist = this.findViewById(R.id.olv1);
            add = this.findViewById(R.id.insert);
            edit = this.findViewById(R.id.edit);
            delete = this.findViewById(R.id.delete);
            DBHelper = new AjudanteParaAbrirBD(this);
            setupButtons();
            manageListView();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            manageListView(); //<<<<<<<<<< refreshes the ListView
        }
    
        private void manageListView() {
            edit.setVisibility(View.INVISIBLE);
            delete.setVisibility(View.INVISIBLE);
            csr = DBHelper.getAll();
            if (csr.getCount() > 0) {
                if (csr.moveToFirst()) {
                    current_id = csr.getLong(csr.getColumnIndex(AjudanteParaAbrirBD.COL_ID));
                    currentSelection.setText(
                            DBHelper.getCurrentSelection(current_id)
                    );
                    csr.moveToPosition(-1);
                }
                edit.setVisibility(View.VISIBLE);
                delete.setVisibility(View.VISIBLE);
            }
            if (adapter == null) {
                adapter = new SimpleCursorAdapter(
                        this,
                        android.R.layout.simple_expandable_list_item_2,
                        csr,
                        new String[]{AjudanteParaAbrirBD.COL_ACAO, AjudanteParaAbrirBD.COl_CURRENTTIME},
                        new int[]{android.R.id.text1, android.R.id.text2},
                        0
                );
                dblist.setAdapter(adapter);
                dblist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        current_id = id;
                        currentSelection.setText(DBHelper.getCurrentSelection(id));
                    }
                });
            } else {
                adapter.swapCursor(csr);
            }
        }
    
        private void setupButtons() {
            add.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handleInsertButtonClicked();
                }
            });
            delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handleDeleteButtonClicked(current_id);
                }
            });
            edit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handleEditButtonClicked(current_id);
                }
            });
        }
    
        private void handleInsertButtonClicked() {
            //...... instantiate intent and startactivity to insert row
            // HOWEVER for demo
            DBHelper.insert("XX",99,"2019-01-01");
            manageListView(); //<<<<<< note only needed because onResume is not called
    
            // onResume would be called when the started activity is finished
        }
    
        private void handleEditButtonClicked(long id) {
            //...... instantiate intent, add intent extra for id, and then startactivity to edit
        }
    
        private void handleDeleteButtonClicked(long id) {
            // No need to start and activity just delete and refresh list
            DBHelper.delete(id);
            manageListView();
        }
    }
    
    public类MainActivity扩展了AppCompatActivity{
    ListView数据库列表;
    文本视图当前选择;
    按钮添加、编辑、删除;
    SimpleCursorAdapter适配器;
    AjudanteParaAbrirBD DBHelper;
    光标csr;
    长电流_id=-1;
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    currentSelection=this.findviewbyd(R.id.current);
    dblist=this.findviewbyd(R.id.olv1);
    add=this.findViewById(R.id.insert);
    edit=this.findviewbyd(R.id.edit);
    delete=this.findviewbyd(R.id.delete);
    DBHelper=新的AjudanteParaAbrirBD(此);
    设置按钮();
    manageListView();
    }
    @凌驾
    受保护的void onResume(){
    super.onResume();
    
    manageListView();//您可以从调试控制台/Logcat添加实际错误,这将有助于识别problem@Andrew使用logcat中的错误编辑文章