Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
#1

ListView+onCreateContextMenu->AlertDialog->dbSQLite - Android

27.01.2015, 10:08. Просмотров 362. Ответов 13
Метки нет (Все метки)

Прошу помощи, т.к. вроде все складно, но не работает, вероятно проблема в получении id для передачи в метод updRec, подскажите пожалуйста кто сможет, несмотря на то что AlertDialog устарел присутствует странное и непреодолимое чувство разобраться и поставить точку в данном вопросе.

OneActivity.java содержит:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.one);
 
        DB.etName = (EditText) findViewById(R.id.editText1);
        // открываем подключение к БД
        db = new DB(this);
        db.open();
 
        // получаем курсор
        cursor = db.getAllData();
        startManagingCursor(cursor);
 
        // формируем столбцы сопоставления
        String[] from = new String[] { DB.COLUMN_TXT };
        int[] to = new int[] {R.id.tvText };
 
        // создааем адаптер и настраиваем список
        scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from,
                to);
        lvData = (ListView) findViewById(R.id.listView1);
        lvData.setAdapter(scAdapter);
 
        // добавляем контекстное меню к списку
        registerForContextMenu(lvData);
        
        
        
    }
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, CM_EDIT_ID, 0, R.string.edit_record);
        menu.add(0, CM_DELETE_ID, 0, R.string.delete_record);
    }
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
            long arg3) {
        
        final EditText textName = (EditText)findViewById(R.id.editText1);
        //cursor.moveToPosition(this.getSelectedItemPosition());
        id_col=cursor.getInt(0);
        textName.setText(cursor.getString(1));
        
        ContentValues val=new ContentValues(2);
        val.put(DB.COLUMN_TXT, textName.getText().toString());
        cursor.requery();
        // TODO Auto-generated method stub
        
    }
    @SuppressWarnings("deprecation")
    public boolean onContextItemSelected(MenuItem item) {
        
        if (item.getItemId() == CM_EDIT_ID) {
            AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item
                    .getMenuInfo();
            cursor.moveToPosition(acmi.position);
            showDialog(IDD_EDIT);
        
        }
 
        if (item.getItemId() == CM_DELETE_ID) {
            // получаем из пункта контекстного меню данные по пункту списка
            AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item
                    .getMenuInfo();
            // извлекаем id записи и удаляем соответствующую запись в БД
            db.delRec(acmi.id);
            // обновляем курсор
            cursor.requery();
            return true;
        }
        return super.onContextItemSelected(item);
    }
 
    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        super.onPrepareDialog(id, dialog);
        
    removeDialog(id);       
    }
    @SuppressLint("InflateParams")
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case IDD_EDIT:
            LayoutInflater inflater = LayoutInflater.from(this);
            View root = inflater.inflate(R.layout.dial, null);
            final EditText textName = (EditText) root.findViewById(R.id.name);
 
            textName.setText(cursor.getString(2));
 
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setView(root);
            builder.setTitle(R.string.title_edit);
            builder.setPositiveButton("Yes",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            
                             String name = textName.getText().toString();
                            
                             
                db.updRec(id, name);//думаю что проблема в получении id, 
                      //но могу ошибаться, "зеленый" еще.
                                        
                        }
                    });
            builder.setNegativeButton("No",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            
                            dialog.cancel();
                             
                        }
                    });
            
            builder.setCancelable(false);
            removeDialog(id);
            return builder.create();
        default:
            return null;
        }
    }
DB.java содержит:

Java
1
2
3
4
5
6
7
8
9
 public void updRec(int id, String name) {
          ContentValues val=new ContentValues();
          name = etName.getText().toString();
            
            val.put(COLUMN_TXT, name);
            
            mDB.update(DB_TABLE, val, "_id = " + id,null);
            
          }
когда после клика на айтеме вылетает алерт диалог с полученным текстом, после изменения кликаем OK и посыпалось:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
01-27 06:58:23.513: E/AndroidRuntime(379): FATAL EXCEPTION: main
01-27 06:58:23.513: E/AndroidRuntime(379): java.lang.NullPointerException
01-27 06:58:23.513: E/AndroidRuntime(379):  at com.crib1.DB.updRec(DB.java:71)
01-27 06:58:23.513: E/AndroidRuntime(379):  at com.crib1.OneActivity$1.onClick(OneActivity.java:148)
01-27 06:58:23.513: E/AndroidRuntime(379):  at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:159)
01-27 06:58:23.513: E/AndroidRuntime(379):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-27 06:58:23.513: E/AndroidRuntime(379):  at android.os.Looper.loop(Looper.java:123)
01-27 06:58:23.513: E/AndroidRuntime(379):  at android.app.ActivityThread.main(ActivityThread.java:3683)
01-27 06:58:23.513: E/AndroidRuntime(379):  at java.lang.reflect.Method.invokeNative(Native Method)
01-27 06:58:23.513: E/AndroidRuntime(379):  at java.lang.reflect.Method.invoke(Method.java:507)
01-27 06:58:23.513: E/AndroidRuntime(379):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-27 06:58:23.513: E/AndroidRuntime(379):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-27 06:58:23.513: E/AndroidRuntime(379):  at dalvik.system.NativeStart.main(Native Method)
помогите пожалуйста поправить?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.01.2015, 10:08     ListView+onCreateContextMenu->AlertDialog->dbSQLite
Посмотрите здесь:

Android AlertDialog Error
Android Не показывается AlertDialog
Потоки и AlertDialog Android
Custom AlertDialog Android
Android AlertDialog появляется дважды
AlertDialog Android
ListView+onCreateContextMenu->AlertDialog Android
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 10:57     ListView+onCreateContextMenu->AlertDialog->dbSQLite #2
Ну, выведите в лог или через Toast, что у вас там в переменных...

Еще странный финт какой-то с присвоениями

Java
1
2
String name = textName.getText().toString();
db.updRec(id, name);
и тут же

Java
1
2
3
public void updRec(int id, String name) {
       ...
          name = etName.getText().toString();
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
27.01.2015, 11:28  [ТС]     ListView+onCreateContextMenu->AlertDialog->dbSQLite #3
Armagedo, рад видеть ...

здесь name закоментил:

Java
1
2
3
public void updRec(int id, String name) {
       ...
        //  name = etName.getText().toString();
Тост вылетает правильный, с отредактированным в алерте текстом:
Java
1
2
3
4
5
6
7
8
9
public void onClick(DialogInterface dialog, int id) {
                            
                             String name = textName.getText().toString();
                        
                             Toast toast = Toast.makeText(getApplicationContext(),
                                        name,
                                        Toast.LENGTH_SHORT);
                                    toast.show();
                             db.updRec(id, name);
а по OK ею просто исчезает этот айтем из списка..., что еще можно глянуть?
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 11:36     ListView+onCreateContextMenu->AlertDialog->dbSQLite #4
А в id чего показывает?

Цитата Сообщение от disx Посмотреть сообщение
а по OK ею просто исчезает этот айтем из списка...
А где вы говорите адаптеру, что данные листвью изменились?

P.S. Чё-то я не могу понять, что нужно, чтобы было
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
27.01.2015, 12:22  [ТС]     ListView+onCreateContextMenu->AlertDialog->dbSQLite #5
Armagedo, не понимаю как посмотреть id тостом, как ни пробую сыпется?

походу нигде, а где и как это сказать?

Java
1
P.S. Чё-то я не могу понять, что нужно, чтобы было
нужно чтобы по кнопке OK Диалога, сохраняло в базе, отредактированый текст(название) айтема в списке?
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 12:29     ListView+onCreateContextMenu->AlertDialog->dbSQLite #6
Ну, там же...

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
if (id==null) 
               Toast.makeText(getApplicationContext(),
                                       "id is NULL",
                                        Toast.LENGTH_SHORT)
                                        .show();
else {
                              Toast.makeText(getApplicationContext(),
                                       "id is " + String.valueOf(id),
                                        Toast.LENGTH_SHORT)
                                        .show();
 
                               db.updRec(id, name);
}
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
27.01.2015, 13:01  [ТС]     ListView+onCreateContextMenu->AlertDialog->dbSQLite #7
Armagedo, первую строчку заменил вот так if (id==0) - ато пишет The operator == is undefined for the argument type(s) int, null

и тост такой "id is -1", и не важно какой айтем выбираешь, по всем одно и то же...
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 13:08     ListView+onCreateContextMenu->AlertDialog->dbSQLite #8
Ну, отлично.
Теперь выхода 2:
1/ Писать кастомный диалог, куда передавать id в конструкторе
2/ Сделать голобальную переменную, куда сохранять значение ключа для записи в onContextItemSelected, ну дальше в диалоге передавать его в updRec
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
27.01.2015, 14:02  [ТС]     ListView+onCreateContextMenu->AlertDialog->dbSQLite #9
Armagedo, пробую вариант 2

но что-то не совсем четко понимаю
куда сохранять значение ключа для записи в onContextItemSelected
т.е. есть интовая переменная id_col, а что есть значение ключа для записи в onContextItemSelected?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public boolean onContextItemSelected(MenuItem item) {
        
        if (item.getItemId() == CM_EDIT_ID) {
            AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item
                    .getMenuInfo();
//          long id_co = acmi.id;
//          id_col=(int)id_co;
            cursor.moveToPosition(acmi.position);
            showDialog(IDD_EDIT);
    
        }
 
        if (item.getItemId() == CM_DELETE_ID) {
            // получаем из пункта контекстного меню данные по пункту списка
            AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item
                    .getMenuInfo();
            // извлекаем id записи и удаляем соответствующую запись в БД
            db.delRec(acmi.id);
            // обновляем курсор
            cursor.requery();
            return true;
        }
        return super.onContextItemSelected(item);
    }
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 14:26     ListView+onCreateContextMenu->AlertDialog->dbSQLite #10
Кто тебе сказал, что id, используемые в Menu и прочих "диалогах" местах соответсвуют значениям ключа (id) из твоего курсора?

Сдвинул указатель в курсоре в нужную позицию
Java
1
 cursor.moveToPosition(acmi.position);
считываешь значение ключевого поля (_id) в этой позиции и сохраняешь его в глобальную переменную.

И дальше работаешь с ним и в updRec и в delRec и в любом другом месте, где обращаешься к таблице.
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
27.01.2015, 14:28  [ТС]     ListView+onCreateContextMenu->AlertDialog->dbSQLite #11
этим получил id:
Java
1
2
long id_co = acmi.id;
id_col=(int)id_co;
передал его так, сюда:

Java
1
db.updRec(id_col, name);
В DB.java updRec так:
Java
1
2
3
4
5
6
7
 public void updRec(int id_col, String name) {
          ContentValues val=new ContentValues();
          val.put(COLUMN_TXT, name);
            
            mDB.update(DB_TABLE, val, "_id = " + id_col,null);
            
          }
теперь тост в OK онклике диалога пишет правильный(полученный в onContextItemSelected) id, а в списке просто исчезает запись ...
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 14:40     ListView+onCreateContextMenu->AlertDialog->dbSQLite #12
Сообщение было отмечено автором темы, экспертом или модератором как ответ
acmi - у тебя экземпляр класса AdapterView.AdapterContextMenuInfo
Смотрим в справке

public long id The row id of the item for which the context menu is being displayed.
Т.е. это id строки в адаптере, для которой вызвано контекстное меню.
Но это значение НЕ обязательно совпадаетс со значением поля id втвоем курсоре.через

Его нужно извлечь из cursor с помощью метода getInt() из той записи, на которую перешёл в курсоре после cursor.moveToPosition(acmi.position);
disx
18 / 18 / 0
Регистрация: 26.02.2014
Сообщений: 479
27.01.2015, 16:14  [ТС]     ListView+onCreateContextMenu->AlertDialog->dbSQLite #13
Armagedo, так
Java
1
 id_col=cursor.getInt(cursor.getColumnIndex(DB.COLUMN_ID));
?


тост показывает вроде правильный id, но после ОК, выбраная запись удаляется (а должна просто изменяться).

Добавлено через 1 час 9 минут
Armagedo, все вопрос закрыт, спасибо за четкие понятия:

1. добавил в диалог onClick cursor.requery();

2. перезагрузил ноут (пока это не сделал не работало ?! )

все заработало, редактируется, сохраняется, и список обновляется.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.01.2015, 18:03     ListView+onCreateContextMenu->AlertDialog->dbSQLite
Еще ссылки по теме:

Android Изменить цвет AlertDialog
Android TextView а AlertDialog
Не работает AlertDialog Android
Android Spinner в AlertDialog
Android AlertDialog и RadioGroup

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
27.01.2015, 18:03     ListView+onCreateContextMenu->AlertDialog->dbSQLite #14
Цитата Сообщение от disx Посмотреть сообщение
Armagedo, все вопрос закрыт, спасибо за четкие понятия:
лишь бы на пользу
Удачи
Yandex
Объявления
27.01.2015, 18:03     ListView+onCreateContextMenu->AlertDialog->dbSQLite
Ответ Создать тему
Опции темы

Текущее время: 09:00. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru