Skip to content

Commit f75f81e

Browse files
committed
refactor(mods): rebuild switch-version dialog + rows to match native app UI patterns
1 parent de149a3 commit f75f81e

3 files changed

Lines changed: 172 additions & 204 deletions

File tree

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/InstalledModAdapter.java

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import androidx.annotation.NonNull;
2222
import androidx.annotation.Nullable;
2323
import androidx.appcompat.widget.SwitchCompat;
24-
import androidx.core.content.ContextCompat;
2524
import androidx.recyclerview.widget.LinearLayoutManager;
2625
import androidx.recyclerview.widget.RecyclerView;
2726

@@ -636,55 +635,45 @@ public int getItemCount() {
636635
}
637636

638637
static class RowHolder extends RecyclerView.ViewHolder {
639-
final View root;
640-
final TextView typeBadge, nameView, subtitleView, currentPill;
641-
final ImageView incompatibleIcon;
638+
final TextView nameView, subtitleView, currentLabel;
639+
final ImageView currentBadge, incompatibleIcon;
642640

643641
RowHolder(@NonNull View itemView) {
644642
super(itemView);
645-
root = itemView.findViewById(R.id.version_row_root);
646-
typeBadge = itemView.findViewById(R.id.version_row_type_badge);
647643
nameView = itemView.findViewById(R.id.version_row_name);
648644
subtitleView = itemView.findViewById(R.id.version_row_subtitle);
649-
currentPill = itemView.findViewById(R.id.version_row_current_pill);
645+
currentLabel = itemView.findViewById(R.id.version_row_current_pill);
646+
currentBadge = itemView.findViewById(R.id.version_row_current_badge);
650647
incompatibleIcon = itemView.findViewById(R.id.version_row_incompatible_icon);
651648
}
652649

653650
void bind(VersionRow row, OnVersionClickListener listener) {
654651
nameView.setText(row.versionNumber);
655652
subtitleView.setText(buildSubtitle(row));
656653

657-
String badgeLetter;
658-
int badgeColorRes;
659-
if ("beta".equalsIgnoreCase(row.releaseType)) {
660-
badgeLetter = "B"; badgeColorRes = R.color.mod_version_beta;
661-
} else if ("alpha".equalsIgnoreCase(row.releaseType)) {
662-
badgeLetter = "A"; badgeColorRes = R.color.mod_version_alpha;
663-
} else {
664-
badgeLetter = "R"; badgeColorRes = R.color.mod_version_release;
665-
}
666-
typeBadge.setText(badgeLetter);
667-
// mutate() first — this drawable resource is shared across rows,
668-
// and without it setTint() would tint every badge at once.
669-
typeBadge.getBackground().mutate()
670-
.setTint(ContextCompat.getColor(itemView.getContext(), badgeColorRes));
671-
672654
if (row.isCurrent) {
673-
currentPill.setVisibility(View.VISIBLE);
655+
currentLabel.setVisibility(View.VISIBLE);
656+
currentBadge.setVisibility(View.VISIBLE);
674657
incompatibleIcon.setVisibility(View.GONE);
675-
root.setBackgroundResource(R.drawable.bg_version_row_current);
676658
} else {
677-
currentPill.setVisibility(View.GONE);
659+
currentLabel.setVisibility(View.GONE);
660+
currentBadge.setVisibility(View.GONE);
678661
incompatibleIcon.setVisibility(row.isCompatible ? View.GONE : View.VISIBLE);
679-
root.setBackgroundResource(R.drawable.bg_version_row);
680662
}
681663

682664
itemView.setOnClickListener(v -> listener.onVersionClick(row));
683665
}
684666

685667
private static String buildSubtitle(VersionRow row) {
686668
StringBuilder sb = new StringBuilder();
687-
if (!row.loaders.isEmpty()) sb.append(capitalize(row.loaders.get(0)));
669+
// Release type as a plain word (Release / Beta / Alpha)
670+
if (row.releaseType != null && !row.releaseType.isEmpty()) {
671+
sb.append(capitalize(row.releaseType));
672+
}
673+
if (!row.loaders.isEmpty()) {
674+
if (sb.length() > 0) sb.append(" • ");
675+
sb.append(capitalize(row.loaders.get(0)));
676+
}
688677
if (!row.gameVersions.isEmpty()) {
689678
if (sb.length() > 0) sb.append(' ');
690679
sb.append(row.gameVersions.get(row.gameVersions.size() - 1));
Lines changed: 96 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,96 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<androidx.constraintlayout.widget.ConstraintLayout
3-
xmlns:android="http://schemas.android.com/apk/res/android"
4-
xmlns:app="http://schemas.android.com/apk/res-auto"
5-
xmlns:tools="http://schemas.android.com/tools"
2+
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
63
android:layout_width="match_parent"
74
android:layout_height="wrap_content"
8-
android:paddingHorizontal="@dimen/padding_heavy"
9-
android:paddingTop="@dimen/padding_heavy"
10-
android:paddingBottom="@dimen/padding_large">
11-
12-
<!-- Header -->
13-
<TextView
14-
android:id="@+id/switch_version_title"
15-
android:layout_width="0dp"
16-
android:layout_height="wrap_content"
17-
android:text="@string/switch_mod_version_title"
18-
android:textColor="?attr/colorTextPrimary"
19-
android:textStyle="bold"
20-
android:textSize="@dimen/_16ssp"
21-
app:layout_constraintStart_toStartOf="parent"
22-
app:layout_constraintTop_toTopOf="parent"
23-
app:layout_constraintEnd_toStartOf="@+id/switch_version_close"
24-
android:singleLine="true"
25-
android:ellipsize="end"
26-
tools:text="Switch version — Sodium" />
27-
28-
<ImageButton
29-
android:id="@+id/switch_version_close"
30-
android:layout_width="@dimen/_32sdp"
31-
android:layout_height="@dimen/_32sdp"
32-
android:background="?android:attr/selectableItemBackgroundBorderless"
33-
android:src="@drawable/ic_close"
34-
android:padding="@dimen/padding_small"
35-
android:contentDescription="@android:string/cancel"
36-
app:layout_constraintEnd_toEndOf="parent"
37-
app:layout_constraintTop_toTopOf="parent" />
38-
39-
<!-- Content area: progress / error / list are mutually exclusive siblings
40-
inside a single FIXED-height container. A fixed dp height (matching
41-
this codebase's existing dialog_expendable_list_view.xml pattern) is
42-
used deliberately instead of match_parent/0dp match-constraint —
43-
AlertDialog windows size themselves to wrap_content, which gives a
44-
match_parent/0dp list nothing definite to measure against and it
45-
collapses to zero height. A concrete height here sidesteps that
46-
entirely and matches how VersionSelectorDialog already solves the
47-
exact same problem elsewhere in this app. -->
48-
<FrameLayout
49-
android:id="@+id/switch_version_content"
5+
android:fillViewport="true">
6+
7+
<LinearLayout
508
android:layout_width="match_parent"
51-
android:layout_height="@dimen/_280sdp"
52-
android:layout_marginTop="@dimen/padding_large"
53-
app:layout_constraintTop_toBottomOf="@id/switch_version_title">
9+
android:layout_height="wrap_content"
10+
android:orientation="vertical"
11+
android:padding="@dimen/padding_large">
12+
13+
<!-- Header row: title + close button -->
14+
<LinearLayout
15+
android:layout_width="match_parent"
16+
android:layout_height="wrap_content"
17+
android:gravity="center_vertical"
18+
android:orientation="horizontal">
19+
20+
<TextView
21+
android:id="@+id/switch_version_title"
22+
android:layout_width="0dp"
23+
android:layout_height="wrap_content"
24+
android:layout_weight="1"
25+
android:text="@string/switch_mod_version_title"
26+
android:textColor="?attr/colorTextPrimary"
27+
android:textStyle="bold"
28+
android:textSize="@dimen/_16ssp"
29+
android:singleLine="true"
30+
android:ellipsize="end" />
5431

32+
<ImageButton
33+
android:id="@+id/switch_version_close"
34+
android:layout_width="@dimen/_32sdp"
35+
android:layout_height="@dimen/_32sdp"
36+
android:background="?android:attr/selectableItemBackgroundBorderless"
37+
android:src="@drawable/ic_close"
38+
android:padding="@dimen/padding_small"
39+
android:contentDescription="@android:string/cancel" />
40+
41+
</LinearLayout>
42+
43+
<!-- Toggle + warning above the list so they're always visible -->
44+
<LinearLayout
45+
android:layout_width="match_parent"
46+
android:layout_height="wrap_content"
47+
android:layout_marginTop="@dimen/padding_moderate"
48+
android:gravity="center_vertical"
49+
android:orientation="horizontal">
50+
51+
<TextView
52+
android:id="@+id/switch_version_toggle_incompatible"
53+
android:layout_width="wrap_content"
54+
android:layout_height="wrap_content"
55+
android:background="?android:attr/selectableItemBackground"
56+
android:paddingVertical="@dimen/padding_small"
57+
android:paddingEnd="@dimen/padding_heavy"
58+
android:textColor="?attr/colorTextSecondary"
59+
android:textSize="@dimen/_11ssp"
60+
android:text="@string/switch_mod_version_show_incompatible" />
61+
62+
<TextView
63+
android:layout_width="0dp"
64+
android:layout_height="wrap_content"
65+
android:layout_weight="1"
66+
android:text="@string/switch_mod_version_warning"
67+
android:textColor="@color/mod_version_incompatible"
68+
android:textSize="@dimen/_10ssp" />
69+
70+
</LinearLayout>
71+
72+
<View
73+
style="@style/ThickDivider"
74+
android:layout_marginTop="@dimen/padding_medium" />
75+
76+
<!-- Progress bar shown while fetching versions -->
5577
<ProgressBar
5678
android:id="@+id/switch_version_progress"
5779
android:layout_width="wrap_content"
5880
android:layout_height="wrap_content"
59-
android:layout_gravity="center" />
81+
android:layout_gravity="center_horizontal"
82+
android:layout_marginTop="@dimen/padding_large"
83+
android:layout_marginBottom="@dimen/padding_large"
84+
android:visibility="visible" />
6085

86+
<!-- Error / empty state -->
6187
<LinearLayout
6288
android:id="@+id/switch_version_error_layout"
6389
android:layout_width="match_parent"
6490
android:layout_height="wrap_content"
65-
android:layout_gravity="center"
6691
android:orientation="vertical"
6792
android:gravity="center"
93+
android:paddingVertical="@dimen/padding_large"
6894
android:visibility="gone">
6995

7096
<TextView
@@ -75,7 +101,7 @@
75101
android:textAlignment="center"
76102
android:text="@string/switch_mod_version_no_versions" />
77103

78-
<Button
104+
<com.kdt.mcgui.MineButton
79105
android:id="@+id/switch_version_retry_button"
80106
android:layout_width="wrap_content"
81107
android:layout_height="wrap_content"
@@ -84,50 +110,27 @@
84110

85111
</LinearLayout>
86112

113+
<!-- Version list — fixed height matching the export-mrpack file list
114+
established native pattern in this codebase -->
87115
<androidx.recyclerview.widget.RecyclerView
88116
android:id="@+id/switch_version_list"
89117
android:layout_width="match_parent"
90-
android:layout_height="match_parent"
91-
android:clipToPadding="false"
118+
android:layout_height="240dp"
119+
android:layout_marginBottom="@dimen/padding_medium"
120+
android:scrollbars="vertical"
92121
android:visibility="gone" />
93122

94-
</FrameLayout>
123+
<View
124+
style="@style/ThickDivider"
125+
android:layout_marginBottom="@dimen/padding_extra_large" />
95126

96-
<!-- Show/hide incompatible toggle -->
97-
<TextView
98-
android:id="@+id/switch_version_toggle_incompatible"
99-
android:layout_width="wrap_content"
100-
android:layout_height="wrap_content"
101-
android:layout_marginTop="@dimen/padding_moderate"
102-
android:background="?android:attr/selectableItemBackground"
103-
android:padding="@dimen/padding_moderate"
104-
android:textColor="?attr/colorTextSecondary"
105-
android:textSize="@dimen/_12ssp"
106-
android:text="@string/switch_mod_version_show_incompatible"
107-
app:layout_constraintStart_toStartOf="parent"
108-
app:layout_constraintTop_toBottomOf="@id/switch_version_content" />
109-
110-
<!-- Warning footer -->
111-
<TextView
112-
android:id="@+id/switch_version_warning"
113-
android:layout_width="match_parent"
114-
android:layout_height="wrap_content"
115-
android:layout_marginTop="@dimen/padding_moderate"
116-
android:text="@string/switch_mod_version_warning"
117-
android:textColor="@color/mod_version_incompatible"
118-
android:textSize="@dimen/_10ssp"
119-
app:layout_constraintTop_toBottomOf="@id/switch_version_toggle_incompatible" />
120-
121-
<!-- Cancel button -->
122-
<Button
123-
android:id="@+id/switch_version_cancel"
124-
android:layout_width="match_parent"
125-
android:layout_height="wrap_content"
126-
android:layout_marginTop="@dimen/padding_moderate"
127-
android:text="@android:string/cancel"
128-
app:layout_constraintTop_toBottomOf="@id/switch_version_warning"
129-
app:layout_constraintBottom_toBottomOf="parent"
130-
app:layout_constraintStart_toStartOf="parent"
131-
app:layout_constraintEnd_toEndOf="parent" />
132-
133-
</androidx.constraintlayout.widget.ConstraintLayout>
127+
<!-- Cancel button -->
128+
<com.kdt.mcgui.MineButton
129+
android:id="@+id/switch_version_cancel"
130+
android:layout_width="match_parent"
131+
android:layout_height="wrap_content"
132+
android:text="@android:string/cancel" />
133+
134+
</LinearLayout>
135+
136+
</ScrollView>

0 commit comments

Comments
 (0)