diff --git a/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListActivity.java b/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListActivity.java index e11c2fb..80b406e 100644 --- a/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListActivity.java +++ b/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListActivity.java @@ -2,13 +2,16 @@ package com.thebrokenrail.mtudining.activity.list; import android.os.Bundle; +import androidx.activity.EdgeToEdge; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.appbar.MaterialToolbar; import com.thebrokenrail.mtudining.R; +import com.thebrokenrail.mtudining.util.EdgeToEdgeUtil; /** * This activity lists the available food halls. @@ -20,8 +23,13 @@ public class ListActivity extends AppCompatActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Setup UI + EdgeToEdge.enable(this); setContentView(R.layout.activity_list); + // Toolbar + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + // Get View Model ViewModelProvider viewModelProvider = new ViewModelProvider(this); ListViewModel viewModel = viewModelProvider.get(ListViewModel.class); @@ -31,5 +39,6 @@ public class ListActivity extends AppCompatActivity { RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); + EdgeToEdgeUtil.setup(this, recyclerView); } } diff --git a/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListAdapter.java b/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListAdapter.java index 4bd5ae6..584d845 100644 --- a/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListAdapter.java +++ b/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListAdapter.java @@ -1,5 +1,6 @@ package com.thebrokenrail.mtudining.activity.list; +import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; @@ -8,11 +9,10 @@ import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatTextView; import androidx.recyclerview.widget.RecyclerView; -import com.google.android.material.card.MaterialCardView; +import com.thebrokenrail.mtudining.R; import com.thebrokenrail.mtudining.activity.task.Task; import com.thebrokenrail.mtudining.activity.task.TaskAdapter; import com.thebrokenrail.mtudining.widget.CategoryView; -import com.thebrokenrail.mtudining.widget.LoaderView; /** * Adapter for listing dining halls. @@ -51,11 +51,26 @@ public class ListAdapter extends TaskAdapter { // Add Locations holder.view.children.removeAllViews(); for (ListData.Element location : data.locations) { - AppCompatTextView textView = new AppCompatTextView(holder.view.getContext()); - textView.setText(location.name); - MaterialCardView.LayoutParams innerLayoutParams = new MaterialCardView.LayoutParams(MaterialCardView.LayoutParams.MATCH_PARENT, MaterialCardView.LayoutParams.WRAP_CONTENT); - textView.setLayoutParams(innerLayoutParams); - holder.view.children.addView(textView); + AppCompatTextView item = new AppCompatTextView(holder.view.getContext()); + // Text + item.setText(location.name); + // Text Size + item.setTextSize(TypedValue.COMPLEX_UNIT_PX, item.getResources().getDimension(R.dimen.item_font_size)); + // Padding + int margin = holder.view.getResources().getDimensionPixelSize(R.dimen.margin); + item.setPadding(margin, margin, margin, margin); + // Make Clickable + item.setClickable(true); + item.setFocusable(true); + // Ripple Effect + TypedValue outValue = new TypedValue(); + holder.view.getContext().getTheme().resolveAttribute(androidx.appcompat.R.attr.selectableItemBackground, outValue, true); + item.setBackgroundResource(outValue.resourceId); + // Layout + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + item.setLayoutParams(layoutParams); + // Add To View + holder.view.children.addView(item); } } diff --git a/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListViewModel.java b/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListViewModel.java index b0c45b4..1891b44 100644 --- a/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListViewModel.java +++ b/app/src/main/java/com/thebrokenrail/mtudining/activity/list/ListViewModel.java @@ -35,7 +35,10 @@ public class ListViewModel extends ViewModel { category.locations.add(new ListData.Element(location.id, location.name)); } } - data.categories.add(category); + // Skip Empty Category + if (category.locations.size() > 0) { + data.categories.add(category); + } } } done(data); diff --git a/app/src/main/java/com/thebrokenrail/mtudining/util/EdgeToEdgeUtil.java b/app/src/main/java/com/thebrokenrail/mtudining/util/EdgeToEdgeUtil.java new file mode 100644 index 0000000..6602f78 --- /dev/null +++ b/app/src/main/java/com/thebrokenrail/mtudining/util/EdgeToEdgeUtil.java @@ -0,0 +1,31 @@ +package com.thebrokenrail.mtudining.util; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.RecyclerView; + +/** + * Utility class for handling edge-to-edge. + */ +public class EdgeToEdgeUtil { + /** + * Setup edge-to-edge on an activity and a RecyclerView. + * @param activity The activity + * @param recyclerView The RecyclerView + */ + public static void setup(AppCompatActivity activity, RecyclerView recyclerView) { + // Insets + ViewCompat.setOnApplyWindowInsetsListener(activity.getWindow().getDecorView(), (v, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(insets.left, 0, insets.right, 0); + return windowInsets; + }); + ViewCompat.setOnApplyWindowInsetsListener(recyclerView, (v, windowInsets) -> { + Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + recyclerView.setPadding(0, 0, 0, insets.bottom); + return windowInsets; + }); + } +} diff --git a/app/src/main/java/com/thebrokenrail/mtudining/widget/CategoryView.java b/app/src/main/java/com/thebrokenrail/mtudining/widget/CategoryView.java index 76fe8be..744c136 100644 --- a/app/src/main/java/com/thebrokenrail/mtudining/widget/CategoryView.java +++ b/app/src/main/java/com/thebrokenrail/mtudining/widget/CategoryView.java @@ -1,6 +1,7 @@ package com.thebrokenrail.mtudining.widget; import android.content.Context; +import android.graphics.Typeface; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.FrameLayout; @@ -17,13 +18,13 @@ import com.thebrokenrail.mtudining.R; * Widget that shows a category of items. */ public class CategoryView extends FrameLayout { - private final LinearLayout inner; - public final MaterialCardView children; + private final MaterialCardView card; + public final LinearLayout children; private final AppCompatTextView title; public CategoryView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); - inner = new LinearLayout(context); + LinearLayout inner = new LinearLayout(context); inner.setOrientation(LinearLayout.VERTICAL); addView(inner); @@ -38,18 +39,27 @@ public class CategoryView extends FrameLayout { TypedValue value = new TypedValue(); context.getTheme().resolveAttribute(androidx.appcompat.R.attr.colorPrimary, value, true); title.setTextColor(value.data); + title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.category_font_size)); + title.setTypeface(null, Typeface.BOLD); title.setClickable(true); title.setFocusable(true); inner.addView(title); - LinearLayout.LayoutParams innerLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + LinearLayout.LayoutParams innerLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); title.setLayoutParams(innerLayoutParams); - // Setup Children - children = new MaterialCardView(context, null, com.google.android.material.R.attr.materialCardViewElevatedStyle); - inner.addView(children); + // Setup Card + card = new MaterialCardView(context, null, com.google.android.material.R.attr.materialCardViewElevatedStyle); + inner.addView(card); innerLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); innerLayoutParams.setMargins(0, margin, 0, 0); - children.setLayoutParams(innerLayoutParams); + card.setLayoutParams(innerLayoutParams); + + // Setup Children + children = new LinearLayout(context); + children.setOrientation(LinearLayout.VERTICAL); + card.addView(children); + MaterialCardView.LayoutParams cardLayoutParams = new MaterialCardView.LayoutParams(MaterialCardView.LayoutParams.MATCH_PARENT, MaterialCardView.LayoutParams.WRAP_CONTENT); + children.setLayoutParams(cardLayoutParams); } /** @@ -61,7 +71,7 @@ public class CategoryView extends FrameLayout { public void setup(boolean isOpen, String titleText, Runnable onClickTitle) { titleText = (isOpen ? "▼" : "▶") + " " + titleText; title.setText(titleText); - children.setVisibility(isOpen ? VISIBLE : GONE); + card.setVisibility(isOpen ? VISIBLE : GONE); title.setOnClickListener(v -> onClickTitle.run()); } } diff --git a/app/src/main/res/layout/activity_list.xml b/app/src/main/res/layout/activity_list.xml index a936c95..b838300 100644 --- a/app/src/main/res/layout/activity_list.xml +++ b/app/src/main/res/layout/activity_list.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" - android:fitsSystemWindows="true" tools:context=".activity.list.ListActivity"> \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 1191347..b84d8a4 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,4 +1,6 @@ 8dp + 20sp + 18sp \ No newline at end of file