回答編集履歴
17
コード修正
test
CHANGED
@@ -44,7 +44,7 @@
|
|
44
44
|
|
45
45
|
if(savedInstanceState == null) {
|
46
46
|
getSupportFragmentManager().beginTransaction()
|
47
|
-
.a
|
47
|
+
.replace(R.id.fragment_container, new MonthFragment())
|
48
48
|
.commit();
|
49
49
|
}
|
50
50
|
}
|
16
MainActivity関係追加(アプリを実行したまま言語を切り替えた際のバグのため)
test
CHANGED
@@ -28,9 +28,38 @@
|
|
28
28
|
|
29
29
|
---
|
30
30
|
アダプタが分かりませんが想像で追加、フラグメントで完結するようにしました。
|
31
|
-
アクティビティは onCreate でフラグメントを配置するだけなので省略です。
|
32
31
|
Calendar は扱い難いので LocalDate/YearMonth に変更、年月の表示は Adapter の更新を受ける形とし、年月の国際化対応(?)、曜日名表示の追加、今日の日は描画時に背景色を変えています。
|
33
32
|
|
33
|
+
MainActivity.java
|
34
|
+
```java
|
35
|
+
import android.os.Bundle;
|
36
|
+
|
37
|
+
import androidx.appcompat.app.AppCompatActivity;
|
38
|
+
|
39
|
+
public class MainActivity extends AppCompatActivity {
|
40
|
+
@Override
|
41
|
+
protected void onCreate(Bundle savedInstanceState) {
|
42
|
+
super.onCreate(savedInstanceState);
|
43
|
+
setContentView(R.layout.activity_main);
|
44
|
+
|
45
|
+
if(savedInstanceState == null) {
|
46
|
+
getSupportFragmentManager().beginTransaction()
|
47
|
+
.add(R.id.fragment_container, new MonthFragment())
|
48
|
+
.commit();
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
```
|
53
|
+
res/layout/activity_main.xml
|
54
|
+
```xml
|
55
|
+
<?xml version="1.0" encoding="utf-8"?>
|
56
|
+
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
57
|
+
xmlns:tools="http://schemas.android.com/tools"
|
58
|
+
android:id="@+id/fragment_container"
|
59
|
+
android:layout_width="match_parent"
|
60
|
+
android:layout_height="match_parent"
|
61
|
+
tools:context=".MainActivity" />
|
62
|
+
```
|
34
63
|
MonthFragment.java
|
35
64
|
```java
|
36
65
|
import android.graphics.Color;
|
15
インデント修正
test
CHANGED
@@ -142,16 +142,16 @@
|
|
142
142
|
}
|
143
143
|
private int getTextColor(LocalDate date) {
|
144
144
|
return date.getMonth() != current.getMonth() ? Color.LTGRAY : //前月・次月
|
145
|
-
|
145
|
+
getTextColor(date.getDayOfWeek());
|
146
146
|
}
|
147
147
|
private int getTextColor(DayOfWeek dayOfWeek) {
|
148
|
-
return dayOfWeek == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
148
|
+
return dayOfWeek == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
149
|
-
|
149
|
+
dayOfWeek == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
150
|
-
|
150
|
+
Color.BLACK;
|
151
151
|
}
|
152
152
|
private int getBackgroundColor(LocalDate date) {
|
153
153
|
return date.isEqual(LocalDate.now()) ? Color.CYAN : //今日
|
154
|
-
|
154
|
+
Color.TRANSPARENT;
|
155
155
|
}
|
156
156
|
}
|
157
157
|
}
|
14
バグ修正・変数名変更
test
CHANGED
@@ -50,7 +50,7 @@
|
|
50
50
|
import java.util.function.Consumer;
|
51
51
|
|
52
52
|
public class MonthFragment extends Fragment {
|
53
|
-
MonthFragment() {
|
53
|
+
public MonthFragment() {
|
54
54
|
super(R.layout.month_fragment);
|
55
55
|
}
|
56
56
|
|
@@ -76,7 +76,7 @@
|
|
76
76
|
}
|
77
77
|
|
78
78
|
private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
|
79
|
-
private
|
79
|
+
private final DayOfWeek firstDayOfWeek = WeekFields.of(Locale.getDefault()).getFirstDayOfWeek(); //週の始まり
|
80
80
|
|
81
81
|
private final Consumer<YearMonth> dateChangeListener;
|
82
82
|
|
@@ -99,7 +99,7 @@
|
|
99
99
|
|
100
100
|
private void setYearMonth(YearMonth yearMonth) {
|
101
101
|
this.current = yearMonth;
|
102
|
-
start = current.atDay(1).with(TemporalAdjusters.previousOrSame(W
|
102
|
+
start = current.atDay(1).with(TemporalAdjusters.previousOrSame(firstDayOfWeek)); //月初直前の週始め
|
103
103
|
notifyItemRangeChanged(7, 6*7); //日付部分
|
104
104
|
if(dateChangeListener != null) dateChangeListener.accept(current);
|
105
105
|
}
|
@@ -129,7 +129,7 @@
|
|
129
129
|
}
|
130
130
|
void bind(int position) {
|
131
131
|
if(position < 7) { //曜日名
|
132
|
-
DayOfWeek dow = W
|
132
|
+
DayOfWeek dow = firstDayOfWeek.plus(position);
|
133
133
|
day.setTextColor(getTextColor(dow));
|
134
134
|
day.setBackgroundColor(HEADER_BGCOLOR);
|
135
135
|
day.setText(dow.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.getDefault()));
|
13
修正
test
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
まだコードを見ただけで試していませんが。
|
2
|
-
|
3
1
|
MainActivity.java(一部)
|
4
2
|
```java
|
5
3
|
MonthFragment monthFragment = new MonthFragment();
|
@@ -47,7 +45,7 @@
|
|
47
45
|
|
48
46
|
import java.time.*;
|
49
47
|
import java.time.format.TextStyle;
|
50
|
-
import java.time.temporal.
|
48
|
+
import java.time.temporal.*;
|
51
49
|
import java.util.*;
|
52
50
|
import java.util.function.Consumer;
|
53
51
|
|
@@ -78,7 +76,7 @@
|
|
78
76
|
}
|
79
77
|
|
80
78
|
private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
|
81
|
-
private static final DayOfWeek WEEK_FIRST = DayOfWeek
|
79
|
+
private static final DayOfWeek WEEK_FIRST = WeekFields.of(Locale.getDefault()).getFirstDayOfWeek(); //週の始まり
|
82
80
|
|
83
81
|
private final Consumer<YearMonth> dateChangeListener;
|
84
82
|
|
@@ -101,16 +99,9 @@
|
|
101
99
|
|
102
100
|
private void setYearMonth(YearMonth yearMonth) {
|
103
101
|
this.current = yearMonth;
|
104
|
-
start = ca
|
102
|
+
start = current.atDay(1).with(TemporalAdjusters.previousOrSame(WEEK_FIRST)); //月初直前の週始め
|
105
103
|
notifyItemRangeChanged(7, 6*7); //日付部分
|
106
104
|
if(dateChangeListener != null) dateChangeListener.accept(current);
|
107
|
-
}
|
108
|
-
|
109
|
-
//月初直前の週始め
|
110
|
-
private LocalDate calcStart(YearMonth yearMonth) {
|
111
|
-
LocalDate start = yearMonth.atDay(1);
|
112
|
-
LocalDate temp = (LocalDate)WEEK_FIRST.adjustInto(start);
|
113
|
-
return temp.isAfter(start) ? temp.minusDays(7) : temp;
|
114
105
|
}
|
115
106
|
|
116
107
|
@NonNull
|
@@ -151,16 +142,16 @@
|
|
151
142
|
}
|
152
143
|
private int getTextColor(LocalDate date) {
|
153
144
|
return date.getMonth() != current.getMonth() ? Color.LTGRAY : //前月・次月
|
154
|
-
getTextColor(date.getDayOfWeek());
|
145
|
+
getTextColor(date.getDayOfWeek());
|
155
146
|
}
|
156
147
|
private int getTextColor(DayOfWeek dayOfWeek) {
|
157
148
|
return dayOfWeek == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
158
|
-
dayOfWeek == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
149
|
+
dayOfWeek == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
159
|
-
Color.BLACK;
|
150
|
+
Color.BLACK;
|
160
151
|
}
|
161
152
|
private int getBackgroundColor(LocalDate date) {
|
162
153
|
return date.isEqual(LocalDate.now()) ? Color.CYAN : //今日
|
163
|
-
Color.TRANSPARENT;
|
154
|
+
Color.TRANSPARENT;
|
164
155
|
}
|
165
156
|
}
|
166
157
|
}
|
12
修正
test
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
}
|
16
16
|
```
|
17
17
|
これでは、 plus を実行するフラグメントオブジェクトと画面に表示しているフラグメントオブジェクトは **違うモノ** です。
|
18
|
-
**View は Activity に載せないと onCreateView や onViewCreated 等のライフサイクルメソッドは呼ばれません。** 従って this.activity も null のままですので、
|
18
|
+
**View は Activity に載せないと onCreateView や onViewCreated 等のライフサイクルメソッドは呼ばれません。** 従って this.activity も null のままですので、 viewCalendar() 内の activity.findViewById() で例外になっています。
|
19
19
|
```
|
20
20
|
.add(R.id.month_fragment_container, monthFragment)
|
21
21
|
```
|
11
修正
test
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
}
|
16
16
|
```
|
17
17
|
これでは、 plus を実行するフラグメントオブジェクトと画面に表示しているフラグメントオブジェクトは **違うモノ** です。
|
18
|
+
**View は Activity に載せないと onCreateView や onViewCreated 等のライフサイクルメソッドは呼ばれません。** 従って this.activity も null のままですので、 plus() メソッドから処理を続けて activity.findViewById() で activity が null で例外になっています。
|
18
19
|
```
|
19
20
|
.add(R.id.month_fragment_container, monthFragment)
|
20
21
|
```
|
@@ -34,7 +35,6 @@
|
|
34
35
|
|
35
36
|
MonthFragment.java
|
36
37
|
```java
|
37
|
-
import android.annotation.SuppressLint;
|
38
38
|
import android.graphics.Color;
|
39
39
|
import android.os.Bundle;
|
40
40
|
import android.text.format.DateUtils;
|
10
コード修正
test
CHANGED
@@ -99,11 +99,10 @@
|
|
99
99
|
setYearMonth(current.minusMonths(1));
|
100
100
|
}
|
101
101
|
|
102
|
-
@SuppressLint("NotifyDataSetChanged")
|
103
102
|
private void setYearMonth(YearMonth yearMonth) {
|
104
103
|
this.current = yearMonth;
|
105
104
|
start = calcStart(current);
|
106
|
-
notify
|
105
|
+
notifyItemRangeChanged(7, 6*7); //日付部分
|
107
106
|
if(dateChangeListener != null) dateChangeListener.accept(current);
|
108
107
|
}
|
109
108
|
|
@@ -127,7 +126,7 @@
|
|
127
126
|
|
128
127
|
@Override
|
129
128
|
public int getItemCount() {
|
130
|
-
return 7 + 6
|
129
|
+
return 7 + 6*7;
|
131
130
|
}
|
132
131
|
|
133
132
|
class ViewHolder extends RecyclerView.ViewHolder {
|
9
コード修正
test
CHANGED
@@ -110,8 +110,8 @@
|
|
110
110
|
//月初直前の週始め
|
111
111
|
private LocalDate calcStart(YearMonth yearMonth) {
|
112
112
|
LocalDate start = yearMonth.atDay(1);
|
113
|
-
|
113
|
+
LocalDate temp = (LocalDate)WEEK_FIRST.adjustInto(start);
|
114
|
-
return start;
|
114
|
+
return temp.isAfter(start) ? temp.minusDays(7) : temp;
|
115
115
|
}
|
116
116
|
|
117
117
|
@NonNull
|
8
コード修正
test
CHANGED
@@ -83,7 +83,7 @@
|
|
83
83
|
private final Consumer<YearMonth> dateChangeListener;
|
84
84
|
|
85
85
|
private YearMonth current;
|
86
|
-
private
|
86
|
+
private LocalDate start;
|
87
87
|
|
88
88
|
Adapter(@NonNull Consumer<YearMonth> dateChangeListener) {
|
89
89
|
this.dateChangeListener = dateChangeListener;
|
@@ -102,20 +102,16 @@
|
|
102
102
|
@SuppressLint("NotifyDataSetChanged")
|
103
103
|
private void setYearMonth(YearMonth yearMonth) {
|
104
104
|
this.current = yearMonth;
|
105
|
-
|
105
|
+
start = calcStart(current);
|
106
106
|
notifyDataSetChanged();
|
107
107
|
if(dateChangeListener != null) dateChangeListener.accept(current);
|
108
108
|
}
|
109
109
|
|
110
|
-
private void generateDayList(YearMonth yearMonth) {
|
111
|
-
|
110
|
+
//月初直前の週始め
|
111
|
+
private LocalDate calcStart(YearMonth yearMonth) {
|
112
112
|
LocalDate start = yearMonth.atDay(1);
|
113
113
|
while(start.getDayOfWeek() != WEEK_FIRST) start = start.minusDays(1);
|
114
|
-
|
115
|
-
LocalDate endExclusive = start.plusDays(6 * 7); //六週間
|
116
|
-
//start から endExclusive まで
|
117
|
-
|
114
|
+
return start;
|
118
|
-
for(LocalDate date=start; date.isBefore(endExclusive); date=date.plusDays(1)) list.add(date);
|
119
115
|
}
|
120
116
|
|
121
117
|
@NonNull
|
@@ -126,12 +122,12 @@
|
|
126
122
|
|
127
123
|
@Override
|
128
124
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
129
|
-
holder.bind(position
|
125
|
+
holder.bind(position);
|
130
126
|
}
|
131
127
|
|
132
128
|
@Override
|
133
129
|
public int getItemCount() {
|
134
|
-
return
|
130
|
+
return 7 + 6 * 7;
|
135
131
|
}
|
136
132
|
|
137
133
|
class ViewHolder extends RecyclerView.ViewHolder {
|
@@ -141,13 +137,14 @@
|
|
141
137
|
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_day, parent, false));
|
142
138
|
day = itemView.findViewById(R.id.day);
|
143
139
|
}
|
144
|
-
void bind(int position
|
140
|
+
void bind(int position) {
|
145
141
|
if(position < 7) { //曜日名
|
146
142
|
DayOfWeek dow = WEEK_FIRST.plus(position);
|
147
143
|
day.setTextColor(getTextColor(dow));
|
148
144
|
day.setBackgroundColor(HEADER_BGCOLOR);
|
149
145
|
day.setText(dow.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.getDefault()));
|
150
146
|
} else {
|
147
|
+
LocalDate date = start.plusDays(position - 7);
|
151
148
|
day.setTextColor(getTextColor(date));
|
152
149
|
day.setBackgroundColor(getBackgroundColor(date));
|
153
150
|
day.setText(String.valueOf(date.getDayOfMonth()));
|
7
コード修正
test
CHANGED
@@ -30,13 +30,14 @@
|
|
30
30
|
---
|
31
31
|
アダプタが分かりませんが想像で追加、フラグメントで完結するようにしました。
|
32
32
|
アクティビティは onCreate でフラグメントを配置するだけなので省略です。
|
33
|
-
Calendar は扱い難いので LocalDate に変更、年月の表示は Adapter の更新を受ける形とし、今日の日は描画時に背景色を変えています。
|
33
|
+
Calendar は扱い難いので LocalDate/YearMonth に変更、年月の表示は Adapter の更新を受ける形とし、年月の国際化対応(?)、曜日名表示の追加、今日の日は描画時に背景色を変えています。
|
34
34
|
|
35
35
|
MonthFragment.java
|
36
36
|
```java
|
37
37
|
import android.annotation.SuppressLint;
|
38
38
|
import android.graphics.Color;
|
39
39
|
import android.os.Bundle;
|
40
|
+
import android.text.format.DateUtils;
|
40
41
|
import android.view.*;
|
41
42
|
import android.widget.*;
|
42
43
|
|
@@ -46,6 +47,7 @@
|
|
46
47
|
|
47
48
|
import java.time.*;
|
48
49
|
import java.time.format.TextStyle;
|
50
|
+
import java.time.temporal.ChronoField;
|
49
51
|
import java.util.*;
|
50
52
|
import java.util.function.Consumer;
|
51
53
|
|
@@ -56,12 +58,11 @@
|
|
56
58
|
|
57
59
|
@Override
|
58
60
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
59
|
-
TextView yearText = view.findViewById(R.id.year);
|
60
61
|
TextView monthText = view.findViewById(R.id.month);
|
61
62
|
|
62
|
-
Adapter adapter = new Adapter(
|
63
|
+
Adapter adapter = new Adapter(yearMonth -> {
|
63
|
-
year
|
64
|
+
long millies = yearMonth.atDay(1).getLong(ChronoField.EPOCH_DAY) * 24 * 60 * 60 * 1000; //epoch[ms]
|
64
|
-
monthText.setText(
|
65
|
+
monthText.setText(DateUtils.formatDateTime(requireContext(), millies, DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_NO_MONTH_DAY));
|
65
66
|
});
|
66
67
|
|
67
68
|
Button prevButton = view.findViewById(R.id.prev);
|
@@ -72,58 +73,49 @@
|
|
72
73
|
|
73
74
|
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
|
74
75
|
recyclerView.setHasFixedSize(true);
|
75
|
-
recyclerView.setLayoutManager(new GridLayoutManager(
|
76
|
+
recyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 7));
|
76
77
|
recyclerView.setAdapter(adapter);
|
77
78
|
}
|
78
79
|
|
79
80
|
private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
|
80
|
-
private final DayOfWeek WEEK_FIRST = DayOfWeek.SUNDAY; //週の始まり
|
81
|
+
private static final DayOfWeek WEEK_FIRST = DayOfWeek.SUNDAY; //週の始まり
|
81
|
-
|
82
|
+
|
82
|
-
private final Consumer<
|
83
|
+
private final Consumer<YearMonth> dateChangeListener;
|
83
|
-
|
84
|
+
|
84
|
-
private
|
85
|
+
private YearMonth current;
|
85
86
|
private final List<LocalDate> list = new ArrayList<>();
|
86
87
|
|
87
|
-
Adapter(@NonNull Consumer<
|
88
|
+
Adapter(@NonNull Consumer<YearMonth> dateChangeListener) {
|
88
89
|
this.dateChangeListener = dateChangeListener;
|
89
90
|
|
90
|
-
set
|
91
|
+
setYearMonth(YearMonth.now());
|
91
92
|
}
|
92
93
|
|
93
94
|
void next() {
|
94
|
-
set
|
95
|
+
setYearMonth(current.plusMonths(1));
|
95
96
|
}
|
96
97
|
|
97
98
|
void prev() {
|
98
|
-
set
|
99
|
+
setYearMonth(current.minusMonths(1));
|
99
100
|
}
|
100
101
|
|
101
102
|
@SuppressLint("NotifyDataSetChanged")
|
102
|
-
private void set
|
103
|
+
private void setYearMonth(YearMonth yearMonth) {
|
103
|
-
this.current =
|
104
|
+
this.current = yearMonth;
|
104
|
-
generateDayList(current
|
105
|
+
generateDayList(current);
|
105
106
|
notifyDataSetChanged();
|
106
107
|
if(dateChangeListener != null) dateChangeListener.accept(current);
|
107
108
|
}
|
108
109
|
|
109
|
-
private void generateDayList(
|
110
|
+
private void generateDayList(YearMonth yearMonth) {
|
110
|
-
LocalDate first = LocalDate.of(year, month, 1);
|
111
111
|
//月初直前の週始め
|
112
|
-
LocalDate start =
|
112
|
+
LocalDate start = yearMonth.atDay(1);
|
113
|
-
while(start.getDayOfWeek() != WEEK_FIRST)
|
113
|
+
while(start.getDayOfWeek() != WEEK_FIRST) start = start.minusDays(1);
|
114
|
-
|
114
|
+
|
115
|
-
}
|
116
|
-
//月末直後の週始め
|
117
|
-
LocalDate endExclusive = first.plusMonths(1);
|
118
|
-
while(endExclusive.getDayOfWeek() != WEEK_FIRST) {
|
119
|
-
endExclusive = endExclusive.plusDays(1);
|
120
|
-
}
|
121
|
-
endExclusive =
|
115
|
+
LocalDate endExclusive = start.plusDays(6 * 7); //六週間
|
122
116
|
//start から endExclusive まで
|
123
117
|
list.clear();
|
124
|
-
for(LocalDate date=start; date.isBefore(endExclusive); date=date.plusDays(1))
|
118
|
+
for(LocalDate date=start; date.isBefore(endExclusive); date=date.plusDays(1)) list.add(date);
|
125
|
-
list.add(date);
|
126
|
-
}
|
127
119
|
}
|
128
120
|
|
129
121
|
@NonNull
|
@@ -134,28 +126,45 @@
|
|
134
126
|
|
135
127
|
@Override
|
136
128
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
137
|
-
holder.bind(list.get(position));
|
129
|
+
holder.bind(position, position < 7 ? null : list.get(position - 7));
|
138
130
|
}
|
139
131
|
|
140
132
|
@Override
|
141
133
|
public int getItemCount() {
|
142
|
-
return list.size();
|
134
|
+
return list.size() + 7;
|
143
135
|
}
|
144
136
|
|
145
137
|
class ViewHolder extends RecyclerView.ViewHolder {
|
138
|
+
private final int HEADER_BGCOLOR = Color.rgb(240,240,240);
|
146
139
|
private final TextView day;
|
147
140
|
ViewHolder(ViewGroup parent) {
|
148
141
|
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_day, parent, false));
|
149
142
|
day = itemView.findViewById(R.id.day);
|
150
143
|
}
|
151
|
-
void bind(LocalDate date) {
|
144
|
+
void bind(int position, LocalDate date) {
|
152
|
-
day.setTextColor(
|
153
|
-
date.getMonth() != current.getMonth() ? Color.LTGRAY : //前月・次月
|
154
|
-
date.getDayOfWeek() == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
155
|
-
date.getDayOfWeek() == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
156
|
-
|
145
|
+
if(position < 7) { //曜日名
|
146
|
+
DayOfWeek dow = WEEK_FIRST.plus(position);
|
147
|
+
day.setTextColor(getTextColor(dow));
|
148
|
+
day.setBackgroundColor(HEADER_BGCOLOR);
|
149
|
+
day.setText(dow.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.getDefault()));
|
150
|
+
} else {
|
151
|
+
day.setTextColor(getTextColor(date));
|
157
|
-
day.setBackgroundColor(
|
152
|
+
day.setBackgroundColor(getBackgroundColor(date));
|
158
|
-
day.setText(String.valueOf(date.getDayOfMonth()));
|
153
|
+
day.setText(String.valueOf(date.getDayOfMonth()));
|
154
|
+
}
|
155
|
+
}
|
156
|
+
private int getTextColor(LocalDate date) {
|
157
|
+
return date.getMonth() != current.getMonth() ? Color.LTGRAY : //前月・次月
|
158
|
+
getTextColor(date.getDayOfWeek());
|
159
|
+
}
|
160
|
+
private int getTextColor(DayOfWeek dayOfWeek) {
|
161
|
+
return dayOfWeek == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
162
|
+
dayOfWeek == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
163
|
+
Color.BLACK;
|
164
|
+
}
|
165
|
+
private int getBackgroundColor(LocalDate date) {
|
166
|
+
return date.isEqual(LocalDate.now()) ? Color.CYAN : //今日
|
167
|
+
Color.TRANSPARENT;
|
159
168
|
}
|
160
169
|
}
|
161
170
|
}
|
@@ -164,28 +173,10 @@
|
|
164
173
|
res/layout/month_fragment.xml
|
165
174
|
```xml
|
166
175
|
<?xml version="1.0" encoding="utf-8"?>
|
167
|
-
<androidx.constraintlayout.widget.ConstraintLayout
|
168
|
-
|
176
|
+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
169
177
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
170
178
|
android:layout_width="match_parent"
|
171
179
|
android:layout_height="match_parent">
|
172
|
-
|
173
|
-
<TextView
|
174
|
-
android:id="@+id/year"
|
175
|
-
android:layout_width="wrap_content"
|
176
|
-
android:layout_height="wrap_content"
|
177
|
-
android:text="year"
|
178
|
-
app:layout_constraintEnd_toEndOf="parent"
|
179
|
-
app:layout_constraintStart_toStartOf="parent"
|
180
|
-
app:layout_constraintTop_toTopOf="parent" />
|
181
|
-
|
182
|
-
<Space
|
183
|
-
android:id="@+id/year_bottom"
|
184
|
-
android:layout_width="0dp"
|
185
|
-
android:layout_height="32dp"
|
186
|
-
app:layout_constraintEnd_toEndOf="parent"
|
187
|
-
app:layout_constraintStart_toStartOf="parent"
|
188
|
-
app:layout_constraintTop_toBottomOf="@id/year" />
|
189
180
|
|
190
181
|
<Button
|
191
182
|
android:id="@+id/prev"
|
@@ -196,21 +187,20 @@
|
|
196
187
|
android:text="prev"
|
197
188
|
android:textColor="@color/black"
|
198
189
|
android:textSize="24sp"
|
199
|
-
app:layout_constraintBottom_toTopOf="@id/header_bottom"
|
200
|
-
app:layout_constraint
|
190
|
+
app:layout_constraintBaseline_toBaselineOf="@id/month"
|
201
|
-
app:layout_constraint
|
191
|
+
app:layout_constraintStart_toStartOf="parent" />
|
202
192
|
|
203
193
|
<TextView
|
204
194
|
android:id="@+id/month"
|
205
|
-
android:layout_width="
|
195
|
+
android:layout_width="0dp"
|
206
|
-
android:layout_height="wrap_content"
|
196
|
+
android:layout_height="wrap_content"
|
197
|
+
android:layout_marginTop="32dp"
|
207
198
|
android:text="month"
|
199
|
+
android:textAlignment="center"
|
208
200
|
android:textSize="24sp"
|
209
|
-
android:textAlignment="center"
|
210
|
-
app:layout_constraintBottom_toTopOf="@id/header_bottom"
|
211
201
|
app:layout_constraintEnd_toEndOf="parent"
|
212
202
|
app:layout_constraintStart_toStartOf="parent"
|
213
|
-
app:layout_constraintTop_to
|
203
|
+
app:layout_constraintTop_toTopOf="parent" />
|
214
204
|
|
215
205
|
<Button
|
216
206
|
android:id="@+id/next"
|
@@ -221,16 +211,8 @@
|
|
221
211
|
android:text="next"
|
222
212
|
android:textColor="@color/black"
|
223
213
|
android:textSize="24sp"
|
224
|
-
app:layout_constraintBottom_toTopOf="@id/header_bottom"
|
225
|
-
app:layout_constraint
|
214
|
+
app:layout_constraintBaseline_toBaselineOf="@id/month"
|
226
|
-
app:layout_constraint
|
215
|
+
app:layout_constraintEnd_toEndOf="parent" />
|
227
|
-
|
228
|
-
<androidx.constraintlayout.widget.Barrier
|
229
|
-
android:id="@+id/header_bottom"
|
230
|
-
android:layout_width="0dp"
|
231
|
-
android:layout_height="0dp"
|
232
|
-
app:barrierDirection="bottom"
|
233
|
-
app:constraint_referenced_ids="prev, month, next" />
|
234
216
|
|
235
217
|
<androidx.recyclerview.widget.RecyclerView
|
236
218
|
android:id="@+id/recycler_view"
|
@@ -239,7 +221,7 @@
|
|
239
221
|
app:layout_constraintBottom_toBottomOf="parent"
|
240
222
|
app:layout_constraintEnd_toEndOf="parent"
|
241
223
|
app:layout_constraintStart_toStartOf="parent"
|
242
|
-
app:layout_constraintTop_toBottomOf="@id/
|
224
|
+
app:layout_constraintTop_toBottomOf="@id/month" />
|
243
225
|
|
244
226
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
245
227
|
```
|
@@ -250,9 +232,12 @@
|
|
250
232
|
android:id="@+id/day"
|
251
233
|
android:layout_width="match_parent"
|
252
234
|
android:layout_height="wrap_content"
|
235
|
+
android:autoSizeTextType="uniform"
|
236
|
+
android:ellipsize="end"
|
237
|
+
android:maxLines="1"
|
253
238
|
android:text="21"
|
254
|
-
android:textSize="30sp"
|
255
|
-
android:textAlignment="center"
|
239
|
+
android:textAlignment="center"
|
240
|
+
android:textSize="30sp" />
|
256
|
-
```
|
241
|
+
```
|
257
|
-
![起動時(1月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/
|
242
|
+
![起動時(1月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/01a37e83-2801-41aa-b9ce-7307f19fc88c.png)
|
258
|
-
![next押下時(2月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/
|
243
|
+
![next押下時(2月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/fa1137d9-47fd-4e18-b79a-9b5e10ed53c4.png)
|
6
行数削減のためレイアウトを簡略化
test
CHANGED
@@ -246,23 +246,13 @@
|
|
246
246
|
res/layout/grid_day.xml
|
247
247
|
```xml
|
248
248
|
<?xml version="1.0" encoding="utf-8"?>
|
249
|
-
<
|
249
|
+
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
250
|
+
android:id="@+id/day"
|
250
251
|
android:layout_width="match_parent"
|
251
252
|
android:layout_height="wrap_content"
|
252
|
-
xmlns:app="http://schemas.android.com/apk/res-auto">
|
253
|
-
|
254
|
-
<TextView
|
255
|
-
android:id="@+id/day"
|
256
|
-
android:layout_width="0dp"
|
257
|
-
android:layout_height="wrap_content"
|
258
|
-
|
253
|
+
android:text="21"
|
259
|
-
|
254
|
+
android:textSize="30sp"
|
260
|
-
|
255
|
+
android:textAlignment="center" />
|
261
|
-
app:layout_constraintEnd_toEndOf="parent"
|
262
|
-
app:layout_constraintStart_toStartOf="parent"
|
263
|
-
app:layout_constraintTop_toTopOf="parent" />
|
264
|
-
|
265
|
-
</androidx.constraintlayout.widget.ConstraintLayout>
|
266
256
|
```
|
267
257
|
![起動時(1月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/70f2e1ae-47cf-4f77-8e7f-1214a9bf932e.png)
|
268
258
|
![next押下時(2月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/149202ea-11d4-4838-8109-eed338dd84e7.png)
|
5
コードのワーニング等修正
test
CHANGED
@@ -45,6 +45,7 @@
|
|
45
45
|
import androidx.recyclerview.widget.*;
|
46
46
|
|
47
47
|
import java.time.*;
|
48
|
+
import java.time.format.TextStyle;
|
48
49
|
import java.util.*;
|
49
50
|
import java.util.function.Consumer;
|
50
51
|
|
@@ -59,8 +60,8 @@
|
|
59
60
|
TextView monthText = view.findViewById(R.id.month);
|
60
61
|
|
61
62
|
Adapter adapter = new Adapter(date -> {
|
62
|
-
yearText.setText(
|
63
|
+
yearText.setText(String.format(Locale.getDefault(), "%d年", date.getYear()));
|
63
|
-
monthText.setText(date.getMonth
|
64
|
+
monthText.setText(date.getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault()));
|
64
65
|
});
|
65
66
|
|
66
67
|
Button prevButton = view.findViewById(R.id.prev);
|
@@ -76,11 +77,12 @@
|
|
76
77
|
}
|
77
78
|
|
78
79
|
private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
|
80
|
+
private final DayOfWeek WEEK_FIRST = DayOfWeek.SUNDAY; //週の始まり
|
81
|
+
|
79
|
-
private Consumer<LocalDate> dateChangeListener;
|
82
|
+
private final Consumer<LocalDate> dateChangeListener;
|
80
|
-
|
81
|
-
|
83
|
+
|
82
84
|
private LocalDate current;
|
83
|
-
private List<LocalDate> list = new ArrayList<>();
|
85
|
+
private final List<LocalDate> list = new ArrayList<>();
|
84
86
|
|
85
87
|
Adapter(@NonNull Consumer<LocalDate> dateChangeListener) {
|
86
88
|
this.dateChangeListener = dateChangeListener;
|
@@ -106,21 +108,21 @@
|
|
106
108
|
|
107
109
|
private void generateDayList(int year, int month) {
|
108
110
|
LocalDate first = LocalDate.of(year, month, 1);
|
109
|
-
//月初
|
111
|
+
//月初直前の週始め
|
110
112
|
LocalDate start = first;
|
111
|
-
while(start.getDayOfWeek() !=
|
113
|
+
while(start.getDayOfWeek() != WEEK_FIRST) {
|
112
114
|
start = start.minusDays(1);
|
113
115
|
}
|
114
|
-
//
|
116
|
+
//月末直後の週始め
|
115
117
|
LocalDate endExclusive = first.plusMonths(1);
|
116
|
-
while(endExclusive.getDayOfWeek() !=
|
118
|
+
while(endExclusive.getDayOfWeek() != WEEK_FIRST) {
|
117
119
|
endExclusive = endExclusive.plusDays(1);
|
118
120
|
}
|
119
121
|
endExclusive = endExclusive.plusDays(7); //+一週間
|
120
122
|
//start から endExclusive まで
|
121
123
|
list.clear();
|
122
|
-
for(LocalDate t
|
124
|
+
for(LocalDate date=start; date.isBefore(endExclusive); date=date.plusDays(1)) {
|
123
|
-
list.add(t
|
125
|
+
list.add(date);
|
124
126
|
}
|
125
127
|
}
|
126
128
|
|
@@ -141,7 +143,7 @@
|
|
141
143
|
}
|
142
144
|
|
143
145
|
class ViewHolder extends RecyclerView.ViewHolder {
|
144
|
-
private TextView day;
|
146
|
+
private final TextView day;
|
145
147
|
ViewHolder(ViewGroup parent) {
|
146
148
|
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_day, parent, false));
|
147
149
|
day = itemView.findViewById(R.id.day);
|
@@ -151,9 +153,9 @@
|
|
151
153
|
date.getMonth() != current.getMonth() ? Color.LTGRAY : //前月・次月
|
152
154
|
date.getDayOfWeek() == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
153
155
|
date.getDayOfWeek() == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
154
|
-
|
156
|
+
Color.BLACK); //通常
|
155
|
-
day.setBackgroundColor(date.
|
157
|
+
day.setBackgroundColor(date.isEqual(LocalDate.now()) ? Color.CYAN : Color.TRANSPARENT); //今日
|
156
|
-
day.setText(
|
158
|
+
day.setText(String.valueOf(date.getDayOfMonth()));
|
157
159
|
}
|
158
160
|
}
|
159
161
|
}
|
4
ログ入れっぱなしだったので削除
test
CHANGED
@@ -37,7 +37,6 @@
|
|
37
37
|
import android.annotation.SuppressLint;
|
38
38
|
import android.graphics.Color;
|
39
39
|
import android.os.Bundle;
|
40
|
-
import android.util.Log;
|
41
40
|
import android.view.*;
|
42
41
|
import android.widget.*;
|
43
42
|
|
@@ -56,7 +55,6 @@
|
|
56
55
|
|
57
56
|
@Override
|
58
57
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
59
|
-
Log.d("MonthFragment", "onViewCreated");
|
60
58
|
TextView yearText = view.findViewById(R.id.year);
|
61
59
|
TextView monthText = view.findViewById(R.id.month);
|
62
60
|
|
@@ -75,7 +73,6 @@
|
|
75
73
|
recyclerView.setHasFixedSize(true);
|
76
74
|
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 7));
|
77
75
|
recyclerView.setAdapter(adapter);
|
78
|
-
Log.d("MonthFragment", "onViewCreated end");
|
79
76
|
}
|
80
77
|
|
81
78
|
private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
|
@@ -121,11 +118,8 @@
|
|
121
118
|
}
|
122
119
|
endExclusive = endExclusive.plusDays(7); //+一週間
|
123
120
|
//start から endExclusive まで
|
124
|
-
Log.d("MonthFragment", "start="+start);
|
125
|
-
Log.d("MonthFragment", "endExclusive="+endExclusive);
|
126
121
|
list.clear();
|
127
122
|
for(LocalDate target=start; target.compareTo(endExclusive) < 0; target=target.plusDays(1)) {
|
128
|
-
Log.d("MonthFragment", "target="+target);
|
129
123
|
list.add(target);
|
130
124
|
}
|
131
125
|
}
|
3
コード追加
test
CHANGED
@@ -26,3 +26,247 @@
|
|
26
26
|
フラグメントの onViewCreated の第一パラメータ view が onCreateView が返した View そのものですので、そのビューから findViewById で得なければならないでしょう。(`view.findViewById(R.id.year);`)
|
27
27
|
|
28
28
|
アクティビティにアタッチしていればビュー階層的にはアクティビティにも属している形になるのでこれでも動くようですが、本来フラグメントはそれ単体で完結するものです。ボタンのクリック処理もフラグメントに書くべきです。
|
29
|
+
|
30
|
+
---
|
31
|
+
アダプタが分かりませんが想像で追加、フラグメントで完結するようにしました。
|
32
|
+
アクティビティは onCreate でフラグメントを配置するだけなので省略です。
|
33
|
+
Calendar は扱い難いので LocalDate に変更、年月の表示は Adapter の更新を受ける形とし、今日の日は描画時に背景色を変えています。
|
34
|
+
|
35
|
+
MonthFragment.java
|
36
|
+
```java
|
37
|
+
import android.annotation.SuppressLint;
|
38
|
+
import android.graphics.Color;
|
39
|
+
import android.os.Bundle;
|
40
|
+
import android.util.Log;
|
41
|
+
import android.view.*;
|
42
|
+
import android.widget.*;
|
43
|
+
|
44
|
+
import androidx.annotation.*;
|
45
|
+
import androidx.fragment.app.*;
|
46
|
+
import androidx.recyclerview.widget.*;
|
47
|
+
|
48
|
+
import java.time.*;
|
49
|
+
import java.util.*;
|
50
|
+
import java.util.function.Consumer;
|
51
|
+
|
52
|
+
public class MonthFragment extends Fragment {
|
53
|
+
MonthFragment() {
|
54
|
+
super(R.layout.month_fragment);
|
55
|
+
}
|
56
|
+
|
57
|
+
@Override
|
58
|
+
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
59
|
+
Log.d("MonthFragment", "onViewCreated");
|
60
|
+
TextView yearText = view.findViewById(R.id.year);
|
61
|
+
TextView monthText = view.findViewById(R.id.month);
|
62
|
+
|
63
|
+
Adapter adapter = new Adapter(date -> {
|
64
|
+
yearText.setText(date.getYear() + "年");
|
65
|
+
monthText.setText(date.getMonthValue() + "月");
|
66
|
+
});
|
67
|
+
|
68
|
+
Button prevButton = view.findViewById(R.id.prev);
|
69
|
+
prevButton.setOnClickListener(v -> adapter.prev());
|
70
|
+
|
71
|
+
Button nextButton = view.findViewById(R.id.next);
|
72
|
+
nextButton.setOnClickListener(v -> adapter.next());
|
73
|
+
|
74
|
+
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
|
75
|
+
recyclerView.setHasFixedSize(true);
|
76
|
+
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 7));
|
77
|
+
recyclerView.setAdapter(adapter);
|
78
|
+
Log.d("MonthFragment", "onViewCreated end");
|
79
|
+
}
|
80
|
+
|
81
|
+
private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
|
82
|
+
private Consumer<LocalDate> dateChangeListener;
|
83
|
+
|
84
|
+
private DayOfWeek weekFirst = DayOfWeek.SUNDAY; //日曜日始まり
|
85
|
+
private LocalDate current;
|
86
|
+
private List<LocalDate> list = new ArrayList<>();
|
87
|
+
|
88
|
+
Adapter(@NonNull Consumer<LocalDate> dateChangeListener) {
|
89
|
+
this.dateChangeListener = dateChangeListener;
|
90
|
+
|
91
|
+
setDate(LocalDate.now().withDayOfMonth(1));
|
92
|
+
}
|
93
|
+
|
94
|
+
void next() {
|
95
|
+
setDate(current.plusMonths(1));
|
96
|
+
}
|
97
|
+
|
98
|
+
void prev() {
|
99
|
+
setDate(current.minusMonths(1));
|
100
|
+
}
|
101
|
+
|
102
|
+
@SuppressLint("NotifyDataSetChanged")
|
103
|
+
private void setDate(LocalDate date) {
|
104
|
+
this.current = date;
|
105
|
+
generateDayList(current.getYear(), current.getMonthValue());
|
106
|
+
notifyDataSetChanged();
|
107
|
+
if(dateChangeListener != null) dateChangeListener.accept(current);
|
108
|
+
}
|
109
|
+
|
110
|
+
private void generateDayList(int year, int month) {
|
111
|
+
LocalDate first = LocalDate.of(year, month, 1);
|
112
|
+
//月初の直前の週始め
|
113
|
+
LocalDate start = first;
|
114
|
+
while(start.getDayOfWeek() != weekFirst) {
|
115
|
+
start = start.minusDays(1);
|
116
|
+
}
|
117
|
+
//最終日直後の週始め
|
118
|
+
LocalDate endExclusive = first.plusMonths(1);
|
119
|
+
while(endExclusive.getDayOfWeek() != weekFirst) {
|
120
|
+
endExclusive = endExclusive.plusDays(1);
|
121
|
+
}
|
122
|
+
endExclusive = endExclusive.plusDays(7); //+一週間
|
123
|
+
//start から endExclusive まで
|
124
|
+
Log.d("MonthFragment", "start="+start);
|
125
|
+
Log.d("MonthFragment", "endExclusive="+endExclusive);
|
126
|
+
list.clear();
|
127
|
+
for(LocalDate target=start; target.compareTo(endExclusive) < 0; target=target.plusDays(1)) {
|
128
|
+
Log.d("MonthFragment", "target="+target);
|
129
|
+
list.add(target);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
@NonNull
|
134
|
+
@Override
|
135
|
+
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
136
|
+
return new ViewHolder(parent);
|
137
|
+
}
|
138
|
+
|
139
|
+
@Override
|
140
|
+
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
141
|
+
holder.bind(list.get(position));
|
142
|
+
}
|
143
|
+
|
144
|
+
@Override
|
145
|
+
public int getItemCount() {
|
146
|
+
return list.size();
|
147
|
+
}
|
148
|
+
|
149
|
+
class ViewHolder extends RecyclerView.ViewHolder {
|
150
|
+
private TextView day;
|
151
|
+
ViewHolder(ViewGroup parent) {
|
152
|
+
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_day, parent, false));
|
153
|
+
day = itemView.findViewById(R.id.day);
|
154
|
+
}
|
155
|
+
void bind(LocalDate date) {
|
156
|
+
day.setTextColor(
|
157
|
+
date.getMonth() != current.getMonth() ? Color.LTGRAY : //前月・次月
|
158
|
+
date.getDayOfWeek() == DayOfWeek.SUNDAY ? Color.RED : //日曜
|
159
|
+
date.getDayOfWeek() == DayOfWeek.SATURDAY ? Color.BLUE : //土曜
|
160
|
+
Color.BLACK); //通常
|
161
|
+
day.setBackgroundColor(date.compareTo(LocalDate.now()) == 0 ? Color.CYAN : Color.WHITE); //今日
|
162
|
+
day.setText("" + date.getDayOfMonth());
|
163
|
+
}
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
```
|
168
|
+
res/layout/month_fragment.xml
|
169
|
+
```xml
|
170
|
+
<?xml version="1.0" encoding="utf-8"?>
|
171
|
+
<androidx.constraintlayout.widget.ConstraintLayout
|
172
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
173
|
+
xmlns:app="http://schemas.android.com/apk/res-auto"
|
174
|
+
android:layout_width="match_parent"
|
175
|
+
android:layout_height="match_parent">
|
176
|
+
|
177
|
+
<TextView
|
178
|
+
android:id="@+id/year"
|
179
|
+
android:layout_width="wrap_content"
|
180
|
+
android:layout_height="wrap_content"
|
181
|
+
android:text="year"
|
182
|
+
app:layout_constraintEnd_toEndOf="parent"
|
183
|
+
app:layout_constraintStart_toStartOf="parent"
|
184
|
+
app:layout_constraintTop_toTopOf="parent" />
|
185
|
+
|
186
|
+
<Space
|
187
|
+
android:id="@+id/year_bottom"
|
188
|
+
android:layout_width="0dp"
|
189
|
+
android:layout_height="32dp"
|
190
|
+
app:layout_constraintEnd_toEndOf="parent"
|
191
|
+
app:layout_constraintStart_toStartOf="parent"
|
192
|
+
app:layout_constraintTop_toBottomOf="@id/year" />
|
193
|
+
|
194
|
+
<Button
|
195
|
+
android:id="@+id/prev"
|
196
|
+
style="?android:attr/borderlessButtonStyle"
|
197
|
+
android:layout_width="wrap_content"
|
198
|
+
android:layout_height="wrap_content"
|
199
|
+
android:backgroundTint="@color/white"
|
200
|
+
android:text="prev"
|
201
|
+
android:textColor="@color/black"
|
202
|
+
android:textSize="24sp"
|
203
|
+
app:layout_constraintBottom_toTopOf="@id/header_bottom"
|
204
|
+
app:layout_constraintEnd_toStartOf="@id/month"
|
205
|
+
app:layout_constraintTop_toBottomOf="@id/year_bottom" />
|
206
|
+
|
207
|
+
<TextView
|
208
|
+
android:id="@+id/month"
|
209
|
+
android:layout_width="100dp"
|
210
|
+
android:layout_height="wrap_content"
|
211
|
+
android:text="month"
|
212
|
+
android:textSize="24sp"
|
213
|
+
android:textAlignment="center"
|
214
|
+
app:layout_constraintBottom_toTopOf="@id/header_bottom"
|
215
|
+
app:layout_constraintEnd_toEndOf="parent"
|
216
|
+
app:layout_constraintStart_toStartOf="parent"
|
217
|
+
app:layout_constraintTop_toBottomOf="@id/year_bottom" />
|
218
|
+
|
219
|
+
<Button
|
220
|
+
android:id="@+id/next"
|
221
|
+
style="?android:attr/borderlessButtonStyle"
|
222
|
+
android:layout_width="wrap_content"
|
223
|
+
android:layout_height="wrap_content"
|
224
|
+
android:backgroundTint="@color/white"
|
225
|
+
android:text="next"
|
226
|
+
android:textColor="@color/black"
|
227
|
+
android:textSize="24sp"
|
228
|
+
app:layout_constraintBottom_toTopOf="@id/header_bottom"
|
229
|
+
app:layout_constraintStart_toEndOf="@id/month"
|
230
|
+
app:layout_constraintTop_toBottomOf="@id/year_bottom"/>
|
231
|
+
|
232
|
+
<androidx.constraintlayout.widget.Barrier
|
233
|
+
android:id="@+id/header_bottom"
|
234
|
+
android:layout_width="0dp"
|
235
|
+
android:layout_height="0dp"
|
236
|
+
app:barrierDirection="bottom"
|
237
|
+
app:constraint_referenced_ids="prev, month, next" />
|
238
|
+
|
239
|
+
<androidx.recyclerview.widget.RecyclerView
|
240
|
+
android:id="@+id/recycler_view"
|
241
|
+
android:layout_width="0dp"
|
242
|
+
android:layout_height="wrap_content"
|
243
|
+
app:layout_constraintBottom_toBottomOf="parent"
|
244
|
+
app:layout_constraintEnd_toEndOf="parent"
|
245
|
+
app:layout_constraintStart_toStartOf="parent"
|
246
|
+
app:layout_constraintTop_toBottomOf="@id/header_bottom" />
|
247
|
+
|
248
|
+
</androidx.constraintlayout.widget.ConstraintLayout>
|
249
|
+
```
|
250
|
+
res/layout/grid_day.xml
|
251
|
+
```xml
|
252
|
+
<?xml version="1.0" encoding="utf-8"?>
|
253
|
+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
254
|
+
android:layout_width="match_parent"
|
255
|
+
android:layout_height="wrap_content"
|
256
|
+
xmlns:app="http://schemas.android.com/apk/res-auto">
|
257
|
+
|
258
|
+
<TextView
|
259
|
+
android:id="@+id/day"
|
260
|
+
android:layout_width="0dp"
|
261
|
+
android:layout_height="wrap_content"
|
262
|
+
android:text="21"
|
263
|
+
android:textSize="30sp"
|
264
|
+
android:textAlignment="center"
|
265
|
+
app:layout_constraintEnd_toEndOf="parent"
|
266
|
+
app:layout_constraintStart_toStartOf="parent"
|
267
|
+
app:layout_constraintTop_toTopOf="parent" />
|
268
|
+
|
269
|
+
</androidx.constraintlayout.widget.ConstraintLayout>
|
270
|
+
```
|
271
|
+
![起動時(1月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/70f2e1ae-47cf-4f77-8e7f-1214a9bf932e.png)
|
272
|
+
![next押下時(2月)スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-23/149202ea-11d4-4838-8109-eed338dd84e7.png)
|
2
追記
test
CHANGED
@@ -20,3 +20,9 @@
|
|
20
20
|
```
|
21
21
|
としなければならないでしょう。
|
22
22
|
|
23
|
+
---
|
24
|
+
動作確認しようとコードをコピペして見ていますが…フラグメントのレイアウトなのに
|
25
|
+
アクティビティで findViewById しています。(`activity.findViewById(R.id.year);`)
|
26
|
+
フラグメントの onViewCreated の第一パラメータ view が onCreateView が返した View そのものですので、そのビューから findViewById で得なければならないでしょう。(`view.findViewById(R.id.year);`)
|
27
|
+
|
28
|
+
アクティビティにアタッチしていればビュー階層的にはアクティビティにも属している形になるのでこれでも動くようですが、本来フラグメントはそれ単体で完結するものです。ボタンのクリック処理もフラグメントに書くべきです。
|
1
マークダウン修正
test
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
monthFragment.plus();
|
15
15
|
}
|
16
16
|
```
|
17
|
-
これでは、 plus を実行するフラグメントオブジェクトと画面に表示しているフラグメントオブジェクトは *違うモノ* です。
|
17
|
+
これでは、 plus を実行するフラグメントオブジェクトと画面に表示しているフラグメントオブジェクトは **違うモノ** です。
|
18
18
|
```
|
19
19
|
.add(R.id.month_fragment_container, monthFragment)
|
20
20
|
```
|