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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

3929閲覧

[Android]ListViewでonItemLongClickからのDBデータ削除の手順について

yoshiky

総合スコア105

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

1クリップ

投稿2016/04/03 07:33

お世話になっております。
Androidアプリで、
1 ローカルDBからデータ取得
2 ListViewに一覧表示
3 list長押しでActionBarの部分に削除ボタン表示
4 OkでDBから削除、画面再描画で対象データが非表示に、
というアプリを作ろうとしています(Gmailアプリみたいな動作です)。

ここで今、4番の削除後の画面再描画のところで詰まっています。
「ListView 更新」などで調べるとnotifyDataSetChangedがよくヒットするので試してみても、変わりません。
削除後、別画面に遷移して戻ってもう一度Listを構築すれば、削除したデータは一覧に出ませんが、
Gmailアプリみたいに削除したらすぐに一覧から消えるようにするには、どうしたらいいのでしょうか。

稚拙ですが、主だった部分のコードを載せます(メソッドの中身はところどころ省略)。
SQliteはActiveAndroidで操作しています。

Adapterを操作せずに直接DeleteしているからnotifyDataSetChangedが効かないと思うのですが、
ActiveAndroidを使うと下記のような書き方しか思いつかず。。

Java

1# モデル定義 2@Table(name="Members") 3public class Members extends Model{ 4 @Column(name="Name") 5 public String Name; 6}

java

1 2public class MyListItem{ 3 ... 4 public Long getId() { return id; } 5 public String getName() { return name; } 6 ... 7} 8

Java

1public class MySampleList extends AppCompatActivity { 2 3 protected MyListItem myListItem; 4 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 ... 8 final List<MyListItem> lists = new ArrayList<>(); 9 List<Members> members = new Select().from(Members.class).orderBy("id DESC").execute(); 10 for(Members member : members){ 11 myListItem = new MyListItem( 12 member.getId(), 13 member.Name 14 ); 15 lists.add(myListItem); 16 } 17 18 MyBaseAdaptor mba = new MyBaseAdaptor(this, lists); 19 ListView mlist = (ListView) this.findViewById(R.id.mListView); 20 mlist.setAdaptor(mba); 21 22 mlist.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 23 @Override 24 public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) { 25 26 final ActionBar actionBar = getSupportActionBar(); 27 startActionMode(new ActionMode.Callback() { //List長押しでActionMode 28 ... 29 @Override 30 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 31 switch (item.getItemId()){ 32 case R.id.icon_discard: // 削除アイコンを押した場合 33 Long member_id = lists.get(position).getId(); 34 new Delete().from(Members.class).where("id = ?", member_id).execute(); 35 //このあたりで notifyDataSetChanged ? 36 return true; 37 } 38 return false; 39 } 40 } 41 } 42 }); 43 } 44 45 public class MyBaseAdaptor extends BaseAdapter{ 46 private Context context; 47 private List<MyListItem> members; 48 49 public MyBaseAdaptor(Context context, List<MyListItem> members) { 50 this.context = context; 51 this.members = members; 52 } 53 @Override 54 public int getCount() { } 55 56 @Override 57 public Object getItem(int position) {} 58 59 @Override 60 public long getItemId(int position) {} 61 62 @Override 63 public View getView(int position, View convertView, ViewGroup parent) {} 64 } 65 66}

アドバイスいただけると幸いです。「ここ見ろ」などサイトの紹介でも結構です。
よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ListViewにセットされているAdapterからデータを削除してからListView#notifyDataSetChangedを呼ぶ必要があります。

投稿2016/04/03 09:57

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoshiky

2016/04/03 10:52

ご回答ありがとうございます。 よく分かってなく恐縮ですが、Adapterからデータを削除すると、同時にDBからも消えるのか、DBから消す処理が別途必要なのかが、分かりません。。 mlist.setAdaptor(mba); でsetしたmbaからremoveすると思っているのですが、removeメソッドが使えずAndroidStudioに怒られます。。
yona

2016/04/03 11:19

Adapterはデータを保持し、データを元にViewをつくり、ViewGroupに渡す役割しかありません。 DBとは切り離されているため、Adapterからデータを削除してもDBには影響がありません。 ArrayListAdapterを継承した方が楽そうですね。
yoshiky

2016/04/03 14:05

アドバイスありがとうございます。 色々試行錯誤しましたが、最終的に下記のようにしたら動きました()。 1) BaseAdapterを継承したMyBaseAdaptorにremoveItem(position)というメソッド追加。 2) removeItem内でnew Delete.from ~ でActiveAndroid経由でDBレコード削除。かつmembers.remove(potision)でMyBaseAdaptorが保持するデータからも対象を削除。 3) startActoinMode#onActionItemClicked にて、myBaseAdaptor#removeItemを呼び出す。 myBaseAdapter#removeItemを呼び出す際、myBaseAdapter(のインスタンス)を定義した箇所が悪いのか、finalをつけないとエラーになるのが気持ち悪いですが。 >ArrayListAdapterを継承した方が楽そうですね。 こちらはちなみに、ArrayAdapterでしょうか? http://developer.android.com/intl/ja/reference/android/widget/ArrayAdapter.html こういうDBのデータを使う場合はArrayAdapterかBaseAdapterで独自に作る方がいいのか、分からないのですが。。
yona

2016/04/03 14:32

finalをつけないといけないのはmyBaseAdapterがローカル変数なため、押したタイミングでは到達できないインスタンスになるからですよ。 DBの更新処理をAdapterの中に入れてしまうのはあまりお勧めできません。 せっかく分離した、データと見た目を再結合してしまうからです。 誤記でした、ArrayAdapterですね。 今回のように配列からAdapterを作るときは追加、挿入、削除ができるからです。
yoshiky

2016/04/06 03:03

返事が遅くなって申し訳ありませんでした(回答コメントってメール通知ないのかな。。) > finalをつけないといけないのはmyBaseAdapterがローカル変数なため、押したタイミングでは到達できないインスタンスになるからですよ。 なるほどです。 finalだらけになりそうで気持ち悪かったのですが、この場合は仕方ないですかね。。 > DBの更新処理をAdapterの中に入れてしまうのはあまりお勧めできません。 > せっかく分離した、データと見た目を再結合してしまうからです。 なるほど、おっしゃる通りですね。。 Adapter内でDBの処理はしないで、分離してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問