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

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

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

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

Android Studio

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

Q&A

解決済

1回答

4790閲覧

AndroidStudioでのカレンダー作成で取得ずれが起きる

Aies

総合スコア21

Java

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

Android Studio

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

0グッド

0クリップ

投稿2019/02/05 15:28

編集2019/02/05 15:38

以下のようなコードでカレンダーをGridViewにて作成しているのですが、今月のクリックイベントのときはちゃんとArrayListに値が入っていて正常に日付を取り出せるのですが、Prevボタンを押して前の月に移動したときや次の月の、クリックイベントではArrayListがずれており(前の月の日付列が入っていなければいけないのに、一番最初に保持した値が残っている)、カレンダーの表記上はちゃんと出ているのですが、正常にクリックした日付を取得できません。調べても解決できなそうなのでよろしければご助言お願いいたします。

Java

1Calendar Class 2 3private List<Date> dateArray = new ArrayList(); 4 private Button prevButton, nextButton; 5 private CalendarAdapter mCalendarAdapter; 6 private GridView calendarGridView; 7 private DateManager mDateManager; 8 private KakeiboDatabase kDB; 9 int foodEx,dailyNe,eduEx,lesson,entEx,other; 10 int total; 11 float foodExPar, dailyNePar, eduExPar, lessonPar, entExPar, otherPar; 12 float oneHan = 100; 13 14 15 @Override 16 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 17 mDateManager = new DateManager(); 18 dateArray = mDateManager.getDays(); 19 String date = titleText.getText().toString().substring(0,7); 20 date = date + "-" + dateArray.get(position).toString().substring(8,10); //ここでポジションがあっているのにdateArrayがずれていて前月や次の月の日付取得ができません 21 String judge = readData(date); 22 if(judge!=null) { 23 Intent intent = new Intent(getApplication(), DailyData.class); 24 intent.putExtra("CalendarID", date); 25 startActivity(intent); 26 } 27 } 28 29 30 private static Calendar instance = null; 31 32 @Override 33 protected void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.activity_calendar); 36 37 38 39 instance = this; 40 41 titleText = findViewById(R.id.titleText); 42 prevButton = findViewById(R.id.prevButton); 43 prevButton.setOnClickListener(new View.OnClickListener() { 44 @Override 45 public void onClick(View v) { 46 mCalendarAdapter.prevMonth(); 47 titleText.setText(mCalendarAdapter.getTitle()); 48 listenerSet(); 49 } 50 }); 51 nextButton = findViewById(R.id.nextButton); 52 nextButton.setOnClickListener(new View.OnClickListener() { 53 @Override 54 public void onClick(View v) { 55 mCalendarAdapter.nextMonth(); 56 titleText.setText(mCalendarAdapter.getTitle()); 57 listenerSet(); 58 } 59 }); 60 calendarGridView = findViewById(R.id.calendarGridView); 61 mCalendarAdapter = new CalendarAdapter(this); 62 calendarGridView.setAdapter(mCalendarAdapter); 63 titleText.setText(mCalendarAdapter.getTitle()); 64 65 66 calendarGridView.setOnItemClickListener(this); 67 } 68 public void listenerSet(){ 69 calendarGridView.setOnItemClickListener(this); 70 } 71}

Java

1alendarAdapter Class 2 3public class CalendarAdapter extends BaseAdapter { 4 private List<Date> dateArray = new ArrayList(); 5 private Context mContext; 6 private DateManager mDateManager; 7 private LayoutInflater mLayoutInflater; 8 private String spendPrice; 9 private String incomePrice; 10 11 //カスタムセルを拡張したらここでWigetを定義 12 private static class ViewHolder { 13 public TextView dateText; 14 } 15 16 public CalendarAdapter(Context context){ 17 mContext = context; 18 mLayoutInflater = LayoutInflater.from(mContext); 19 mDateManager = new DateManager(); 20 dateArray = mDateManager.getDays(); 21 } 22 23 @Override 24 public int getCount() { 25 return dateArray.size(); 26 } 27 28 @Override 29 public View getView(int position, View convertView, ViewGroup parent) { 30 ViewHolder holder; 31 if (convertView == null) { 32 convertView = mLayoutInflater.inflate(R.layout.calendar_cell, null); 33 holder = new ViewHolder(); 34 holder.dateText = convertView.findViewById(R.id.dateText); 35 convertView.setTag(holder); 36 } else { 37 holder = (ViewHolder)convertView.getTag(); 38 } 39 40 //セルのサイズを指定 41 float dp = mContext.getResources().getDisplayMetrics().density; 42 AbsListView.LayoutParams params = new AbsListView.LayoutParams(parent.getWidth()/7 - (int)dp, (parent.getHeight() - (int)dp * mDateManager.getWeeks() ) / mDateManager.getWeeks()); 43 convertView.setLayoutParams(params); 44 45 //その月日の金額をまとめる 46 Calendar cal = (Calendar)mContext; 47 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.JAPAN); 48 String sDate = format.format(dateArray.get(position)); 49 50 String getSpend = cal.readData(sDate); 51 String getIncome = cal.incomeData(sDate); 52 53 spendPrice = "<font color=\"red\">" + getSpend + "円</font>"; 54 incomePrice = "<font color=\"blue\">" + getIncome + "円</font>"; 55 56 String price; 57 58 //日付とデータベースの金額を表示させる 59 SimpleDateFormat dateFormat = new SimpleDateFormat("d", Locale.JAPAN); 60 if((getSpend==null) && (getIncome == null)){ 61 holder.dateText.setText(dateFormat.format(dateArray.get(position))); 62 } else if((getSpend==null) && (getIncome!=null)){ 63 holder.dateText.setText(Html.fromHtml(dateFormat.format(dateArray.get(position)) + "<br>" + incomePrice)); 64 } else if((getSpend!=null) && (getIncome==null)) { 65 holder.dateText.setText(Html.fromHtml(dateFormat.format(dateArray.get(position)) + "<br>" + spendPrice)); 66 } else { 67 holder.dateText.setText(Html.fromHtml(dateFormat.format(dateArray.get(position)) + "<br>" + incomePrice + "<br>" + spendPrice)); 68 } 69 70 //当月以外のセルをグレーアウト 71 if (mDateManager.isCurrentMonth(dateArray.get(position))){ 72 convertView.setBackgroundColor(Color.WHITE); 73 }else { 74 convertView.setBackgroundColor(Color.LTGRAY); 75 } 76 77 //日曜日を赤、土曜日を青に 78 int colorId; 79 switch (mDateManager.getDayOfWeek(dateArray.get(position))){ 80 case 1: 81 colorId = Color.RED; 82 break; 83 case 7: 84 colorId = Color.BLUE; 85 break; 86 87 default: 88 colorId = Color.BLACK; 89 break; 90 } 91 holder.dateText.setTextColor(colorId); 92 93 return convertView; 94 } 95 96 @Override 97 public long getItemId(int position) { 98 return 0; 99 } 100 101 @Override 102 public Object getItem(int position) { 103 return null; 104 } 105 106 //表示月を取得 107 public String getTitle(){ 108 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM", Locale.JAPAN); 109 return format.format(mDateManager.mCalendar.getTime()); 110 } 111 112 //翌月表示 113 public void nextMonth(){ 114 mDateManager.nextMonth(); 115 dateArray = mDateManager.getDays(); 116 this.notifyDataSetChanged(); 117 } 118 119 //前月表示 120 public void prevMonth(){ 121 mDateManager.prevMonth(); 122 dateArray = mDateManager.getDays(); 123 this.notifyDataSetChanged(); 124 } 125 static Date truncateTime(Date d) { 126 Instant instant = d.toInstant(); 127 ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Tokyo", ZoneId.SHORT_IDS)); 128 ZonedDateTime truncated = zonedDateTime.truncatedTo(ChronoUnit.DAYS); 129 return Date.from(truncated.toInstant()); 130 } 131} 132

Java

1DateManager Class 2 3public class DateManager { 4 Calendar mCalendar; 5 6 public DateManager(){ 7 mCalendar = Calendar.getInstance(); 8 } 9 10 //当月の要素を取得 11 public List<Date> getDays(){ 12 //現在の状態を保持 13 Date startDate = mCalendar.getTime(); 14 15 //GridViewに表示するマスの合計を計算 16 int count = getWeeks() * 7 ; 17 18 //当月のカレンダーに表示される前月分の日数を計算 19 mCalendar.set(Calendar.DATE, 1); 20 int dayOfWeek = mCalendar.get(Calendar.DAY_OF_WEEK) - 1; 21 mCalendar.add(Calendar.DATE, -dayOfWeek); 22 23 List<Date> days = new ArrayList<>(); 24 25 for (int i = 0; i < count; i ++){ 26 days.add(mCalendar.getTime()); 27 mCalendar.add(Calendar.DATE, 1); 28 } 29 30 //状態を復元 31 mCalendar.setTime(startDate); 32 33 return days; 34 } 35 36 //当月かどうか確認 37 public boolean isCurrentMonth(Date date){ 38 SimpleDateFormat format = new SimpleDateFormat("yyyy.MM", Locale.JAPAN); 39 String currentMonth = format.format(mCalendar.getTime()); 40 if (currentMonth.equals(format.format(date))){ 41 return true; 42 }else { 43 return false; 44 } 45 } 46 47 //週数を取得 48 public int getWeeks(){ 49 return mCalendar.getActualMaximum(Calendar.WEEK_OF_MONTH); 50 } 51 52 //曜日を取得 53 public int getDayOfWeek(Date date) { 54 Calendar calendar = Calendar.getInstance(); 55 calendar.setTime(date); 56 return calendar.get(Calendar.DAY_OF_WEEK); 57 } 58 59 //翌月へ 60 public void nextMonth(){ 61 mCalendar.add(Calendar.MONTH, 1); 62 } 63 64 //前月へ 65 public void prevMonth(){ 66 mCalendar.add(Calendar.MONTH, -1); 67 } 68} 69

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

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

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

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

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

guest

回答1

0

ベストアンサー

ざっと見た感じですが, Calendar クラスの onItemClick で, dateArray を作成する DateManager が作られていますが,

java

1mDateManager = new DateManager(); // <- これです 2dateArray = mDateManager.getDays(); 3String date = titleText.getText().toString().substring(0,7); 4date = date + "-" + dateArray.get(position).toString().substring(8,10)

DateManager は「何月の」dateArray を生成していますか?
画面の表示が前月や次月に移動した場合に, それに追従した dateArray が生成されるようになっていますでしょうか.

投稿2019/02/05 15:42

編集2019/02/06 01:42
jimbe

総合スコア12646

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

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

Aies

2019/02/05 23:23 編集

回答ありがとうございます。 前の月表示前である当月のdateArrayが生成されているように思えます。 DateManagerのコンストラクタにあるインスタンス設定で最初の月の値がまた入っているのでしょうか?
jimbe

2019/02/06 02:17

どのようにするとどのようなインスタンスが作成されるのかは, 作者の Aies さんがご理解頂いていなくてはなりません. DateManager はどのような存在でしょうか. DateManager は CalendarAdapter クラスでも使われていますが, こちらは前月・次月ボタンの操作によって, メソッドを呼び出して自身の内容を更新しているようです. つまり DateManager は, 現在表示中の月の各日付を管理しているモノと考えられます. ですから, このアプリの起動時に1つだけ生成して使うことを想定したモノで, 何度も作られるモノでは無いと思われます. CalendarAdapter 内の DateManager のインスタンス mDateManager を使っては如何でしょう. CalenderAdapter のインスタンスは Calender クラスが mCalendarAdapter として持っています. CalendarAdapter には, 本来こういった場合に使う getItem(int position) がありますが, 現在は null を返していて使えません. mDateManager.getDays().get(position) を返すようにすることで, 問題の date = date + "-" + dateArray.get(position).toString().substring(8,10); という行が date = date + "-" + mCalendarAdapter.getItem(position).toString().substring(8,10); と書けるようになります.
jimbe

2019/02/06 03:14 編集

なお, toString は本来デバッグ用のもので, ~.toString().substring(8,10) のように解析して使用することを想定されていないものだということを念のためお伝えしておきます. toString の返す文字列は, 実装やバージョン, 時にはオブジェクトの内容毎にでも異なって良いことになっています. それを知らずにいますと, 後になって「何もしていないのに動かなくなった」となる場合があります. 文字列にして一部を取り出すのでは無く, Date 型から月・日など必要なデータを一つずつ取り出して文字列化(フォーマット)するようにしたほうが良いと思います.
Aies

2019/02/06 05:44

なるほど。ご指摘の通り、一つずつコメントをつけるなどして理解するようにしたら、解決し、理解も深まりました。ありがとうございました。 結果おっしゃっていた通り、return nullをかえ、受け取るようにしたらできました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問