ダイアログのアクションでListviewを更新する方法

1,256 views
Skip to first unread message

oda

unread,
Aug 11, 2011, 10:15:31 AM8/11/11
to 日本Androidの会
始めまして。odaと申します。
最近Android開発・勉強をはじめました。ド素人です。
ネットや本等で調べているのですが、とうとう行き詰ってしまいました。

現在、ListViewをクリックするとダイアログを表示し、ダイアログボタンでListViewを更新するというアプリを
作っておりますが、ダイアログのボタンにてListViewを更新する方法がわかりません。
大変申し訳ございませんが、ご存知の方がおられましたらご教授頂けませんでしょうか。
(尚、Javaも初めてなもので、もっとよいやり方があるのかもしれません。その辺もご教授頂けますと非常に
たすかります)


アプリのイメージてきには、データリストがあり、クリックすると「削除しますか?」のようなメッセージが
表示され、OKボタンでデータを削除するといった感じにあります。

現コードは以下のようになっております。
(一部はしょっています)


public class ShowView extends TabActivity implements
View.OnClickListener{

private ArrayAdapter<IntentItem> listdata;

@Override
public void onCreate(Bundle savedInstanceState) {
ListView lv1 = (ListView)findViewById(R.id.listview1);

listdata = new IntentItemArrayAdapter(this,R.layout.list_item);
listdata.add(new IntentItem("1", "あああああ", "2"));
listdata.add(new IntentItem("2", "いいいいい", "2"));
listdata.add(new IntentItem("3", "ううううう", "1"));
lv1.setAdapter(listdata);

// リスナーを登録する
lv1.setOnItemClickListener(new ApproveClickEvent());


}
class ApproveClickEvent implements OnItemClickListener {

@Override
public void onItemClick(AdapterView<?> adapter, View view, int
position, long id) {

AlertDialog.Builder diag = new
AlertDialog.Builder(ShowDialog.this);

// ダイアログの表示内容
diag.setTitle("削除");
diag.setMessage(listdata.getItem(position).name+"を削除しますか?");

// ダイアログに表示するボタンの設定(第一引数はラベル、第二引数は設定するリスナー)
diag.setPositiveButton("はい", new
DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
//Yesボタンが押された時の処理
Toast.makeText(getApplicationContext(), "Yes Clicked!",
Toast.LENGTH_LONG).show();
//Yesなら削除処理がはいる
}
});
diag.setNegativeButton("いいえ", new
DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
//Noボタンが押された時の処理
Toast.makeText(getApplicationContext(), "No Clicked!",
Toast.LENGTH_LONG).show();
//Noならスルー
}
});

// ダイアログの作成、表示
diag.create();
diag.show();


}

}
private class IntentItem {
private String id;
private String name;
private String sts;

private IntentItem(String id, String name, String sts) {
this.id = id;
this.name = name;
this.sts = sts;
}
}

private class IntentItemArrayAdapter extends
ArrayAdapter<IntentItem> {
private int resourceId;

@Override
public View getView(int position, View convertView, ViewGroup
parent) {
:
:
:
}
@Override
public boolean isEnabled(int position) {
:
:
:
}
}

}

以上です。
何卒よろしくお願いいたします。

三浦智

unread,
Aug 11, 2011, 11:23:54 AM8/11/11
to android-g...@googlegroups.com
三浦です。

ダイアログのYesボタンが押された場合の処理で、
adapterにセットしたデータを更新(削除)して
BaseAdapter#notifyDataSetChangedを
呼んであげればListViewが更新されると思います。


2011年8月11日23:15 oda <o...@lcfield.com>:

> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>
>

Message has been deleted

o...@lcfield.com

unread,
Aug 11, 2011, 10:08:42 PM8/11/11
to android-g...@googlegroups.com
三浦様

早速の返信ありがとうございます。

具体的なやり方を調べ、あの手この手とやっておりますが、
未だにできておりません。

単純なListViewですと
ダイアログのYesボタンで以下のようなコードを入れればできそうなのですが、

ListView list = (ListView)adapter;
String item = (String)list.getItemAtPosition(position);
ArrayAdapter<String> adapter2 = (ArrayAdapter<String>)list.getAdapter();
adapter2.remove(item);


※(当たり前?ですが)上記を入れて動かすと、エラーで落ちます。

ArrayAdapter<IntentItem>だけに、扱いがよくわかっておりません。
#やりたいことは単純なのですが、ここまではまるとは思ってもいませんでした

何か参考になるサイトなど御存知ありましたら教えていただけませんでしょうか。


三浦智

unread,
Aug 11, 2011, 10:40:46 PM8/11/11
to android-g...@googlegroups.com
三浦です。

どんなエラーになっている書かないと他の人も回答に困るのではないでしょうか。
ブレークポイントを設定して、どこでエラーになっているか明確にしてください。


2011年8月12日11:08 <o...@lcfield.com>:

o...@lcfield.com

unread,
Aug 12, 2011, 2:24:40 AM8/12/11
to android-g...@googlegroups.com
odaです。
失礼致しました。


どういうわけか、ブレイクポイントを設定してもスルーされてしまったので、
小生が追加したプログラムとエラーログをお伝えいたします。


ダイアログのボタンクリックイベントにて、以下のコードを追加
(【追加】部です)

@Override
public void onItemClick(AdapterView<?> adapter
, View view
, int position
, long id) {


AlertDialog.Builder diag = new AlertDialog.Builder(ShowDialog.this);

// ダイアログの表示内容
diag.setTitle("削除");
diag.setMessage(listdata.getItem(position).name+"を削除しますか?");

// ダイアログに表示するボタンの設定


diag.setPositiveButton("はい"
, new DialogInterface.OnClickListener(){

public void onClick(DialogInterface dialog, int which) {


//

//処理を【追加】
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


ListView list = (ListView)adapter;
String item = (String)list.getItemAtPosition(position);
ArrayAdapter<String> adapter2 =
(ArrayAdapter<String>)list.getAdapter();
adapter2.remove(item);

//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑


}
});

○エラーログ
DEBUG/AndroidRuntime(211): Shutting down VM
WARN/dalvikvm(211): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
ERROR/AndroidRuntime(211): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(211): java.lang.ClassCastException: com.sample.hogehoge.ShowDialog$IntentItem
ERROR/AndroidRuntime(211): at com.sample.hogehoge.ShowDialog$ApproveClickEvent.onItemClick(ShowDialog.java:232)

ShowDialog.java:232・・・232行目ということだと思うのですが、この行は
String item = (String)list.getItemAtPosition(position);

の部分です。

リストビューにデータを登録する際に、以下のように<IntentItem>を使っている
ためにエラーが出るのはおかしくないかと思いました。

データ登録箇所のソース(onCreate内)
ArrayAdapter<IntentItem>listdata =
new IntentItemArrayAdapter(this
,R.layout.list_item);
listdata.add(new IntentItem("1", "あああああ", "0"));
:

そこで、ダイアログのクリックイベントの追加した箇所を以下のように書き換え
動かして見ると、今度は違うところでエラー

ListView list = (ListView)adapter;
IntentItem item = (IntentItem)list.getItemAtPosition(position);
ArrayAdapter<IntentItem> adapter2 =
(ArrayAdapter<IntentItem>)list.getAdapter();
adapter2.remove(item);


○エラーログ

WARN/dalvikvm(291): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
ERROR/AndroidRuntime(291): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(291): java.lang.NullPointerException
ERROR/AndroidRuntime(291): at com.sample.hogehoge.ShowDialog$IntentItemArrayAdapter.getView(ShowDialog.java:329)


ShowDialog.java:329・・・329行目とは、

getViewの「convertView = inflater.inflate(R.layout.list_sep, null);」
こちらでした。


public View getView(int position, View convertView, ViewGroup parent) {

final IntentItem intentItem = (IntentItem) getItem(position);
LayoutInflater inflater = null ;
if (convertView == null) {
inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resourceId, null);
}
if((!isEnabled(position))){


//↓↓↓エラーがでた行↓↓↓↓↓↓↓↓↓↓↓↓
convertView = inflater.inflate(R.layout.list_sep, null);
//↑↑↑エラーがでた行↑↑↑↑↑↑↑↑↑↑↑↑



TextView sep_text = (TextView)convertView.findViewById(R.id.listView_initial);
sep_text.setText(intentItem.name);
}else{
TextView tv1 = (TextView) convertView.findViewById(R.id.user_id);
tv1.setText(intentItem.id);
TextView tv2 = (TextView) convertView.findViewById(R.id.user_name);
tv2.setText(intentItem.name);
TextView tv3 = (TextView) convertView.findViewById(R.id.user_sts);
tv3.setText(intentItem.sts);
}
return convertView;
}


まだまだ勉強不足なので初歩的(理解不足)だと思うのですが、
完全に行き詰ってしまいました。
何かアドバイス頂ければ幸いです。


以上、よろしくお願いいたします。

三浦智

unread,
Aug 12, 2011, 3:39:11 AM8/12/11
to android-g...@googlegroups.com
三浦です。

329行目の時点で、変数inflaterがnullの場合とそうでない場合があるので、
NullPointerExceptionになっているのだと思います。

convertViewの内容を確認しながらデバッグをしてみてください。


> public View getView(int position, View convertView, ViewGroup parent) {
> final IntentItem intentItem = (IntentItem) getItem(position);
> LayoutInflater inflater = null ;
> if (convertView == null) {
> inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
> convertView = inflater.inflate(resourceId, null);
> }
> if((!isEnabled(position))){
>


2011年8月12日15:24 <o...@lcfield.com>:

o...@lcfield.com

unread,
Aug 12, 2011, 4:35:36 AM8/12/11
to android-g...@googlegroups.com
odaです。

三浦さん、まえたかさん

ありがとうございました。
お二人にご教授頂き、getViewに処理を追加してみました。
convertViewはnullじゃないが、inflaterがnullということがあるということだ
と理解しました。


LayoutInflater inflater = null ;
if (convertView == null) {
inflater = (LayoutInflater)
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resourceId, null);
}

//↓↓↓↓追加した処理↓↓↓↓
if(inflater == null){


inflater = (LayoutInflater)
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resourceId, null);
}

上記の処理をいれると正常に動かせることができました。
本当にありがとうございました。
#これで先にすすめます。


ちなみに、ダイアログのクリックイベントの処理は、以下の通りです。
----------------------------------------------------------------


ListView list = (ListView)adapter;
IntentItem item = (IntentItem)list.getItemAtPosition(position);
ArrayAdapter<IntentItem> adapter2 = (ArrayAdapter<IntentItem>)list.getAdapter();
adapter2.remove(item);

----------------------------------------------------------------
notifyDataSetChanged();は入れてないのですが、リストビューの項目は
消えました。


以上です。


On Fri, 12 Aug 2011 16:39:11 +0900

三浦智

unread,
Aug 12, 2011, 11:45:26 AM8/12/11
to android-g...@googlegroups.com
三浦です

解決されたようですが1点。
追加した処理があれば最初のif文が必要ないように思えます。

ArrayAdapter#getViewの処理は検索するとたくさんでてきますので、
再度調べてみるのをおすすめします。


2011年8月12日17:35 <o...@lcfield.com>:

o...@lcfield.com

unread,
Aug 13, 2011, 8:05:58 PM8/13/11
to android-g...@googlegroups.com
odaです。

三浦さん、追加情報ありがとうございます。

私も腑に落ちないこともありますので、改めて他のサイトも参考に、
勉強したいと思います。

以上、今後ともよろしくお願いします。

On Sat, 13 Aug 2011 00:45:26 +0900

Reply all
Reply to author
Forward
0 new messages