首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android ListView 長按獲取項目數據並彈出上下文菜單撥打電話/發短信

     編輯:程式設計綜合問答

問題分析

原代碼在 `onItemLongClick` 中正確獲取了姓名和電話,但變量 `dh` 定義為局部變量,導致 `onContextItemSelected` 中引用的是類成員數組 `dh[]` 而非選中的具體號碼。解決方案是**將選中的電話號碼存入類成員變量**,供上下文菜單回調使用。

修正後的核心代碼

public class M1 extends Activity {
    private ListView lv1;
    private String[] names = {"張三", "李四", "王五", "趙六"};
    private String[] phones = {"626746", "624882", "620874", "130533"};
    private String selectedPhone = ""; // 新增:存儲長按選中的電話

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.m1);
        lv1 = findViewById(R.id.lv1);

        List<Map<String, Object>> data = new ArrayList<>();
        for (int i = 0; i < names.length; i++) {
            Map<String, Object> item = new HashMap<>();
            item.put("pic", pics[i]);
            item.put("name", names[i]);
            item.put("phone", phones[i]);
            data.add(item);
        }

        SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.moban,
                new String[]{"pic", "name", "phone"},
                new int[]{R.id.iv1, R.id.tv1, R.id.tv2});
        lv1.setAdapter(adapter);

        lv1.setOnItemLongClickListener((parent, view, position, id) -> {
            Map<String, Object> item = (Map<String, Object>)
                    lv1.getItemAtPosition(position);
            selectedPhone = (String) item.get("phone"); // 關鍵:保存到成員變量
            String name = (String) item.get("name");
            Toast.makeText(this, "長按: " + name + " - " + selectedPhone, Toast.LENGTH_SHORT).show();
            return false; // 返回 false 允許上下文菜單彈出
        });

        registerForContextMenu(lv1);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        getMenuInflater().inflate(R.menu.m1, menu);
        menu.setHeaderTitle("請選擇操作");
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (selectedPhone.isEmpty()) return super.onContextItemSelected(item);

        Intent intent = new Intent();
        switch (item.getItemId()) {
            case R.id.dh: // 撥打電話
                intent.setAction(Intent.ACTION_CALL);
                intent.setData(Uri.parse("tel:" + selectedPhone));
                // 需權限: 
                startActivity(intent);
                break;
            case R.id.dx: // 發送短信
                intent.setAction(Intent.ACTION_SENDTO);
                intent.setData(Uri.parse("smsto:" + selectedPhone));
                intent.putExtra("sms_body", "");
                startActivity(intent);
                break;
        }
        return super.onContextItemSelected(item);
    }
}

關鍵修正點

  1. 成員變量 `selectedPhone`:在 `onItemLongClick` 中賦值,`onContextItemSelected` 中讀取,避免引用錯誤數組。
  2. 返回 `false`:`OnItemLongClickListener` 返回 `false` 才會繼續觸發 `onCreateContextMenu`,返回 `true` 會攔截事件導致菜單不彈出。
  3. 權限聲明:`AndroidManifest.xml` 中需添加 ``,Android 6.0+ 還需運行時請求權限。
  4. 簡化數據構建:使用鏈式調用、鑽石操作符 `<>`、Lambda 表達式(API 24+)提升可讀性。

進階建議:遷移至 RecyclerView

ListView 已過時,新項目建議使用 `RecyclerView` + `ItemTouchHelper` 或 `OnLongClickListener` 實現更靈活的交互。數據綁定邏輯同理:長按時在 ViewHolder 或 Adapter 回調中獲取對應位置數據,存入 Activity/Fragment 成員變量或通過接口回調傳遞給菜單處理邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved