Android開発におけるイベント発生時の画像の再描画について
解決済
回答 3
投稿
- 評価
- クリップ 0
- VIEW 3,924

退会済みユーザー
前提・実現したいこと
使っている開発ツール:
AndroidStudio
現在教本を参考にしながら簡単なサンプルアプリの改修を
行っているのですが、思ったように動かせません。
やりたいこととしては、
画面上に、押せるなにかしらの画像を配置し、その画像を
タップした際にダイアログメッセージの表示とともに
画像が別の画像に挿げ変わる、という実装をしたいです。
発生している問題・エラーメッセージ
エラーメッセージ
該当のソースコード
//ボタンとダイアログ
public class ButtonEx extends Activity implements View.OnClickListener{
private final static int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private final static String TAG_MESSAGE = "0";
private final static String TAG_YESNO = "1";
private final static String TAG_TEXT = "2";
private final static String TAG_IMAGE = "3";
private static boolean imgOk = true;
private Context context;
private int waitperiod = 1000;
//アクティビティ起動時に呼ばれる
@Override
public void onCreate(Bundle bundle){
System.out.println("onCreate実行");
super.onCreate(bundle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//レイアウトの生成
LinearLayout layout = new LinearLayout(this);
layout.setBackgroundColor(Color.WHITE);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
//ボタンの生成
layout.addView(makeButton("メッセージダイアログの表示", TAG_MESSAGE));
layout.addView(makeButton("Yes/Noダイアログの表示", TAG_YESNO));
layout.addView(makeButton("テキスト入力ダイアログの表示", TAG_TEXT));
if(imgOk == true){
System.out.println("目をつぶる");
layout.addView(makeButton(res2bmp(this, R.drawable.sample), TAG_IMAGE));
}else{
System.out.println("目をひらく");
layout.addView(makeButton(res2bmp(this, R.drawable.sample2), TAG_IMAGE));
}
}
//疑似再描画用メソッド
public void restart(Context cnt, int period){
// intent 設定で自分自身のクラスを設定
Intent buttonEx = new Intent(cnt, ButtonEx.class);
// PendingIntent , ID=0
PendingIntent pendingIntent = PendingIntent.getActivity(cnt, 0, buttonEx, PendingIntent.FLAG_CANCEL_CURRENT);
// AlarmManager のインスタンス生成
AlarmManager alarmManager = (AlarmManager)cnt.getSystemService(Context.ALARM_SERVICE);
// 1回のアラームを現在の時間からperiod秒後に実行させる
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + period, pendingIntent);
// アプリ終了
finish();
}
//ボタンの生成
private Button makeButton(String text, String tag){
Button button = new Button(this);
button.setText(text);
button.setTag(tag);
button.setOnClickListener(this);
button.setLayoutParams(new LinearLayout.LayoutParams(WC, WC));
button.invalidate();
return button;
}
//イメージボタンの生成
private ImageButton makeButton(Bitmap bmp,String tag){
ImageButton button = new ImageButton(this);
button.setTag(tag);
button.setOnClickListener(this);
button.setImageBitmap(bmp);
button.setLayoutParams(new LinearLayout.LayoutParams(WC, WC));
button.invalidate();
return button;
}
//リソース→ビットマップ
public Bitmap res2bmp(Context context, int resID){
return BitmapFactory.decodeResource(context.getResources(), resID);
}
//ボタン押下時に呼ばれる
public void onClick(View view){
String tag = (String)view.getTag();
if(TAG_MESSAGE.equals(tag)){
MessageDialog.show(this, "メッセージダイアログ", "ボタンを押した");
}else if(TAG_YESNO.equals(tag)){
YesNoDialog.show(this, "Yes/Noダイアログ", "Yes/Noを選択");
}else if(TAG_TEXT.equals((tag))){
TextDialog.show(this, "テキスト入力ダイアログ", "テキストを入力");
}else if(TAG_IMAGE.equals(tag)){
if(imgOk){
imgOk = false;
}else{
imgOk = true;
}
MessageDialog.show(this, "", "イメージボタンを押した");
//画像の再描画のやり方がわからないので、
// アプリごと再起動するための設定
context = getApplicationContext();
waitperiod = 1;
//restart(context, waitperiod);
}
}
//イメージダイアログの定義
public static class MessageDialog extends DialogFragment{
//ダイアログの表示
public static void show(Activity activity, String title, String text){
MessageDialog f = new MessageDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("text", text);
f.setArguments(args);
f.show(activity.getFragmentManager(), "messageDialog");
}
//ダイアログの生成
@Override
public Dialog onCreateDialog(Bundle bundle){
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
ad.setTitle(getArguments().getString("title"));
ad.setMessage(getArguments().getString("text"));
ad.setPositiveButton("OK", null);
return ad.create();
}
}
//Yes/Noダイアログの定義
public static class YesNoDialog extends DialogFragment{
//ダイアログの表示
public static void show(Activity activity, String title, String text){
YesNoDialog f = new YesNoDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("text", text);
f.setArguments(args);
f.show(activity.getFragmentManager(), "yesNoDialog");
}
//Yes/Noダイアログの生成
@Override
public Dialog onCreateDialog(Bundle bundle) {
//リスナーの生成
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
//ダイアログボタン押下時に呼ばれる
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
MessageDialog.show(getActivity(), "", "YES");
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
MessageDialog.show(getActivity(), "", "NO");
}
}
};
//Yes/Noダイアログの生成
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
ad.setTitle(getArguments().getString("title"));
ad.setMessage(getArguments().getString("text"));
ad.setPositiveButton("Yes", listener);
ad.setNegativeButton("No", listener);
return ad.create();
}
}
//テキスト入力ダイアログの定義
public static class TextDialog extends DialogFragment{
private EditText editText;
//ダイアログの表示
public static void show(Activity activity, String title, String text){
TextDialog f = new TextDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("text", text);
f.setArguments(args);
f.show(activity.getFragmentManager(), "textDialog");
}
//テキスト入力ダイアログの生成
@Override
public Dialog onCreateDialog(Bundle bundle){
//リスナーの生成
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
//ダイアログボタン押下時に呼ばれる
@Override
public void onClick(DialogInterface dialog, int which) {
if(editText.getText().toString().equals("")){
MessageDialog.show(getActivity(), "", "何も入力されませんでした");
}else{
MessageDialog.show(getActivity(), "", editText.getText().toString());
}
}
};
//エディットテキストの生成
editText = new EditText(getActivity());
//テキスト入力ダイアログの生成
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
ad.setTitle(getArguments().getString("title"));
ad.setMessage(getArguments().getString("text"));
ad.setView(editText);
ad.setPositiveButton("OK", listener);
//フラグメントの状態復帰
if(bundle != null) editText.setText(bundle.getString("editText", ""));
return ad.create();
}
//フラグメントの状態保存
@Override
public void onSaveInstanceState(Bundle bundle){
super.onSaveInstanceState(bundle);
bundle.putString("editText", editText.getText().toString());
}
}
}
試したこと
ソースコードには画像以外の関係ない処理も入っています。
現在はどうしても画像の再描画のやり方がわからなく、
強制的にアプリの再起動を行うという荒業を使って
むりやりもう一度Activityを再起動させ、
onCreate()メソッドを呼び出し再描画を行う
という方法を採っています。
invalidate()メソッドによる再描画も試してみたのですが変わりませんでした・・・。
色々と調べていると根本的ななにかが足りないのではないかと感じています。
どうかご教示のほど宜しくお願い致します。
補足情報(言語/FW/ツール等のバージョンなど)
言語:Java
FW:Android6.0環境
開発ツールver:AndroidStudio2.1
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
public void onClick(View view){
String tag = (String)view.getTag();
if(TAG_IMAGE.equals(tag)){
MessageDialog.show(this, "", "イメージボタンを押した");
//TAG_IMAGEを持つViewはImageButtonであることが分かっているのでキャスト
ImageButton image = (ImageButton)view;
}
}
こういった使い方は教本に出てきてないですかね?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
やりたいことはImageButton#setImageResourceを使って画像を差し替えるだけじゃないですか?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
-1
//ボタンとダイアログ
public class ButtonEx extends Activity implements View.OnClickListener{
private final static int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private final static String TAG_MESSAGE = "0";
private final static String TAG_YESNO = "1";
private final static String TAG_TEXT = "2";
private final static String TAG_IMAGE = "3";
private static boolean imgOk = true;
private Context context;
private int waitperiod = 1000;
LinearLayout layout;
//アクティビティ起動時に呼ばれる
@Override
public void onCreate(Bundle bundle){
System.out.println("onCreate実行");
super.onCreate(bundle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//変更部分(インスタンスをクラスフィールドへ)
//レイアウトの生成
layout = new LinearLayout(this);
layout.setBackgroundColor(Color.WHITE);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
//ボタンの生成
layout.addView(makeButton("メッセージダイアログの表示", TAG_MESSAGE));
layout.addView(makeButton("Yes/Noダイアログの表示", TAG_YESNO));
layout.addView(makeButton("テキスト入力ダイアログの表示", TAG_TEXT));
layout.invalidate();
if(imgOk == true){
System.out.println("目をつぶる");
layout.addView(makeButton(res2bmp(this, R.drawable.sample), TAG_IMAGE));
}else{
System.out.println("目をひらく");
layout.addView(makeButton(res2bmp(this, R.drawable.sample2), TAG_IMAGE));
}
}
//疑似再描画用メソッド
public void restart(Context cnt, int period){
// intent 設定で自分自身のクラスを設定
Intent buttonEx = new Intent(cnt, ButtonEx.class);
// PendingIntent , ID=0
PendingIntent pendingIntent = PendingIntent.getActivity(cnt, 0, buttonEx, PendingIntent.FLAG_CANCEL_CURRENT);
// AlarmManager のインスタンス生成
AlarmManager alarmManager = (AlarmManager)cnt.getSystemService(Context.ALARM_SERVICE);
// 1回のアラームを現在の時間からperiod秒後に実行させる
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + period, pendingIntent);
// アプリ終了
finish();
}
@Override
protected void onResume(){
System.out.println("onResume実行");
super.onResume();
}
//ボタンの生成
private Button makeButton(String text, String tag){
Button button = new Button(this);
button.setText(text);
button.setTag(tag);
button.setOnClickListener(this);
button.setLayoutParams(new LinearLayout.LayoutParams(WC, WC));
button.invalidate();
return button;
}
//イメージボタンの生成
private ImageButton makeButton(Bitmap bmp,String tag){
ImageButton button = new ImageButton(this);
button.setTag(tag);
button.setOnClickListener(this);
button.setImageBitmap(bmp);
button.setLayoutParams(new LinearLayout.LayoutParams(WC, WC));
button.invalidate();
return button;
}
//リソース→ビットマップ
public Bitmap res2bmp(Context context, int resID){
return BitmapFactory.decodeResource(context.getResources(), resID);
}
//ボタン押下時に呼ばれる
public void onClick(View view){
String tag = (String)view.getTag();
if(TAG_MESSAGE.equals(tag)){
MessageDialog.show(this, "メッセージダイアログ", "ボタンを押した");
}else if(TAG_YESNO.equals(tag)){
YesNoDialog.show(this, "Yes/Noダイアログ", "Yes/Noを選択");
}else if(TAG_TEXT.equals((tag))){
TextDialog.show(this, "テキスト入力ダイアログ", "テキストを入力");
}else if(TAG_IMAGE.equals(tag)){
if(imgOk){
imgOk = false;
}else{
imgOk = true;
}
MessageDialog.show(this, "", "イメージボタンを押した");
//変更部分(外に出したインスタンスに対してadd)
if(imgOk == true){
System.out.println("目をつぶる");
layout.addView(makeButton(res2bmp(this, R.drawable.sample), TAG_IMAGE));
}else{
System.out.println("目をひらく");
layout.addView(makeButton(res2bmp(this, R.drawable.sample2), TAG_IMAGE));
}
}
}
//イメージダイアログの定義
public static class MessageDialog extends DialogFragment{
//ダイアログの表示
public static void show(Activity activity, String title, String text){
MessageDialog f = new MessageDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("text", text);
f.setArguments(args);
f.show(activity.getFragmentManager(), "messageDialog");
}
//ダイアログの生成
@Override
public Dialog onCreateDialog(Bundle bundle){
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
ad.setTitle(getArguments().getString("title"));
ad.setMessage(getArguments().getString("text"));
ad.setPositiveButton("OK", null);
return ad.create();
}
}
//Yes/Noダイアログの定義
public static class YesNoDialog extends DialogFragment{
//ダイアログの表示
public static void show(Activity activity, String title, String text){
YesNoDialog f = new YesNoDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("text", text);
f.setArguments(args);
f.show(activity.getFragmentManager(), "yesNoDialog");
}
//Yes/Noダイアログの生成
@Override
public Dialog onCreateDialog(Bundle bundle) {
//リスナーの生成
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
//ダイアログボタン押下時に呼ばれる
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
MessageDialog.show(getActivity(), "", "YES");
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
MessageDialog.show(getActivity(), "", "NO");
}
}
};
//Yes/Noダイアログの生成
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
ad.setTitle(getArguments().getString("title"));
ad.setMessage(getArguments().getString("text"));
ad.setPositiveButton("Yes", listener);
ad.setNegativeButton("No", listener);
return ad.create();
}
}
//テキスト入力ダイアログの定義
public static class TextDialog extends DialogFragment{
private EditText editText;
//ダイアログの表示
public static void show(Activity activity, String title, String text){
TextDialog f = new TextDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("text", text);
f.setArguments(args);
f.show(activity.getFragmentManager(), "textDialog");
}
//テキスト入力ダイアログの生成
@Override
public Dialog onCreateDialog(Bundle bundle){
//リスナーの生成
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
//ダイアログボタン押下時に呼ばれる
@Override
public void onClick(DialogInterface dialog, int which) {
if(editText.getText().toString().equals("")){
MessageDialog.show(getActivity(), "", "何も入力されませんでした");
}else{
MessageDialog.show(getActivity(), "", editText.getText().toString());
}
}
};
//エディットテキストの生成
editText = new EditText(getActivity());
//テキスト入力ダイアログの生成
AlertDialog.Builder ad = new AlertDialog.Builder(getActivity());
ad.setTitle(getArguments().getString("title"));
ad.setMessage(getArguments().getString("text"));
ad.setView(editText);
ad.setPositiveButton("OK", listener);
//フラグメントの状態復帰
if(bundle != null) editText.setText(bundle.getString("editText", ""));
return ad.create();
}
//フラグメントの状態保存
@Override
public void onSaveInstanceState(Bundle bundle){
super.onSaveInstanceState(bundle);
bundle.putString("editText", editText.getText().toString());
}
}
}
上記コードに追記・変更することで画像を押した際の
イベント処理が実装できました。
このままだと画像が増えていきますので差し替え処理をこの後実装します。
質問に答えてくださった方々、ありがとうございました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
abs123
2016/08/23 15:50
出来なかった時のコードを貼ってください、無理やり解決したときのコードを貼られても困ります。
退会済みユーザー
2016/08/23 15:56
ソースコードを読んでいただくとお分かりいただけますが、
無理やり解決したといってもrestartメソッドを作成しonClick()メソッド内で
画像がタップされた際にrestart()メソッドを呼び出すようにしているだけです。
その部分をコメントアウトしていますからこのコード自体が出来ないコードとなっております。
宜しくお願い致します。
abs123
2016/08/23 16:16
invalidate()メソッドによる再描画も試してみた、というのは、どの部分のとこでしょうか?
退会済みユーザー
2016/08/23 16:35 編集
よろしければここではなく回答フォームの方で回答して頂けると嬉しいです。
語句検索(Ctrl+F)で探していただけるとわかると思いますが、makeButton()メソッド内で使用しています。