java - 如何将上下文菜单添加到表格布局?
问题描述
各位程序员好
我正在尝试自己在一个应用程序上记录我所做的所有费用。我在表单中输入我的信息,将其添加到 SQLite 数据库并在 TableLayout 的新活动中显示它。一切都很好,直到那里,或多或少......
这是我展示我的 SQLite 表数据的活动
package com.ascendise.ascBudget;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.Configuration;
import android.database.Cursor;
import android.database.SQLException;
import android.icu.text.DecimalFormat;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CheckBox;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
public class ShowExpensesActivity extends AppCompatActivity {
private TableLayout tblExpenses;
private TextView tvMessage;
private TableOpenHandler toh = new TableOpenHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
Cursor cursor = toh.getCursor(toh.TABLE_NAME_XPNSES);
Boolean isLandscape = this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_expenses);
setTitle(R.string.main_button_expenses);
//region Initialization GUI-Elements
tblExpenses = findViewById(R.id.tblExpenses);
tvMessage = findViewById(R.id.tvMessage);
//endregion
//region fill Table
while(cursor.moveToNext()) {
try {
TableRow row = new TableRow(this);
TextView tvArticle = new TextView(this);
TextView tvCategory = new TextView(this);
TextView tvDescription = new TextView(this);
TextView tvDate = new TextView(this);
CheckBox ckbxNecessity = new CheckBox(this);
TextView tvPrice = new TextView(this);
String sArticle = cursor.getString(toh.COLUMN_ARTICLE);
String sCategory = cursor.getString(toh.COLUMN_CATEGORY);
String sDescription = cursor.getString(toh.COLUMN_DESC);
String sDate = cursor.getString(toh.COLUMN_DATE);
String sPrice = cursor.getString(toh.COLUMN_PRICE);
DecimalFormat df = new DecimalFormat(getString(R.string.input_decimalFormat));
sPrice = df.format(Double.parseDouble(sPrice)).replace(',', '\'');
tvArticle.setText(sArticle);
tvCategory.setText(sCategory);
tvDescription.setText(sDescription);
tvDate.setText(sDate);
ckbxNecessity.setClickable(false);
tvPrice.setText(sPrice);
if (Integer.parseInt(cursor.getString(toh.COLUMN_NT)) == (toh.XPNSES_NECESSITY)) {
ckbxNecessity.setChecked(true);
} else {
ckbxNecessity.setChecked(false);
}
row.addView(tvArticle);
row.addView(tvCategory);
row.addView(tvDescription);
row.addView(tvDate);
row.addView(ckbxNecessity);
row.addView(tvPrice);
row.setClickable(true);
registerForContextMenu(row);
tblExpenses.addView(row);
}catch(SQLException ex) {
ex.printStackTrace();
}catch(Exception ex) {
ex.printStackTrace();
}
}
//endregion
//region change TableLayout @ OrientationChange
if(isLandscape){
tvMessage.setVisibility(View.INVISIBLE);
tvMessage.setHeight(0);
tblExpenses.setColumnCollapsed(2,false);
tblExpenses.setColumnCollapsed(4, false);
}else{
tvMessage.setVisibility(View.VISIBLE);
tblExpenses.setColumnCollapsed(2,true);
tblExpenses.setColumnCollapsed(4, true);
}
//endregion
}
//closes TableHandler when Activity/App gets closed
@Override
public void onDestroy(){
super.onDestroy();
toh.close();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu , menu);
setIntent(getIntent());
}
@Override
public boolean onContextItemSelected(MenuItem item){
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()){
case R.id.delete:
toh.delete(info.id);
break;
case R.id.edit:
break;
default:
break;
}
return true;
}
}
现在我正在尝试向该 TableLayout 添加一个上下文菜单,这样我就可以删除行,但它并没有真正起作用。当我尝试调用 info.id 时收到 NullPointerException。我认为这与我如何为 ContextMenu 注册视图有关。我尝试注册行、TableLayout 等。甚至可以这样做还是只适用于 ListViews?
这是堆栈跟踪:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ascendise.ascBudget, PID: 26615
java.lang.NullPointerException: Attempt to read from field 'long android.widget.AdapterView$AdapterContextMenuInfo.id' on a null object reference
at com.ascendise.ascBudget.ShowExpensesActivity.onContextItemSelected(ShowExpensesActivity.java:133)
at android.app.Activity.onMenuItemSelected(Activity.java:3676)
at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:436)
at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:196)
at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
at com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback.onMenuItemSelected(PhoneWindow.java:3851)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:178)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:908)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:898)
at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:166)
at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1146)
at android.widget.AdapterView.performItemClick(AdapterView.java:321)
at android.widget.AbsListView.performItemClick(AbsListView.java:1206)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3197)
at android.widget.AbsListView$3.run(AbsListView.java:4145)
at android.os.Handler.handleCallback(Handler.java:809)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7555)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
解决方案
我建议从此处发布的答案之一中查看下面的代码,我已经从中列出了最重要的部分:
row.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
String message = "Here is your message"
setIntent(getIntent().putExtra("message_key", message));
registerForContextMenu(v);
openContextMenu(v);
unregisterForContextMenu(v);
return true;
}
});
推荐阅读
- parquet - 为什么对于 Parquet 源的 STRING 和 CHAR 数据类型,每次查询扫描的 Athena 数据不同?
- python - 如何总结时间戳Python
- python - 通过循环通过 train_test_split 训练模型并在不循环的情况下进行训练
- python - Python 英镑 自 公斤
- python - 在pyspark中将字符串价格值转换为double类型
- python-3.x - 来自 Flask 和 API Gateway 的不同响应
- rabbitmq - 过期后未从队列中删除的 RabbitMQ 未确认消息
- android - 找不到 drawable/ic_stat_ic_launcher ,颜色/汽油
- go - 从 Handler Func 返回响应
- ruby-on-rails - 部署在 Heroku 上的 React Rails 项目看起来与 localhost 上的不同