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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

1回答

3150閲覧

gridViewの各セルにはりつけたlayaout内のテキストビューを書き換えたい。

dabodaboda29

総合スコア6

Android

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2018/07/06 16:59

編集2018/07/08 00:31

前提・実現したいこと

androidでシフト管理アプリを開発しています。
シフトを登録したボタンをクリック→シフトを記入したい日付セルをクリック、でカレンダー上にシフトがのるようになっています。
最後に日付をキーにしてプレファレンスでシフトを記録、参照してOnResumeでシフトが記入されたカレンダーを復元したいのです。
このとき、calenderGridViewにinflateしているcalender_cellのテキスト(tx_shift)を変更したいのですが、viewが指定できず、nullPointExceptionが帰ってきてしまいます。

どのようにすれば、目的のviewを取得できるでしょうか。
また、その他にカレンダーを復元する方法はあるでしょうか。

発生している問題・エラーメッセージ

FATAL EXCEPTION: main Process: com.example.shiftcalender, PID: 25808 java.lang.RuntimeException: Unable to resume activity {com.example.shiftcalender/com.example.shiftcalender.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3158) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3189) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2527) at android.app.ActivityThread.access$900(ActivityThread.java:154) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1389) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:5514) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference at com.example.shiftcalender.MainActivity.onResume(MainActivity.java:159) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1259) at android.app.Activity.performResume(Activity.java:6346) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3147) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3189)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2527)  at android.app.ActivityThread.access$900(ActivityThread.java:154)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1389)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:224)  at android.app.ActivityThread.main(ActivityThread.java:5514)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

該当のソースコード

protected void onResume() { super.onResume(); calendarGridView =findViewById(R.id.calendarGridView); mCalendarAdapter = new CalendarAdapter(this); calendarGridView.setAdapter(mCalendarAdapter); View view = mCalendarAdapter.getPositionView(1); date = mCalendarAdapter.getDateText(1); tempShift = CalendarRead(date); if(tempShift != null){ tx_shift = view.findViewById(R.id.tx_shift); //エラーの出る159行目 tx_shift.setText(tempShift); Toast.makeText(this, tempShift,Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "null",Toast.LENGTH_LONG).show(); } } public void CalendarSave(String date, String shiftPT){ SharedPreferences pref = getSharedPreferences("CalendarSave", MODE_PRIVATE); SharedPreferences.Editor editor = pref.edit(); editor.putString(date, shiftPT); editor.commit(); } public String CalendarRead(String date){ SharedPreferences pref = getSharedPreferences("CalendarSave", MODE_PRIVATE); Toast.makeText(this, pref.getString(date,null),Toast.LENGTH_LONG).show(); return pref.getString(date,null); }
public class CalendarAdapter extends BaseAdapter { private List<Date> dateArray = new ArrayList(); private Context mContext; private DateManager mDateManager; private LayoutInflater mLayoutInflater; private Map<Integer, View> positionView; //カスタムセルを拡張したらここでWidgetを定義 private static class ViewHolder{ public TextView dateText,tx_shift; } public CalendarAdapter(Context context){ mContext = context; mLayoutInflater = LayoutInflater.from(mContext); mDateManager = new DateManager(); dateArray = mDateManager.getDays(); positionView = new HashMap<Integer, View>(36); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null){ convertView = mLayoutInflater.inflate(R.layout.calendar_cell, null); holder = new ViewHolder(); holder.dateText = convertView.findViewById(R.id.dateText); holder.tx_shift = convertView.findViewById(R.id.tx_shift); convertView.setTag(holder); }else { holder = (ViewHolder) convertView.getTag(); } //セルのサイズを指定 float dp = mContext.getResources().getDisplayMetrics().density; AbsListView.LayoutParams params = new AbsListView.LayoutParams(parent.getWidth()/7 - (int)dp, (parent.getHeight()/5 - (int)dp)); convertView.setLayoutParams(params); //日付を月/日で表示 SimpleDateFormat dateFormat = new SimpleDateFormat("M/d", Locale.US); holder.dateText.setText(dateFormat.format(dateArray.get(position))); positionView.put(position, convertView); return convertView; } public View getPositionView(int position){ View targetView = positionView.get(position); return targetView; } public String getDateText(int position){ SimpleDateFormat dateFormat = new SimpleDateFormat("M/d", Locale.US); return dateFormat.format(dateArray.get(position)).toString(); }

試したこと

gridViewからgetChildAtで取れないかと試しましたが、これもnullが帰ってくる。
viewが取れないのであればと、calenderAdapterのgetView内でプレファレンスを調べて、データがあればtx_shiftに代入、と思いましたがgetSharedPrefarencesが使えず…。
手探りで開発しているので的外れな部分が多々あるかと思いますが、何卒よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Android Studio 3.1.2

大元のソースはこちらを参考にさせていただいてます。

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

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

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

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

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

guest

回答1

0

GridViewなどのAdapterをセットする形式のViewは画面内に表示できるだけの子Viewを持つようになっているため、子Viewを直接取得して表示を書き換えるのではなく、Adapterにデータの更新を伝えることで子Viewの更新を促すようにすべきです。

ご質問のコードのCalendarAdapter内にある positionView のように、子Viewにアクセスするためのキャッシュを持っておくのはアンチパターンなので削除しましょう。その代わりに、tx_shiftに関連するデータをAdapterに持たせ、 getView() 内で子Viewの設定をすべて行うようにします。Activity側では、Adapter内のデータを変更して、変更を通知するために notifyDataSetChanged() を呼べばOKです。

java

1// 修正例 2public class CalendarAdapter extends BaseAdapter { 3 4 private String tempShift = null; 5 6 // 外部からtempShiftを設定するためのメソッド 7 public void setTempShift(String tempShift) { 8 this.tempShift = tempShift; 9 } 10 11 @Override 12 public View getView(int position, View convertView, ViewGroup parent) { 13 ... 14 15 // tx_shiftの設定(ロジックは適当なので調整してください) 16 if (position == 1 && tempShift != null) { 17 // tempShiftがnullでなく、1番目のViewなら表示 18 holder.tx_shift.setText(tempShift); 19 } else { 20 // それ以外なら空文字を表示 21 holder.tx_shift.setText(""); 22 } 23 24 return convertView; 25 } 26 27} 28 29// Activity側 30protected void onResume() { 31 super.onResume(); 32 33 calendarGridView = findViewById(R.id.calendarGridView); 34 mCalendarAdapter = new CalendarAdapter(this); 35 calendarGridView.setAdapter(mCalendarAdapter); 36 37 date = mCalendarAdapter.getDateText(1); 38 tempShift = CalendarRead(date); 39 40 // tempShiftをセットし、データの更新を伝える 41 mCalendarAdapter.setTempShift(tempShift); 42 mCalendarAdapter.notifyDataSetChanged(); 43}

投稿2018/07/09 14:37

編集2018/07/09 14:40
kakajika

総合スコア3131

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問