diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index 792c3deb7..c1ba78f88 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -33,6 +33,7 @@ import android.view.View; import android.view.WindowManager; import android.webkit.MimeTypeMap; import android.widget.EditText; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -1029,4 +1030,11 @@ public final class Tools { Intent sendIntent = Intent.createChooser(shareIntent, "latestlog.txt"); context.startActivity(sendIntent); } + + public static int mesureTextviewHeight(TextView t) { + int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(t.getWidth(), View.MeasureSpec.AT_MOST); + int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + t.measure(widthMeasureSpec, heightMeasureSpec); + return t.getMeasuredHeight(); + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SearchModFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SearchModFragment.java index 835ba06d1..26f8f7400 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SearchModFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SearchModFragment.java @@ -2,6 +2,7 @@ package net.kdt.pojavlaunch.fragments; import android.content.res.ColorStateList; import android.graphics.Color; +import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.View; @@ -12,6 +13,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.math.MathUtils; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -35,6 +37,16 @@ import java.util.concurrent.Future; public class SearchModFragment extends Fragment { public static final String TAG = "SearchModFragment"; + private View mOverlay; + private float mOverlayTopCache; // Padding cache reduce resource lookup + + private final RecyclerView.OnScrollListener mOverlayPositionListener = new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + mOverlay.setY(MathUtils.clamp(mOverlay.getY() - dy, -mOverlay.getHeight(), mOverlayTopCache)); + } + }; + private TextView mSelectedVersion; private Button mSelectVersionButton; private EditText mSearchEditText; @@ -49,8 +61,6 @@ public class SearchModFragment extends Fragment { private SearchFilters mSearchFilters; - - public SearchModFragment(){ super(R.layout.fragment_mod_search); modpackApi = new CommonApi(); @@ -62,7 +72,9 @@ public class SearchModFragment extends Fragment { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { // You can only access resources after attaching to current context mModItemAdapter = new ModItemAdapter(getResources(), modpackApi); + mOverlayTopCache = getResources().getDimension(R.dimen.fragment_padding_medium); + mOverlay = view.findViewById(R.id.search_mod_overlay); mSearchEditText = view.findViewById(R.id.search_mod_edittext); mSearchProgressBar = view.findViewById(R.id.search_mod_progressbar); mSelectedVersion = view.findViewById(R.id.search_mod_selected_mc_version_textview); @@ -75,6 +87,8 @@ public class SearchModFragment extends Fragment { mRecyclerview.setLayoutManager(new LinearLayoutManager(getContext())); mRecyclerview.setAdapter(mModItemAdapter); + mRecyclerview.addOnScrollListener(mOverlayPositionListener); + // Setup the expendable list behavior mSelectVersionButton.setOnClickListener(v -> VersionSelectorDialog.open(v.getContext(), true, (id, snapshot)->{ mSelectedVersion.setText(id); @@ -93,6 +107,12 @@ public class SearchModFragment extends Fragment { }); } + @Override + public void onDestroyView() { + super.onDestroyView(); + mRecyclerview.removeOnScrollListener(mOverlayPositionListener); + } + class SearchModTask implements SelfReferencingFuture.FutureInterface { private final SearchFilters mTaskFilters; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/ModItemAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/ModItemAdapter.java index 074552199..5c78d8780 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/ModItemAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/modpacks/ModItemAdapter.java @@ -31,10 +31,14 @@ import net.kdt.pojavlaunch.modloaders.modpacks.models.ModDetail; import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem; import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.Future; public class ModItemAdapter extends RecyclerView.Adapter { private static final ModItem[] MOD_ITEMS_EMPTY = new ModItem[0]; + + /* Used when versions haven't loaded yet, default text to reduce layout shifting */ + private final SimpleArrayAdapter mLoadingAdapter = new SimpleArrayAdapter<>(Collections.singletonList("Loading")); private final ModIconCache mIconCache = new ModIconCache(); private ModItem[] mModItems; private final ModpackApi mModpackApi; @@ -60,7 +64,7 @@ public class ModItemAdapter extends RecyclerView.Adapter mVersionAdapter = new SimpleArrayAdapter<>(null); + private final SimpleArrayAdapter mVersionAdapter = new SimpleArrayAdapter<>(null); public ViewHolder(View view) { super(view); @@ -77,7 +81,7 @@ public class ModItemAdapter extends RecyclerView.Adapter { - // We need to align to the longer section - ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) mExtendedLayout.getLayoutParams(); - params.topToBottom = mDescription.getBottom() > mIconView.getBottom() ? R.id.mod_body_textview : R.id.mod_thumbnail_imageview; - mExtendedLayout.setLayoutParams(params); - }); + + // We need to align to the longer section + int futureBottom = mDescription.getBottom() + Tools.mesureTextviewHeight(mDescription) - mDescription.getHeight(); + ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) mExtendedLayout.getLayoutParams(); + params.topToBottom = futureBottom > mIconView.getBottom() ? R.id.mod_body_textview : R.id.mod_thumbnail_imageview; + mExtendedLayout.setLayoutParams(params); } private void closeDetailedView(){ @@ -199,7 +203,7 @@ public class ModItemAdapter extends RecyclerView.Adapter + + + + + diff --git a/app_pojavlauncher/src/main/res/layout/fragment_mod_search.xml b/app_pojavlauncher/src/main/res/layout/fragment_mod_search.xml index cb70a72f8..c2a75cbb4 100644 --- a/app_pojavlauncher/src/main/res/layout/fragment_mod_search.xml +++ b/app_pojavlauncher/src/main/res/layout/fragment_mod_search.xml @@ -6,75 +6,106 @@ android:background="@color/background_app" xmlns:app="http://schemas.android.com/apk/res-auto" android:paddingHorizontal="@dimen/fragment_padding_medium" - android:paddingVertical="@dimen/fragment_padding_medium"> + > - + - - + > + + + + + + + + + + +