java - 如何将上下文菜单添加到表格布局?

标签 java android android-tablelayout android-contextmenu

各位程序员大家好

我正在尝试使用一个应用程序来记录我所做的所有费用。 我正在表单中输入我的信息,将其添加到 SQLite 数据库并在 TableLayout 中的新 Activity 中显示它。一切正常,直到那里,或多或少......

这是我显示 SQLite 表数据的 Activity

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 的 View 有关。我尝试注册行、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)

最佳答案

我建议查看以下来自 answer posted here 之一的代码,我已经把最重要的部分从中拿出来了:

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;
    }
});


关于java - 如何将上下文菜单添加到表格布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60441126/

相关文章:

java - 使用日历添加或删除日期

java - 在 Eclipse Workbench 中查看任何 Java 项目时,Eclipse Workbench 如何显示 JRE 系统库?

Android:向 tableRow 添加并排 View

android - Android ImageView 中的透明 GIF

android - 我如何在不使用 SafeArea 的情况下检查设备是否有缺口?

Android:表格 View 中的垂直线以编程方式

android - 表格布局调整。是否可以?

java - 如何强制浏览器下载文件?

java - 将类转换为其实现的接口(interface)

android - 使用 Android.mk 构建时缺少资源文件