创建上下文菜单时,在android的长pressing项目 [英] Creating a contextual menu when long pressing item in android

查看:154
本文介绍了创建上下文菜单时,在android的长pressing项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个清单,它允许用户添加新的项目到列表中,我试图让用户当他们想要删除的项目。所以我创建使用自带我们,当一个上下文菜单用户长期presses列表中的一个项目。现在,它认识到长期preSS但没有任何反应,所以上下文菜单中不会出现。

I am creating a checklist and it allows the user to add new items to the list, I am trying to allow the user to delete an item when they want to. So I am creating a contextual menu using this that comes us when the user long-presses an item in the list. Right now, it recognizes the long-press but nothing happens, so the contextual menu doesn't appear.

下面是我的活动页面:(ViewTask.java)

Here is my activity page: (ViewTask.java)

package com.example.androidhive;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ViewTask extends Activity {
    protected TaskerDbHelper db;
    List<Task> list;
    MyAdapter adapt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_task);
        db = new TaskerDbHelper(this);
        list = db.getAllTasks();
        adapt = new MyAdapter(this, R.layout.list_inner_view, list);
        ListView listTask = (ListView) findViewById(R.id.listView1);
        listTask.setAdapter(adapt);
    }

    public void addTaskNow(View v) {
        EditText t = (EditText) findViewById(R.id.editText1);
        String s = t.getText().toString();
        if (s.equalsIgnoreCase("")) {
            Toast.makeText(this, "Enter a goal please!",
                    Toast.LENGTH_LONG);
        } else {
            Task task = new Task(s, 0);
            db.addTask(task);
            Log.d("tasker", "data added");
            t.setText("");
            adapt.add(task);
            adapt.notifyDataSetChanged();
        }

    }
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.layout.cmenu, menu);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
            case R.id.Delete_Task:
                db.deleteTask(info.id);
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.layout.activity_view_task, menu);
        return true;
    }

    private class MyAdapter extends ArrayAdapter<Task> {

        Context context;
        List<Task> taskList = new ArrayList<Task>();
        int layoutResourceId;

        public MyAdapter(Context context, int layoutResourceId,
                List<Task> objects) {
            super(context, layoutResourceId, objects);
            this.layoutResourceId = layoutResourceId;
            this.taskList = objects;
            this.context = context;
        }

        /**
         * This method will DEFINe what the view inside the list view will
         * finally look like Here we are going to code that the checkbox state
         * is the status of task and check box text is the task name
         */
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            CheckBox chk = null;
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.list_inner_view,
                        parent, false);
                chk = (CheckBox) convertView.findViewById(R.id.chkStatus);
                convertView.setTag(chk);

                chk.setOnClickListener(new View.OnClickListener() {

                    public void onClick(View v) {
                        CheckBox cb = (CheckBox) v;
                        Task changeTask = (Task) cb.getTag();
                        changeTask.setStatus(cb.isChecked() == true ? 1 : 0);
                        db.updateTask(changeTask);
                        if(cb.isChecked())
                          {
                           Toast.makeText(
                             getApplicationContext(),
                             "Goal Accomplished!", Toast.LENGTH_LONG).show();
                          }
                    }

                });
            } else {
                chk = (CheckBox) convertView.getTag();
            }
            Task current = taskList.get(position);
            chk.setText(current.getTaskName());
            chk.setChecked(current.getStatus() == 1 ? true : false);
            chk.setTag(current);
            Log.d("listener", String.valueOf(current.getId()));
            return convertView;
        }

    }

}

下面是关联到这个页面的XML页面:(activity_view_task.xml)

Here is the xml page associated to this page:(activity_view_task.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DE8126"
    android:orientation="vertical" >

    <!-- Header Start -->
    <LinearLayout
        android:id="@+id/header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@layout/header_gradient"
        android:orientation="vertical"
        android:paddingBottom="5dip"
        android:paddingTop="5dip" >

                <!-- Logo Start -->
        <ImageView
            android:id="@+id/logoButton"
            android:layout_width="match_parent"
            android:layout_height="132dp"
            android:src="@drawable/logo" />
                <!-- Logo Ends -->
    </LinearLayout>
             <!-- Header End -->

             <!-- Goals Title Start -->
      <LinearLayout 
          android:id="@+id/goalsTitle"
          android:layout_width="match_parent"
          android:layout_height="80dp"
          android:paddingTop="5dip"
          android:paddingBottom="5dip">

          <TextView 
              android:id="@+id/gTitle"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:text="My Goals"
              android:textSize="50sp"
              android:textScaleX="1.5"
              android:textStyle="bold"
              android:gravity="center"/>
      </LinearLayout>
            <!-- Goals Title End -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ViewTask" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:ems="10" >

        <requestFocus />
    </EditText>


    <Button
       android:id="@+id/button1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentRight="true"
       android:layout_alignParentTop="true"
       android:layout_marginRight="14dp"
       android:text="@string/Save"
       android:onClick="addTaskNow"/>


    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/button1" >
    </ListView>
</RelativeLayout>
</LinearLayout>

这里是菜单本身:(cmenu.xml)

And here is the menu itself: (cmenu.xml)

<?xml version="1.0" encoding="UTF-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/Edit_Task"></item>
    <item android:id="@+id/Delete_Task"></item>
</menu>

感谢你的答复,现在我不能获得该项目实际上被删除。

Thanks you for the responses, now I cannot get the item to actually be deleted.

这是我的数据库帮助页面:(TaskerDbHelper.java)

here is my database helper page:(TaskerDbHelper.java)

package com.example.androidhive;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;


public class TaskerDbHelper extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "taskerManager";

    // tasks table name
    private static final String TABLE_TASKS = "tasks";

    // tasks Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_TASKNAME = "taskName";
    private static final String KEY_STATUS = "status";

    public TaskerDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_TASKS + " ( "
                + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + KEY_TASKNAME+ " TEXT, "
                + KEY_STATUS + " INTEGER)";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
         // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_TASKS);
        // Create tables again
        onCreate(db);
    }

    public void addTask(Task task) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_TASKNAME, task.getTaskName()); // task name
         // status of task- can be 0 for not done and 1 for done
        values.put(KEY_STATUS, task.getStatus());

        // Inserting Row
        db.insert(TABLE_TASKS, null, values);
        db.close(); // Closing database connection
    }
    public boolean deleteTask(long task) 
    {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete(TABLE_TASKS, KEY_TASKNAME + "=" + task, null) > 0;
    }

    public List<Task> getAllTasks() {
        List<Task> taskList = new ArrayList<Task>();
        // Select All Query
        String selectQuery = "SELECT  * FROM " + TABLE_TASKS;
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Task task = new Task();
                task.setId(cursor.getInt(0));
                task.setTaskName(cursor.getString(1));
                task.setStatus(cursor.getInt(2));
                // Adding contact to list
                taskList.add(task);
            } while (cursor.moveToNext());
        }
        // return task list
        return taskList;
    }

    public void updateTask(Task task) {
        // updating row
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(KEY_TASKNAME, task.getTaskName());
        values.put(KEY_STATUS, task.getStatus());
        db.update(TABLE_TASKS, values, KEY_ID + " = ?",new String[] {String.valueOf(task.getId())});
        db.close();
    }

}

以上该文件包含我的DeleteTask活动()。

That file above contains my deleteTask().

推荐答案

我不明白registerForContextMenu()的任何地方。这是必要的列表实际上知道它有一个文本菜单

I don't see registerForContextMenu() anywhere. This is necessary for the list to actually know that it has a contextmenu.

  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_view_task);
      db = new TaskerDbHelper(this);
      list = db.getAllTasks();
      adapt = new MyAdapter(this, R.layout.list_inner_view, list);
      ListView listTask = (ListView) findViewById(R.id.listView1);
      listTask.setAdapter(adapt);
      registerForContextMenu(listTask); // <-- Register!
  }

此外,你应该把一个字符串值,菜单中的XML文件中。显然,这是更好地参考您的字符串的xml文件的实际字符串。

In addition you should put a String value in your menu xml file. Obviously it is better to refer to your string xml file for the actual string.

<item
    android:id="@+id/Edit_Task"
    android:title="Edit">
</item>
<item
    android:id="@+id/Delete_Task"
    android:title="Delete">
</item>

关于删除任务:
若要从SQL数据库你的任务,你需要某种标识符。据我所知,你只有一个任务名称和状态的整数。如果允许任务具有相同的名称,这不能被用作唯一标识符。也许你应该添加到您的任务类。然后,您可以用它来查找并删除特定任务在数据库中。 (你info.id不会工作,因为它仅仅是视图的标识符)可以在适配器使用info.position检索在任务列表的任务的位置,或更具体地,当前列表。

Concerning the delete task: To delete your task from the sql database you need some kind of identifier. As far as I can tell, you have only a task name and a status integer. If you allow tasks to have the same name, this cannot be used as an unique identifier. Perhaps you should add that to your Task class. You can then use this to find and remove the specific task in your database. (Your info.id will not work, because it is merely the identifier of the view) You can use info.position to retrieve the position of the Task in taskList, or more specifically, the current list in the adapter.

    case R.id.Delete_Task:
         Task task = list.get(info.position);                
         if (db.deleteTask(task.getUniqueIdentifier())) { // <-- Determine the unique id
             list.Remove(info.position);
             listTask.invalidate();
             return true;
         }
         return false;

我不知道无效()是否会做的伎俩。但给它一试。你也可以给适配器的新名单,并调用notifyDataSetChanged()作为你的addTaskNow()做的。

I'm not sure whether invalidate() will do the trick. But give it a try. You could also give the adapter the new list and call notifyDataSetChanged() as you do for the addTaskNow().

这篇关于创建上下文菜单时,在android的长pressing项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆