質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.94%

リストビュー項目削除出来ない。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,137

score 26

お世話になっております。Android開発初心者です。

リストビュー項目が削除出来ません。

ビルド後、リストビュー項目を長押しした際、一瞬のみ、項目がリストから消えますが、その後すぐにまた復活して、項目を短く押した際にインテントで遷移する次の項目の詳細画面に処理が進み、長押しした項目自体も削除されておりません。

以下が私のコードです。

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.ListView;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class complist extends Activity {

private /*丙プロジェクトとアプリ名*/SimpleDatabaseHelper_bo1 helper = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.complist_layout);

Integer pcontentid = 0;
String ptime = null;
String pname = null;

String stringid = null;

if (helper == null) {
helper = new SimpleDatabaseHelper_bo1(complist.this);
}

final ArrayList<HashMap<String, String>> datalist1 = new ArrayList();
//       ArrayList datalist1 = new ArrayList();

SQLiteDatabase db1 = helper.getReadableDatabase();

try {

Cursor c3 = db1.rawQuery("SELECT * FROM "/*丙データベーステーブル名*/", null);
boolean next = c3.moveToFirst();
while (next) {
HashMap<String, String> data = new HashMap<>();

pcontentid = c3.getInt(0);
ptime = c3.getString(1);
pname = c3.getString(2);

stringid = String.valueOf(pcontentid);

data.put("ID", stringid);
data.put("Time", ptime);
data.put("Subject",pname);

datalist1.add(data);
next = c3.moveToNext();

}
c3.close();

}catch (Exception e){

TextView error = (TextView)findViewById(R.id.textview_error);
error.setText(getString(R.string.not_yet));

} finally {
db1.close();
}

final ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1,
datalist1);

final ListView listView1 = (ListView) findViewById(R.id.listview1);
listView1.setAdapter(adapter);

listView1.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?
>parent, View view, int position, long id){
/*
HashMap<String, String> map1 = (HashMap<String, String>)listView1.parentAdapter.getItemAtPosition(position);
String value1 = map1.get("ID");
String value2 = map1.get("Time");
String value3 = map1.get("Subject");
try {
String item = (String)map1.get(position);
}catch (Exception e){

}
*/

String item1 = (String)parent.getItemAtPosition(position) ;
datalist1.remove(item1);

adapter.notifyDataSetChanged();
return false;

}

});

listView1.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> av, View view, int position, long id){

String get_id2 = String.valueOf(id + 1);
Intent intent4 = new Intent(complist.this,
user.win.hope.a_box_to_complain.compdisp.class);
intent4.putExtra("did2",get_id2);
startActivity(intent4);

}
});

}

}

項目を削除する前にダイアログも表示させたいのですが、項目自体が削除されないので、次に進めずにとても困っております。

もし、解決方法がお解りでいらっしゃいましたら、ご教授の程、宜しくお願い申し上げます。

追伸

今回のArraylistの項目にデータベースのデータを使用しており、短いクリックで項目の詳細画面にIntentしているのですが、その詳細画面で再び、データベースを開いて各々のデータを表示しております。

ただのlistなら、adapter.removeで削除出来ても、データベースのデータを使う場合は、データベース自体のカラムも削除しなければならないのでしょうか…?


2019/10/10  PM12:40頃

長押しで押されたitemを取得するときに、エラーで型が違うと表示されます。

HashMapを使っているので、keyとvalueの2つが必要なのに、無理やりStringでキャストしておりましたので、そこが問題でしょうか…?

現在、HashMapを使用せずにデータベースから項目のみ取得してリストビューに渡せるかどうか、試しております。

String item = (String)adapter.getItem(position)

のitemは「never used」と警告が出ております。


2019/10/10  PM13:25頃

HashMapを使わないで試してみましたが、うまくいきませんでした。

itemにデータが入ってきてないのは、間違ったキャストをしているからですよね…?

キャストのExceptionがlogcatで出ておりますので、データのキャストをどうすれば良いのか、もし、お解りでいらっしゃいましたら、ご教授の程、お願い申し上げたい次第です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • EveryoneCanEat

    2019/10/10 16:16

    申し訳ありません。インデント出来ませんでした。

    読んで下さるお気持ちだけで、本当に有難いです、本当ありがとうございます。

    キャンセル

  • EveryoneCanEat

    2019/10/10 16:17

    コードを入れ替え致しました。

    キャンセル

  • EveryoneCanEat

    2019/10/10 16:26

    海外のサイトも沢山調べましたが、どう、あがいても、長押ししたリスト項目が復活してしまいます。

    ご多忙でお疲れの中、誠にありがとうございます。

    キャンセル

回答 2

checkベストアンサー

0

Adapter のデータの削除は Adapter.remove であっています.
また, Adapter に特に設定していなければ, Adapter.remove 内で notifyDataSetChanged も呼ばれますので別途の呼び出しは不要です.

一瞬削除されてから再度表示されるのでしたら, 削除処理後に再度データベースを読む処理がどこかで行われている可能性があります.
さらには, 削除処理がDBから「行」(カラムでは無いですよね?)を削除することを意味するのであれば, 当然 adapter からの削除だけでなくDBデータの削除を実装・実行しなければなりません.
ご提示のコードにはDBの行の削除は見当たりませんので, adb で確認せずとも, 行は削除されていないと思います.

長押しで押されたitemを取得するときに、エラーで型が違うと表示されます。
String item = (String)adapter.getItem(position)

この場合 getItem の戻りの型は HashMap<String,String> ではないでしょうか.

HashMap<String,String> item = (HashMap<String,String>)adapter.getItem(position)


とされては如何でしょう.

のitemは「never used」と警告が出ております。

使われていませんので当然です.
すぐに使う予定が無いのでしたら, コメント化しておけば良いかと思います.


String item1 = (String)parent.getItemAtPosition(position) ;
datalist1.remove(item1);
adapter.notifyDataSetChanged();


は単に

adapter.remove(parent.getItemAtPosition(position));


では如何でしょうか.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/11 07:54

    的を得たご教授、誠にありがとうございます。

    ご教授の通り、リストからのデータ削除は、一行のみで済みました。

    ただ、データベースの行の削除が出来ません。

    db.deleteで、レコードの削除を試みておりますが、全く削除されません。

    未だ、解決に至らず、誠に申し訳ありません。

    キャンセル

  • 2019/10/11 08:05

    listView1.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
    @Override
    public boolean onItemLongClick(AdapterView<?
    >parent, View view, int position, long id){

    int dbid = (int)id + 1;

    adapter.remove(parent.getItemAtPosition(position));


    SQLiteDatabase db1 = helper.getWritableDatabase();

    try {
    db1.delete("/*丙テーブル名前*/", "id = " + dbid, null);
    }catch (Exception e){

    } finally {
    db1.close();
    }
    return true;
    }
    });


    こちらが該当コードです。

    キャンセル

  • 2019/10/11 08:14 編集

    本当に、ありがとうございます!!

    削除出来ました!!

    リストからの削除とデータベースのレコードの削除両方、出来ました!!

    deleteのwhereの部分のidを、"id"から"_id"に変更したら、レコードが削除出来ました!!

    長押しでちゃんとデータが消えるようになりました。

    問題がまだ1つ残っておりますが(削除したidの次のデータベースの中身が消えている)これは何とか自分で解決していくしかありません。

    貴重なお時間を頂き、温かいお心遣いを頂きまして、本当にありがとうございました。


    --------------------------------------


    削除したidの次のidのレコードの中身が消えている問題につきまして。

    おそらく、sqliteのオートインクリメントで、削除したidの部分に次のidが詰めて表示されて、中身が消えているように見えたのではないか、と、推測致します。

    あとは、自分で調べて、やっていきます。

    キャンセル

0

「datalist1.remove(position);」も「adapter.notifyDataSetChanged();」の前に必要な気がします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/10 21:49

    試してみましたが、ダメでした。

    一瞬、リストから消えたように見えますが、やはりデータ自体は削除されておりません。

    そのクリックしたidのデータベースのカラムを全て、削除しないと解決しないように思えます。

    windowsは起動したのですが、adbも使えるようになっておりません。

    それにつきましても、原因を探ってみます。

    本当に、貴重なお時間頂きまして、誠にありがとうございます。

    キャンセル

  • 2019/10/10 21:59

    お役に立てず申し訳ないです。

    ちなみに
    adapter.notifyDataSetChanged();
    return false;

    return true;
    にすると短く押した処理が続けて動くことはなくなるはずです。

    キャンセル

  • 2019/10/10 22:11

    それは重要な情報です!!

    何故、long click と、短いclickが、同時に実行されてしまうのが、疑問でした。

    本当、貴重なお時間を頂きまして、助けて頂きまして、誠にありがとうございました。

    どうか、ご無理はなさらず、多方面におきまして、お気をつけ下さいませ。

    本当にありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.94%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る