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 d8c9ac2..70132b7 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 @@ -9,6 +9,7 @@ import android.util.Log; import android.util.TypedValue; import android.view.View; +import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.Button; @@ -70,6 +71,7 @@ private ChatViewModel chatViewModel; private final List recentUpdatedFriends = new ArrayList<>(); // 最新6人 + private final Map friendIconViewMap = new HashMap<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -127,12 +129,69 @@ } }); + // 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() + ); + + createFriendIconView(i, null, marginTopInPx, marginStartInPx, parent); + } + + // 変更があったときに、FriendIconViewを更新する (2, 3) + activityViewModel.getSortedFriendUserIdsLiveData().observe(this, new Observer>() { + @Override + public void onChanged(List friendUserIds) { + Log.d("SortedFriendUserIds", "フレンドIDが更新されました。"); + + // 1. recentUpdatedFriendsを更新する + for (int i = 0; i < 6; i++) { + if (friendUserIds.get(i) != null) { + recentUpdatedFriends.set(i, friendUserIds.get(i)); + } + } + + for (int i = 0; i < 6; 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() { + //friendIconView.set(userViewModel.getIcon(friendId)); + friendIconView.setIconUrl(userViewModel.getIcon(friendId)); + friendIconView.setIconUrl(userViewModel.getIcon(friendId)); + } + }).start(); + + // TODO: 2. FriendIconView.setUserId()でFriendIconViewが使用するユーザーIDを更新する + // TODO: 3. FriendIconView.setIcon()でFriendIconViewが使用するアイコンURLを更新する + // TODO: 4. FriendIconView.setNickname()でFriendIconViewが使用するニックネームを更新する + } + + } + } + }); MutableLiveData> friendsLiveData = activityViewModel.getFriendUserIdsLiveData(); friendsLiveData.observe(this, new Observer>() { - @Override + @Override//2 public void onChanged(List friends) { // フレンドの追加と削除 updateActivityView(friends); @@ -150,8 +209,6 @@ //if (friendView == null) continue; - - //natty もともと // activitiesLiveData.observeForever(new Observer>() { // //アクティビティを更新したらonChangedが呼び出される @@ -205,6 +262,7 @@ } // 🔥 並び替えた最新リストでUIを更新 + //TODO: 3 runOnUiThread(() -> updateActivityView(recentUpdatedFriends)); }); //////////////////// @@ -454,7 +512,7 @@ new Thread(new Runnable() { @Override public void run() { - FriendIconView container = new FriendIconView(MainActivity.this, friendId, userViewModel.getNickname(friendId), chatViewModel,userViewModel.getIcon(friendId)); + FriendIconView container = new FriendIconView(MainActivity.this, friendId, userViewModel.getNickname(friendId), chatViewModel, userViewModel.getIcon(friendId)); Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @@ -485,6 +543,7 @@ // iconView.setImageResource(getUserIconResource(friendId)); // ←ここがポイント // Mapに登録、画面に追加 + //TODO: userViews.put(friendId, container); // userView = container; // messageList.addView(container); @@ -525,25 +584,64 @@ } }); - 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); - } - } - } +// List sortedFriendUserIds = activityViewModel.getSortedFriendUserIdsLiveData(); +// 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(); } } + + 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.getIcon(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.setPadding(16, 16, 16, 16); + friendIconView.setId(View.generateViewId()); + + ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams( + ConstraintLayout.LayoutParams.WRAP_CONTENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ); + friendIconView.setLayoutParams(params); + parent.addView(friendIconView); + +// userViews.put(friendId, container); + + ConstraintSet set = new ConstraintSet(); + set.clone(parent); + + 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.applyTo(parent); + } + }); + } + }).start(); + } } //プッシュ通知