diff --git a/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java b/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java index 183e544..62ed1f3 100644 --- a/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java @@ -45,8 +45,7 @@ private final List userActivityStatusChangeListeners; - private final List sortedFriendUserIds = new ArrayList<>(); - + private final MutableLiveData> sortedFriendUserIdsLiveData = new MutableLiveData<>(); /** * ActivityのViewModelを作成する。 @@ -117,8 +116,12 @@ public void onSuccess(Activity activity) { updateFriendToActivitiesLiveData(activity, userId); - // NOTE: 毎秒呼ばれるけど動いているので気にしない - sortFriendsByUpdateTime(friendUserIds); + // 変更があった場合、フレンドのユーザーIDを並び替えて更新する + List prevSortedFriendIds = sortedFriendUserIdsLiveData.getValue(); + List sortedFriendIds = sortFriendsByUpdateTime(friendUserIds); + if (prevSortedFriendIds == null || !prevSortedFriendIds.equals(sortedFriendIds)) { + sortedFriendUserIdsLiveData.postValue(sortedFriendIds); + } } @Override @@ -272,9 +275,14 @@ if (friendUserIds == null || !friendUserIds.equals(response.body())) { friendUserIdsLiveData.postValue(response.body()); - // NOTE: 毎秒呼ばれるけど動いているので気にしない - assert friendUserIds != null; - sortFriendsByUpdateTime(friendUserIds); + // 変更があった場合、フレンドのユーザーIDを並び替えて更新する + if (friendUserIds != null) { + List prevSortedFriendIds = sortedFriendUserIdsLiveData.getValue(); + List sortedFriendIds = sortFriendsByUpdateTime(friendUserIds); + if (prevSortedFriendIds == null || !prevSortedFriendIds.equals(sortedFriendIds)) { + sortedFriendUserIdsLiveData.postValue(sortedFriendIds); + } + } } } } @@ -291,7 +299,8 @@ * * @param friendUserIds 自身のフレンドのユーザーIDのリスト */ - private void sortFriendsByUpdateTime(List friendUserIds) { + private List sortFriendsByUpdateTime(List friendUserIds) { + List friendIds = new ArrayList<>(); SortedSet friends = new TreeSet<>(new Friend.UpdateTimeComparator()); friendUserIds.forEach(userId -> { @@ -304,9 +313,8 @@ friends.add(new Friend(userId, latestActivity.getUpdateTime())); }); - // 並び替えたフレンドのユーザーIDを順番に格納して更新する - sortedFriendUserIds.clear(); - friends.forEach(friend -> sortedFriendUserIds.add(friend.getUserId())); + friends.forEach(friend -> friendIds.add(friend.getUserId())); + return friendIds; } public MutableLiveData getMyLatestActivityLiveData() { @@ -342,8 +350,8 @@ return myToken; } - public List getSortedFriendUserIds() { - return sortedFriendUserIds; + public MutableLiveData> getSortedFriendUserIdsLiveData() { + return sortedFriendUserIdsLiveData; } public void addActivityStatusChangeObserver(UserActivityStatusChangeListener observer) { diff --git a/app/src/main/java/com/example/tampopo_client/views/MainActivity.java b/app/src/main/java/com/example/tampopo_client/views/MainActivity.java index cd5d3b3..5f91723 100644 --- a/app/src/main/java/com/example/tampopo_client/views/MainActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/MainActivity.java @@ -18,7 +18,6 @@ import android.widget.LinearLayout; import androidx.activity.EdgeToEdge; -import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; @@ -28,14 +27,12 @@ import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; -import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import com.bumptech.glide.Glide; import com.example.tampopo_client.R; import com.example.tampopo_client.Tampopo; -import com.example.tampopo_client.models.Activity; import com.example.tampopo_client.viewmodels.ActivityViewModel; import com.example.tampopo_client.viewmodels.ActivityViewModelFactory; import com.example.tampopo_client.viewmodels.ChatViewModel; @@ -72,6 +69,7 @@ private ChatViewModel chatViewModel; private final List recentUpdatedFriends = new ArrayList<>(); // 最新6人 + private final Map friendIconViewMap = new HashMap<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -141,57 +139,202 @@ } }); + /* + * FriendIconViewを作成して、画面に配置する + */ + ConstraintLayout parent = findViewById(R.id.main); + for (int i = 0; i < 6; i++) { + int marginTopInPx = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + marginTopInDp[i], + getResources().getDisplayMetrics() + ); + int marginStartInPx = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + marginStartInDp[i], + getResources().getDisplayMetrics() + ); - MutableLiveData> friendsLiveData = activityViewModel.getFriendUserIdsLiveData(); + createFriendIconView(i, null, marginTopInPx, marginStartInPx, parent); + } - friendsLiveData.observe(this, new Observer>() { + /* + * 変更があったときに、FriendIconViewを更新する (2, 3) + */ + activityViewModel.getSortedFriendUserIdsLiveData().observe(this, new Observer>() { @Override - public void onChanged(List friends) { - // フレンドの追加と削除 - updateActivityView(friends); + public void onChanged(List friendUserIds) { + Log.d("SortedFriendUserIds", "フレンドIDが更新されました。"); + + // 元の配列に影響を与えないようにコピーする + List latestFriendUseIds = new ArrayList<>(); + for (String friendUserId : friendUserIds) { + latestFriendUseIds.add(String.valueOf(friendUserId)); + } + + // ユーザーの数を6人まで制限する + if (latestFriendUseIds.size() > 6) { + latestFriendUseIds.subList(6, latestFriendUseIds.size()).clear(); + } + + // 各FriendIconViewの表示を切り替える + int prevFriendUserCount = recentUpdatedFriends.size(); + int latestFriendUserCount = latestFriendUseIds.size(); + if (prevFriendUserCount != latestFriendUserCount) { + if (prevFriendUserCount > latestFriendUserCount) { + for (int i = latestFriendUserCount; i < prevFriendUserCount; i++) { + FriendIconView friendIconView = friendIconViewMap.get(i); + assert friendIconView != null; + + friendIconView.setVisibility(View.GONE); + } + } else { + for (int i = prevFriendUserCount; i < latestFriendUserCount; i++) { + FriendIconView friendIconView = friendIconViewMap.get(i); + assert friendIconView != null; + + friendIconView.setVisibility(View.VISIBLE); + } + } + } + + // 0, 以前のユーザーのObserveを停止する + for (int i = 0; i < recentUpdatedFriends.size(); i++) { + String friendUserId = recentUpdatedFriends.get(i); + FriendIconView friendIconView = friendIconViewMap.get(i); + assert friendIconView != null; + + activityViewModel.getActivitiesLiveDataFromUserId(friendUserId).removeObserver(friendIconView.getActivitiesObserver()); + } + + // 1. recentUpdatedFriendsを更新する + recentUpdatedFriends.clear(); + recentUpdatedFriends.addAll(latestFriendUseIds); + + // 2. FriendIconViewを更新する + for (int i = 0; i < recentUpdatedFriends.size(); i++) { + FriendIconView friendIconView = friendIconViewMap.get(i); + assert friendIconView != null; + + String friendId = recentUpdatedFriends.get(i); + if (friendId == null) { + friendIconView.setVisibility(View.INVISIBLE); + } else { + friendIconView.setVisibility(View.VISIBLE); + new Thread(new Runnable() { + @Override + public void run() { + String nickname = userViewModel.getNickname(friendId); + String iconUrl = userViewModel.getFriendIcon(friendId); + + Looper looper = Looper.getMainLooper(); + Handler handler = new Handler(looper); + handler.post(new Runnable() { + @Override + public void run() { + // FriendIconView.setUserId()でFriendIconViewが使用するユーザーIDを更新する + friendIconView.setFriendUserId(friendId); + + // FriendIconView.setNickname()でFriendIconViewが使用するニックネームを更新する + friendIconView.setNickname(nickname); + + // FriendIconView.setIcon()でFriendIconViewが使用するアイコンURLを更新する + friendIconView.setIconUrl(iconUrl); + + // 各FriendIconViewにActivityをobserveさせる + activityViewModel.getActivitiesLiveDataFromUserId(friendId).observe(MainActivity.this, friendIconView.getActivitiesObserver()); + } + }); + } + }).start(); + } + } } }); - //アクティビティを投稿した人がアクティビティを更新しないか監視する - //なにかをクリックしたらここに飛んでくる - for (String friendId : userViews.keySet()) { - //final String updateFriendId = friendId; - MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(friendId); - //MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(updateFriendId); - //FriendIconView friendView = userViews.get(friendId); - //if (friendView == null) continue; +// MutableLiveData> friendsLiveData = activityViewModel.getFriendUserIdsLiveData(); - activitiesLiveData.observeForever(new Observer>() { - //アクティビティを更新したらonChangedが呼び出される - @Override - public void onChanged(List activities) { - // 更新したフレンドの再登場,更新してないフレンドの退場 - //更新した人を見つけてFriendIconViewを呼び出して、 - List sortedFriendUserIds = activityViewModel.getSortedFriendUserIds();//アクティビティを更新した最新6人のリスト -// FriendIconView userView = userViews.get(friendId); -// if (userView != null && activities != null && !activities.isEmpty()) { -// //latestは最新のアクティビティを保持する -// Activity latest = activities.get(activities.size() - 1); +// friendsLiveData.observe(this, new Observer>() { +// @Override//2 +// public void onChanged(List friends) { +// // フレンドの追加と削除 +//// updateActivityView(friends); +// } +// }); + +// //アクティビティを投稿した人がアクティビティを更新しないか監視する +// //なにかをクリックしたらここに飛んでくる +// for (String friendId : userViews.keySet()) { +// //final String updateFriendId = friendId; +// MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(friendId); +// //MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(updateFriendId); +// +// //FriendIconView friendView = userViews.get(friendId); +// //if (friendView == null) continue; +// +// +////natty もともと +//// activitiesLiveData.observeForever(new Observer>() { +//// //アクティビティを更新したらonChangedが呼び出される +//// @Override +//// public void onChanged(List activities) { +//// // 更新したフレンドの再登場,更新してないフレンドの退場 +//// //更新した人を見つけてFriendIconViewを呼び出して、 +//// List sortedFriendUserIds = activityViewModel.getSortedFriendUserIds();//アクティビティを更新した最新6人のリスト +////// FriendIconView userView = userViews.get(friendId); +////// if (userView != null && activities != null && !activities.isEmpty()) { +////// //latestは最新のアクティビティを保持する +////// Activity latest = activities.get(activities.size() - 1); +////// } +////// // 最新更新フレンドをリストに追加(最大6人保持) +//// int size = sortedFriendUserIds.size(); +//// List latestSix = sortedFriendUserIds.subList(Math.max(size - 6, 0), size); +//// +//// synchronized (recentUpdatedFriends) { +//// if (latestSix.contains(friendId)) { +//// recentUpdatedFriends.remove(friendId); +//// recentUpdatedFriends.add(0, friendId); +//// if (recentUpdatedFriends.size() > 6) { +//// recentUpdatedFriends.remove(recentUpdatedFriends.size() - 1); +//// } +//// } +//// } +//////スレッド処理をいれて更新できるようにする +//// } +// //}); +// +// //natty かきかえご +// activitiesLiveData.observe(this, activities -> { +// if (activities == null || activities.isEmpty()) return; +// +// // 最新のアクティビティを取得 +// Activity latest = activities.get(activities.size() - 1); +// +// // コメントを更新 +// FriendIconView friendView = userViews.get(friendId); +// if (friendView != null) { +// friendView.setComment(latest.getText()); +// } +// +// // 並び順を更新 +// synchronized (recentUpdatedFriends) { +// recentUpdatedFriends.remove(friendId); +// recentUpdatedFriends.add(0, friendId); +// if (recentUpdatedFriends.size() > 6) { +// recentUpdatedFriends.remove(recentUpdatedFriends.size() - 1); // } -// // 最新更新フレンドをリストに追加(最大6人保持) - int size = sortedFriendUserIds.size(); - List latestSix = sortedFriendUserIds.subList(Math.max(size - 6, 0), size); +// } +// +// // 🔥 並び替えた最新リストでUIを更新 +// //TODO: 3 +// runOnUiThread(() -> updateActivityView(recentUpdatedFriends)); +// }); +// //////////////////// +// - synchronized (recentUpdatedFriends) { - if (latestSix.contains(friendId)) { - recentUpdatedFriends.remove(friendId); - recentUpdatedFriends.add(0, friendId); - if (recentUpdatedFriends.size() > 6) { - recentUpdatedFriends.remove(recentUpdatedFriends.size() - 1); - } - } - } -//スレッド処理をいれて更新できるようにする - } - }); - } +// } // for (String friendId : userViews.keySet()) { @@ -351,180 +494,221 @@ dialog.show(); } - //natty 仮のフレンド情報 - private int getUserIconResource(String userId) { - switch (userId) { - case "user01": - return R.drawable.friend01_icon; - case "user02": - return R.drawable.friend04_icon; - case "user03": - return R.drawable.friend03_icon; - default: - return R.drawable.default_icon; - } - } +// //natty 仮のフレンド情報 +// private int getUserIconResource(String userId) { +// switch (userId) { +// case "user01": +// return R.drawable.friend01_icon; +// case "user02": +// return R.drawable.friend04_icon; +// case "user03": +// return R.drawable.friend03_icon; +// default: +// return R.drawable.default_icon; +// } +// } - private void setupActivityObservers(List sortedFriendUserIds) { - for (String friendId : sortedFriendUserIds) { - FriendIconView userView = userViews.get(friendId); - if (userView == null) { - Log.w("MainActivity", "userViews に存在しません: " + friendId); - continue; - } - - MutableLiveData> activitiesLiveData = - activityViewModel.getActivitiesLiveDataFromUserId(friendId); - - activitiesLiveData.observeForever(new Observer>() { - @Override - public void onChanged(List activities) { - if (activities == null || activities.isEmpty()) return; - - Activity latest = activities.get(activities.size() - 1); - Log.d("ActivityUpdate", friendId + " 最新: " + latest.getText()); - - // FriendIconView の更新 - //userView.setComment(latest.getText()); - - // 最近更新したフレンドリストを更新(最大6人) - synchronized (sortedFriendUserIds) { - sortedFriendUserIds.remove(friendId); - sortedFriendUserIds.add(0, friendId); - - if (sortedFriendUserIds.size() > 6) { - sortedFriendUserIds.remove(sortedFriendUserIds.size() - 1); - } - } - - // 並び順をログ出力(デバッグ用) - Log.d("RecentFriends", "最新更新順: " + sortedFriendUserIds); - } - }); - } - } - - private void updateActivityView(@NonNull List friends) { - ///natty ユーザごとにコメントの更新をする - LinearLayout messageList = findViewById(R.id.messageList); - ConstraintLayout layout = findViewById(R.id.main); - - for (String friendId : friends) { - FriendIconView userView = userViews.get(friendId); - //userViews.put(friendId, null); - MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(friendId); - +// private void setupActivityObservers(List sortedFriendUserIds) { // for (String friendId : sortedFriendUserIds) { // FriendIconView userView = userViews.get(friendId); -// MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(friendId); - //nattyもしnullだったらって処理入れた気がする // if (userView == null) { -// userView = new FriendIconView( -// MainActivity.this, -// friendId, -// userViewModel.getNickname(friendId), -// chatViewModel -// ); -// userViews.put(friendId, userView); +// Log.w("MainActivity", "userViews に存在しません: " + friendId); +// continue; // } - // 新しいユーザなので、アイコン+コメントを作成 - //FriendIconView container = new FriendIconView(this); +// +// MutableLiveData> activitiesLiveData = +// activityViewModel.getActivitiesLiveDataFromUserId(friendId); +// +// activitiesLiveData.observeForever(new Observer>() { +// @Override +// public void onChanged(List activities) { +// if (activities == null || activities.isEmpty()) return; +// +// Activity latest = activities.get(activities.size() - 1); +// Log.d("ActivityUpdate", friendId + " 最新: " + latest.getText()); +// +// // FriendIconView の更新 +// //userView.setComment(latest.getText()); +// +// // 最近更新したフレンドリストを更新(最大6人) +// synchronized (sortedFriendUserIds) { +// sortedFriendUserIds.remove(friendId); +// sortedFriendUserIds.add(0, friendId); +// +// if (sortedFriendUserIds.size() > 6) { +// sortedFriendUserIds.remove(sortedFriendUserIds.size() - 1); +// } +// } +// +// // 並び順をログ出力(デバッグ用) +// Log.d("RecentFriends", "最新更新順: " + sortedFriendUserIds); +// } +// }); +// } +// } + +// private void updateActivityView(@NonNull List friends) { +// ///natty ユーザごとにコメントの更新をする +// LinearLayout messageList = findViewById(R.id.messageList); +// ConstraintLayout layout = findViewById(R.id.main); +// +// for (String friendId : friends) { +// FriendIconView userView = userViews.get(friendId); +// //userViews.put(friendId, null); +// MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(friendId); +// +//// for (String friendId : sortedFriendUserIds) { +//// FriendIconView userView = userViews.get(friendId); +//// MutableLiveData> activitiesLiveData = activityViewModel.getActivitiesLiveDataFromUserId(friendId); +// //nattyもしnullだったらって処理入れた気がする +//// if (userView == null) { +//// userView = new FriendIconView( +//// MainActivity.this, +//// friendId, +//// userViewModel.getNickname(friendId), +//// chatViewModel +//// ); +//// userViews.put(friendId, userView); +//// } +// // 新しいユーザなので、アイコン+コメントを作成 +// //FriendIconView container = new FriendIconView(this); +// +// +// if (userView == null) { +// new Thread(new Runnable() { +// @Override +// public void run() { +// FriendIconView container = new FriendIconView(MainActivity.this, friendId, userViewModel.getNickname(friendId), chatViewModel, userViewModel.getFriendIcon(friendId)); +// +// Handler handler = new Handler(Looper.getMainLooper()); +// handler.post(new Runnable() { +// @Override +// public void run() { +// container.setPadding(16, 16, 16, 16); +// container.setId(View.generateViewId()); +// +//// // ユーザのアイコン(固定) +//// ShapeableImageView iconView = new ShapeableImageView(MainActivity.this); +//// iconView.setLayoutParams(new LinearLayout.LayoutParams(100, 100)); +//// iconView.setScaleType(ImageView.ScaleType.CENTER_CROP); +//// iconView.setStrokeColor(ContextCompat.getColorStateList(MainActivity.this, R.color.red)); +//// iconView.setStrokeWidth(2f); +//// iconView.setShapeAppearanceModel( +//// iconView.getShapeAppearanceModel().toBuilder() +//// .setAllCornerSizes(50) // 丸く +//// .build() +//// ); +// ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams( +// ConstraintLayout.LayoutParams.WRAP_CONTENT, +// ConstraintLayout.LayoutParams.WRAP_CONTENT +// ); +// container.setLayoutParams(params); +// layout.addView(container); +//// +//// // ユーザIDに応じてアイコンリソースを決定(仮にハードコード or マッピング) +//// iconView.setImageResource(getUserIconResource(friendId)); // ←ここがポイント +// +// // Mapに登録、画面に追加 +// userViews.put(friendId, container); +//// userView = container; +//// messageList.addView(container); +// +// ConstraintSet set = new ConstraintSet(); +// set.clone(layout); +// int marginTopInPx = (int) TypedValue.applyDimension( +// TypedValue.COMPLEX_UNIT_DIP, +// marginTopInDp[i], +// getResources().getDisplayMetrics() +// ); +// int marginStartInPx = (int) TypedValue.applyDimension( +// TypedValue.COMPLEX_UNIT_DIP, +// marginStartInDp[i], +// getResources().getDisplayMetrics() +// ); +// +// set.connect(container.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, marginTopInPx); +// set.connect(container.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, marginStartInPx); +// +// set.applyTo(layout); +// +// if (i < 6) { +// i++; +// } +// +// // TODO: CHANGE +// activitiesLiveData.observe(MainActivity.this, activities -> { +// if (activities == null || activities.isEmpty()) return; +// +// Activity latest = activities.get(activities.size() - 1); +// +// // UIスレッドで安全に更新 +// FriendIconView friendView = userViews.get(friendId); +// if (friendView != null) { +// friendView.setComment(latest.getText()); +// Log.d("ActivityUpdate", friendId + " のコメントを更新: " + latest.getText()); +// } +// }); +// +//// List sortedFriendUserIds = activityViewModel.getSortedFriendUserIds(); +//// int size = sortedFriendUserIds.size(); +//// List latestSix = sortedFriendUserIds.subList(Math.max(size - 6, 0), size); +//// +//// synchronized (recentUpdatedFriends) { +//// if (latestSix.contains(friendId)) { +//// recentUpdatedFriends.remove(friendId); +//// recentUpdatedFriends.add(0, friendId); +//// if (recentUpdatedFriends.size() > 6) { +//// recentUpdatedFriends.remove(recentUpdatedFriends.size() - 1); +//// } +//// } +//// } +// } +// }); +// } +// }).start(); +// } +// } +// } - if(userView == null) { - new Thread(new Runnable() { + private void createFriendIconView(int index, String userId, int topMarginInPx, int startMarginInPx, ConstraintLayout parent) { + new Thread(new Runnable() { + @Override + public void run() { + String nickname = userId != null ? userViewModel.getNickname(userId) : null; + String iconUrl = userId != null ? userViewModel.getFriendIcon(userId) : null; + // TODO: userId, iconUrl, nicknameがnullのときやばくない? + FriendIconView friendIconView = new FriendIconView(MainActivity.this, userId, nickname, chatViewModel, iconUrl); + friendIconViewMap.put(index, friendIconView); + + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { @Override public void run() { - FriendIconView container = new FriendIconView(MainActivity.this, friendId, userViewModel.getNickname(friendId), chatViewModel, userViewModel.getFriendIcon(friendId)); + friendIconView.setVisibility(View.GONE); + friendIconView.setPadding(16, 16, 16, 16); + friendIconView.setId(View.generateViewId()); - Handler handler = new Handler(Looper.getMainLooper()); - handler.post(new Runnable() { - @Override - public void run() { - container.setPadding(16, 16, 16, 16); - container.setId(View.generateViewId()); + ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams( + ConstraintLayout.LayoutParams.WRAP_CONTENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ); + friendIconView.setLayoutParams(params); + parent.addView(friendIconView); -// // ユーザのアイコン(固定) -// ShapeableImageView iconView = new ShapeableImageView(MainActivity.this); -// iconView.setLayoutParams(new LinearLayout.LayoutParams(100, 100)); -// iconView.setScaleType(ImageView.ScaleType.CENTER_CROP); -// iconView.setStrokeColor(ContextCompat.getColorStateList(MainActivity.this, R.color.red)); -// iconView.setStrokeWidth(2f); -// iconView.setShapeAppearanceModel( -// iconView.getShapeAppearanceModel().toBuilder() -// .setAllCornerSizes(50) // 丸く -// .build() -// ); - ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams( - ConstraintLayout.LayoutParams.WRAP_CONTENT, - ConstraintLayout.LayoutParams.WRAP_CONTENT - ); - container.setLayoutParams(params); - layout.addView(container); -// -// // ユーザIDに応じてアイコンリソースを決定(仮にハードコード or マッピング) -// iconView.setImageResource(getUserIconResource(friendId)); // ←ここがポイント +// userViews.put(friendId, container); - // Mapに登録、画面に追加 - userViews.put(friendId, container); -// userView = container; -// messageList.addView(container); + ConstraintSet set = new ConstraintSet(); + set.clone(parent); - ConstraintSet set = new ConstraintSet(); - set.clone(layout); - int marginTopInPx = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - marginTopInDp[i], - getResources().getDisplayMetrics() - ); - int marginStartInPx = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - marginStartInDp[i], - getResources().getDisplayMetrics() - ); + set.connect(friendIconView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, topMarginInPx); + set.connect(friendIconView.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, startMarginInPx); - set.connect(container.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, marginTopInPx); - set.connect(container.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, marginStartInPx); - - set.applyTo(layout); - - if (i < 6) { - i++; - } - - // TODO: CHANGE - activitiesLiveData.observe(MainActivity.this, activities -> { - if (activities == null || activities.isEmpty()) return; - - Activity latest = activities.get(activities.size() - 1); - - // UIスレッドで安全に更新 - FriendIconView friendView = userViews.get(friendId); - if (friendView != null) { - friendView.setComment(latest.getText()); - Log.d("ActivityUpdate", friendId + " のコメントを更新: " + latest.getText()); - } - }); - - List sortedFriendUserIds = activityViewModel.getSortedFriendUserIds(); - int size = sortedFriendUserIds.size(); - List latestSix = sortedFriendUserIds.subList(Math.max(size - 6, 0), size); - - synchronized (recentUpdatedFriends) { - if (latestSix.contains(friendId)) { - recentUpdatedFriends.remove(friendId); - recentUpdatedFriends.add(0, friendId); - if (recentUpdatedFriends.size() > 6) { - recentUpdatedFriends.remove(recentUpdatedFriends.size() - 1); - } - } - } - } - }); + set.applyTo(parent); } - }).start(); + }); } - } + }).start(); } }