Java 如何从附加的线性布局(Android)中删除和编辑特定(sqlite db)行
我正在Android Studio中制作一个应用程序,我在一些方法上遇到了一些问题,如果代码不好,很抱歉,我是一名CS学生,第一次制作类似的东西Java 如何从附加的线性布局(Android)中删除和编辑特定(sqlite db)行,java,android,sqlite,android-sqlite,Java,Android,Sqlite,Android Sqlite,我正在Android Studio中制作一个应用程序,我在一些方法上遇到了一些问题,如果代码不好,很抱歉,我是一名CS学生,第一次制作类似的东西 删除有错误的方法 我想创建一个方法来删除一个choosen行并更新数据库表的视图。我的方法,只是删除它,但有错误。我所说的错误是指:每当我单击要删除的行,然后单击“删除”按钮时,应用程序就会重新启动。它实际上从数据库中删除了该行 编辑(找不到进行编辑的方法) 这个编辑方法应该是,类似于我已经拥有的INSERT方法,我认为它可以完全工作,但是它从一个特定
//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
。
然而,我相信您基本上是在尝试重新发明众所周知的轮子,如果您不尝试管理自己的视图列表,而是使用ListView或RecyclerView来管理数据列表中行的处理,事情将大大简化
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中的错误编辑文章