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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

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

Q&A

解決済

1回答

4195閲覧

AndroidウィジェットでListViewのButtonのイベントを取得したい

gorira1321

総合スコア27

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

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

1グッド

0クリップ

投稿2016/05/19 07:36

編集2016/05/19 07:41

###前提・実現したいこと
ウィジェットにListViewを配置し、1行毎に名前とボタンを表示するサンプルアプリを作っています。(イメージ参照)
ListViewの表示まで出来たのですが、rowのボタンをタップしてもイベントが取得できません。

イメージのBUTTON1とBUTTON2のタップイベントは取得できました。
SuzukiとSatoの横にあるボタンのイベント取得方法を教えて下さい
(将来的にはSuzukiのボタンをタップしたらSuzukiさんとtextviewを変えたい)
イメージ説明

###該当のソースコード

AndroidManifest.xml(抜粋) <receiver android:name=".NewAppWidget"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/> <action android:name="com.android.BUTTON1_CLICKED" /> <action android:name="com.android.BUTTON2_CLICKED" /> <action android:name="com.android.BUTTON3_CLICKED" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/new_app_widget_info"/> </receiver> <service android:name=".SampleWidgetService" android:permission="android.permission.BIND_REMOTEVIEWS"> </service> NewAppWidget.class public class NewAppWidget extends AppWidgetProvider { private static final String TAG = "NewAppWidget"; public static final String btn1Filter = "com.android.BUTTON1_CLICKED"; public static final String btn2Filter = "com.android.BUTTON2_CLICKED"; public static final String btn3Filter = "com.android.BUTTON3_CLICKED"; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); Log.e(TAG, "[onUpdate]"); for (int appWidgetId : appWidgetIds) { Intent remoteViewsFactoryIntent = new Intent(context, SampleWidgetService.class); RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); rv.setRemoteAdapter(R.id.listView, remoteViewsFactoryIntent); // BUTTON1 このイベントは取得できました Intent btn1Intent = new Intent(NewAppWidget.btn1Filter); PendingIntent btn1Pending = PendingIntent.getBroadcast(context, 0, btn1Intent, 0); rv.setOnClickPendingIntent(R.id.btn1_id, btn1Pending); // BTUUON2 このイベントは取得できました Intent btn2Intent = new Intent(NewAppWidget.btn2Filter); PendingIntent btn2Pending = PendingIntent.getBroadcast(context, 0, btn2Intent, 0); rv.setOnClickPendingIntent(R.id.btn2_id, btn2Pending); appWidgetManager.updateAppWidget(appWidgetId, rv); } } @Override public void onReceive(Context ctx, Intent intent) { super.onReceive(ctx, intent); Log.e(TAG,"[action]" + intent.getAction()); } @Override public void onEnabled(Context context) { super.onEnabled(context); Log.e(TAG, "[onEnabled]"); } @Override public void onDisabled(Context context) { super.onDisabled(context); Log.e(TAG, "[onDisabled]"); } } Person.class public class Person { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; } SampleWidgetService.class public class SampleWidgetService extends RemoteViewsService { private static final String TAG = "SampleViewFactory"; private List<Person> persons = new ArrayList<Person>(); @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { Log.e(TAG,"[onGetViewFactory]"); return new SampleWidgetFactory(); } private class SampleWidgetFactory implements RemoteViewsFactory { public void onCreate() { Log.e(TAG, "[onCreate]"); if (persons.size() == 0) { Person p1 = new Person(); p1.setName("Suzuki"); persons.add(p1); Person p2 = new Person(); p2.setName("Sato"); persons.add(p2); } } public void onDataSetChanged() { Log.e(TAG, "[onDataSetChanged]"); } public void onDestroy() { Log.e(TAG, "[onDestroy]"); } public RemoteViews getViewAt(int position) { Log.e(TAG, "[getViewAt]: " + position); RemoteViews rv = null; Person p = persons.get(position); rv = new RemoteViews(getPackageName(), R.layout.listview_row); rv.setTextViewText(R.id.nameText, p.getName()); // LISTBUTTONS // R.id.myButtonのイベントを取りたい。setOnClickPendingIntentしてもイベントがとれない Intent btn3Intent = new Intent(NewAppWidget.btn3Filter); PendingIntent btn3Pending = PendingIntent.getBroadcast(getApplicationContext(), 0, btn3Intent, 0); rv.setOnClickPendingIntent(R.id.myButton, btn3Pending); return rv; } public long getItemId(int position) { Log.e(TAG, "[getItemId]: " + position); return position; } public int getCount() { Log.e(TAG, "[getCount]"); return persons.size(); } public RemoteViews getLoadingView() { Log.e(TAG, "[getLoadingView]"); return null; } public int getViewTypeCount() { Log.e(TAG, "[getViewTypeCount]"); return 1; } public boolean hasStableIds() { Log.e(TAG, "[hasStableIds]"); return true; } } } new_app_widget.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="@dimen/widget_margin"> <Button android:id="@+id/btn1_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button1" /> <Button android:id="@+id/btn2_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button2" /> <ListView android:id="@+id/listView" android:layout_width="fill_parent" android:layout_height="match_parent"/> </LinearLayout> listview_row.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/nameText" android:layout_weight="1" android:textSize="24sp" android:padding="16dp" android:text="名前" android:layout_width="0dp" android:layout_height="wrap_content"/> <Button android:id="@+id/myButton" android:layout_weight="1" android:textSize="24sp" android:text="ボタン" android:layout_width="0dp" android:layout_height="wrap_content"/> </LinearLayout>

###試したこと
以下のページを参考に作成しました

Androidでの簡易なWidget作り方 - Qiita
Y.A.M の 雑記帳: Android AppWidget
AppWidgetのクリックイベントを取得する - Androidプログラマへの道 ~ Moonlight 明日香 ~
###補足情報(言語/FW/ツール等のバージョンなど)
AndroidStudio2.1

KiyoshiMotoki👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

ウィジェットでListViewのボタン押下イベントを取得するにはいくつか処理が足りてません。

・NewAppWidgetクラスのonUpdate()にてRemoteViews.setPendingIntentTemplate()を使う
・SampleWidgetServiceクラスのgetViewAt()にてRemoteViews.setOnClickFillInIntent()を使う
・ListView内のボタン判別にはpositionを使う

詳細はAndroid Developerを見ていただければと
https://developer.android.com/reference/android/widget/RemoteViews.html

ソース修正してみました。
変更箇所(抜粋)をのっけておきます。

AndroidManifest.xml ※BUTTON3_CLICKEDの名前を変えただけ

XML

1 <receiver android:name=".NewAppWidget"> 2 <intent-filter> 3 <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/> 4 <action android:name="com.android.BUTTON1_CLICKED" /> 5 <action android:name="com.android.BUTTON2_CLICKED" /> 6 <action android:name="com.android.LIST_BUTTON_CLICKED" /> 7 </intent-filter> 8 9 <meta-data 10 android:name="android.appwidget.provider" 11 android:resource="@xml/new_app_widget_info"/> 12 </receiver>

NewAppWidget.class

java

1public class NewAppWidget extends AppWidgetProvider { 2 3 private static final String TAG = "NewAppWidget"; 4 5 public static final String btn1Filter = "com.android.BUTTON1_CLICKED"; 6 public static final String btn2Filter = "com.android.BUTTON2_CLICKED"; 7 public static final String listBtnFilter = "com.android.LIST_BUTTON_CLICKED"; 8 9 @Override 10 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 11 super.onUpdate(context, appWidgetManager, appWidgetIds); 12 13 Log.e(TAG, "[onUpdate]"); 14 15 for (int appWidgetId : appWidgetIds) { 16 17 Intent remoteViewsFactoryIntent = new Intent(context, SampleWidgetService.class); 18 RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.new_app_widget); 19 rv.setRemoteAdapter(R.id.listView, remoteViewsFactoryIntent); 20 21 // BUTTON1 このイベントは取得できました 22 Intent btn1Intent = new Intent(NewAppWidget.btn1Filter); 23 PendingIntent btn1Pending = PendingIntent.getBroadcast(context, 0, btn1Intent, 0); 24 rv.setOnClickPendingIntent(R.id.btn1_id, btn1Pending); 25 26 // BTUUON2 このイベントは取得できました 27 Intent btn2Intent = new Intent(NewAppWidget.btn2Filter); 28 PendingIntent btn2Pending = PendingIntent.getBroadcast(context, 0, btn2Intent, 0); 29 rv.setOnClickPendingIntent(R.id.btn2_id, btn2Pending); 30 31 // LIST BUTTON setPendingIntentTemplateを使う 32 Intent listBtnIntent = new Intent(NewAppWidget.listBtnFilter); 33 PendingIntent template = PendingIntent.getBroadcast(context, 0, listBtnIntent, 0); 34 rv.setPendingIntentTemplate(R.id.listView, template); 35 36 appWidgetManager.updateAppWidget(appWidgetId, rv); 37 } 38 } 39 40 @Override 41 public void onReceive(Context ctx, Intent intent) { 42 super.onReceive(ctx, intent); 43 Log.e(TAG,"[action]" + intent.getAction()); 44 45 // 押下したリストの位置を取得し表示 46 int pos = intent.getIntExtra("ListPosition", -1); 47 Log.e(TAG,"List Click pos"+ pos); 48 }

SampleWidgetService.class

java

1public class SampleWidgetService extends RemoteViewsService { 2 3 public RemoteViews getViewAt(int position) { 4 Log.e(TAG, "[getViewAt]: " + position); 5 6 RemoteViews rv = null; 7 8 Person p = persons.get(position); 9 10 rv = new RemoteViews(getPackageName(), R.layout.listview_row); 11 rv.setTextViewText(R.id.nameText, p.getName()); 12 13 // LISTBUTTONS 14 // R.id.myButtonのイベントを取りたい。setOnClickPendingIntentしてもイベントがとれない 15// Intent btn3Intent = new Intent(NewAppWidget.btn3Filter); 16// PendingIntent btn3Pending = PendingIntent.getBroadcast(getApplicationContext(), 0, btn3Intent, 0); 17// rv.setOnClickPendingIntent(R.id.myButton, btn3Pending); 18 19 // LISTのボタンイベントを取るにはsetOnClickPendingIntentではなくsetOnClickFillInIntentを使う 20 Intent listBtnIntent = new Intent(NewAppWidget.listBtnFilter); 21 listBtnIntent.putExtra("ListPosition", position); // リストの押下した位置を持っておく 22 rv.setOnClickFillInIntent(R.id.myButton, listBtnIntent); 23 24 return rv; 25 }

実行結果

Suzuki ボタンを押下した場合
[action]com.android.LIST_BUTTON_CLICKED
List Click pos0

Sato ボタンを押下した場合
[action]com.android.LIST_BUTTON_CLICKED
List Click pos1

こんな感じでどうでしょうか。
あとはonReceiveでif文なりswitch文でposの値を見て押されたボタンに対応する処理を
行っていけばいいかと

ここを利用するのは初めてなので変なところあったらすいませんっ

投稿2016/05/23 12:20

mocomoco

総合スコア54

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

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

gorira1321

2016/05/24 03:17

非常にわかりやすく足りない部分を教えていただきありがとうございました! おかげさまでListviewのbuttonのイベントを取ることが出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問