AggregatedStatisticsActivity: Convert ListView to RecyclerView

Part of: #1613
This commit is contained in:
Leon Marz
2023-08-05 16:58:40 +02:00
committed by Dennis Guse
parent 4baaff8374
commit e69bea802f
4 changed files with 56 additions and 50 deletions
@@ -7,6 +7,7 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
@@ -40,8 +41,6 @@ public class AggregatedStatisticsActivity extends AbstractActivity implements Fi
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
viewBinding.aggregatedStatsList.setEmptyView(viewBinding.aggregatedStatsEmptyView);
areFiltersApplied = savedInstanceState != null && savedInstanceState.getBoolean(STATE_ARE_FILTERS_APPLIED); areFiltersApplied = savedInstanceState != null && savedInstanceState.getBoolean(STATE_ARE_FILTERS_APPLIED);
List<Track.Id> trackIds = getIntent().getParcelableArrayListExtra(EXTRA_TRACK_IDS); List<Track.Id> trackIds = getIntent().getParcelableArrayListExtra(EXTRA_TRACK_IDS);
@@ -49,21 +48,35 @@ public class AggregatedStatisticsActivity extends AbstractActivity implements Fi
trackIds.stream().forEach(selection::addTrackId); trackIds.stream().forEach(selection::addTrackId);
} }
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
adapter = new AggregatedStatisticsAdapter(this, null);
viewBinding.aggregatedStatsList.setLayoutManager(layoutManager);
viewBinding.aggregatedStatsList.setAdapter(adapter);
viewModel = new ViewModelProvider(this).get(AggregatedStatisticsModel.class); viewModel = new ViewModelProvider(this).get(AggregatedStatisticsModel.class);
viewModel.getAggregatedStats(selection).observe(this, aggregatedStatistics -> { viewModel.getAggregatedStats(selection).observe(this, aggregatedStatistics -> {
if ((aggregatedStatistics == null || aggregatedStatistics.getCount() == 0) && !selection.isEmpty()) { if ((aggregatedStatistics == null || aggregatedStatistics.getCount() == 0) && !selection.isEmpty()) {
viewBinding.aggregatedStatsEmptyView.setText(getString(R.string.aggregated_stats_filter_no_results)); viewBinding.aggregatedStatsEmptyView.setText(getString(R.string.aggregated_stats_filter_no_results));
} }
if (aggregatedStatistics != null) { if (aggregatedStatistics != null) {
adapter = new AggregatedStatisticsAdapter(this, aggregatedStatistics); adapter.swapData(aggregatedStatistics);
viewBinding.aggregatedStatsList.setAdapter(adapter);
} }
adapter.notifyDataSetChanged(); checkListEmpty();
}); });
setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar); setSupportActionBar(viewBinding.bottomAppBarLayout.bottomAppBar);
} }
private void checkListEmpty() {
if (adapter.getItemCount() == 0) {
viewBinding.aggregatedStatsList.setVisibility(View.GONE);
viewBinding.aggregatedStatsEmptyView.setVisibility(View.VISIBLE);
} else {
viewBinding.aggregatedStatsList.setVisibility(View.VISIBLE);
viewBinding.aggregatedStatsEmptyView.setVisibility(View.GONE);
}
}
@Override @Override
public void onSaveInstanceState(@NonNull Bundle outState) { public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
@@ -1,15 +1,16 @@
package de.dennisguse.opentracks.ui.aggregatedStatistics; package de.dennisguse.opentracks.ui.aggregatedStatistics;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.util.Pair; import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -21,7 +22,7 @@ import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.settings.UnitSystem;
import de.dennisguse.opentracks.util.StringUtils; import de.dennisguse.opentracks.util.StringUtils;
public class AggregatedStatisticsAdapter extends BaseAdapter { public class AggregatedStatisticsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private AggregatedStatistics aggregatedStatistics; private AggregatedStatistics aggregatedStatistics;
private final Context context; private final Context context;
@@ -31,54 +32,38 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
this.aggregatedStatistics = aggregatedStatistics; this.aggregatedStatistics = aggregatedStatistics;
} }
@NonNull
@Override @Override
public int getCount() { public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (aggregatedStatistics != null) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.aggregated_stats_list_item, parent, false);
return aggregatedStatistics.getCount(); return new ViewHolder(view);
}
return 0;
} }
@Override @Override
public AggregatedStatistics.AggregatedStatistic getItem(int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
return aggregatedStatistics.getItem(position); ViewHolder viewHolder = (ViewHolder) holder;
}
@Override AggregatedStatistics.AggregatedStatistic aggregatedStatistic = aggregatedStatistics.getItem(position);
public long getItemId(int position) {
// Not important because data are not database register but cooked data.
return position;
}
@Override String type = aggregatedStatistic.getActivityTypeLocalized();
public View getView(int position, View convertView, ViewGroup parent) { if (ActivityType.findByLocalizedString(context, type).isShowSpeedPreferred()) {
AggregatedStatistics.AggregatedStatistic aggregatedStatistic = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.aggregated_stats_list_item, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
Resources resources = context.getResources();
String localizedActivityType = aggregatedStatistic.getActivityTypeLocalized();
if (ActivityType.findByLocalizedString(resources, localizedActivityType)
.isShowSpeedPreferred()) {
viewHolder.setSpeed(aggregatedStatistic); viewHolder.setSpeed(aggregatedStatistic);
} else { } else {
viewHolder.setPace(aggregatedStatistic); viewHolder.setPace(aggregatedStatistic);
} }
return convertView;
} }
public AggregatedStatistics swapData(AggregatedStatistics aggregatedStatistics) { @Override
public int getItemCount() {
if (aggregatedStatistics == null) {
return 0;
}
return aggregatedStatistics.getCount();
}
public void swapData(AggregatedStatistics aggregatedStatistics) {
this.aggregatedStatistics = aggregatedStatistics; this.aggregatedStatistics = aggregatedStatistics;
this.notifyDataSetChanged(); this.notifyDataSetChanged();
return aggregatedStatistics;
} }
public List<String> getCategories() { public List<String> getCategories() {
@@ -89,7 +74,7 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
return categories; return categories;
} }
private class ViewHolder { private class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView sportIcon; private final ImageView sportIcon;
private final TextView typeLabel; private final TextView typeLabel;
private final TextView numTracks; private final TextView numTracks;
@@ -108,6 +93,7 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
private boolean reportSpeed; private boolean reportSpeed;
public ViewHolder(View view) { public ViewHolder(View view) {
super(view);
sportIcon = view.findViewById(R.id.aggregated_stats_sport_icon); sportIcon = view.findViewById(R.id.aggregated_stats_sport_icon);
typeLabel = view.findViewById(R.id.aggregated_stats_type_label); typeLabel = view.findViewById(R.id.aggregated_stats_type_label);
numTracks = view.findViewById(R.id.aggregated_stats_num_tracks); numTracks = view.findViewById(R.id.aggregated_stats_num_tracks);
@@ -183,9 +169,7 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
private int getIcon(AggregatedStatistics.AggregatedStatistic aggregatedStatistic) { private int getIcon(AggregatedStatistics.AggregatedStatistic aggregatedStatistic) {
String localizedActivityType = aggregatedStatistic.getActivityTypeLocalized(); String localizedActivityType = aggregatedStatistic.getActivityTypeLocalized();
String iconValue = ActivityType.findByLocalizedString(context, localizedActivityType) return ActivityType.findByLocalizedString(context, localizedActivityType)
.getIconId();
return ActivityType.findBy(iconValue)
.getIconDrawableId(); .getIconDrawableId();
} }
} }
+3 -2
View File
@@ -23,10 +23,11 @@
android:paddingBottom="?attr/actionBarSize" android:paddingBottom="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<ListView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/aggregated_stats_list" android:id="@+id/aggregated_stats_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:visibility="gone" />
<TextView <TextView
android:id="@+id/aggregated_stats_empty_view" android:id="@+id/aggregated_stats_empty_view"
@@ -3,11 +3,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:paddingStart="8dp" android:paddingStart="8dp"
android:paddingBottom="24dp"> android:paddingBottom="8dp">
<!-- Guidelines --> <!-- Guidelines -->
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
@@ -166,4 +166,12 @@
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_max_rate" app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_max_rate"
tools:text="@string/stats_max_speed" /> tools:text="@string/stats_max_speed" />
<View
android:id="@+id/aggregated_stats_horizontal_line"
style="@style/HorizontalLine"
android:layout_marginTop="8dp"
app:layout_constraintStart_toEndOf="@id/guideline1"
app:layout_constraintEnd_toStartOf="@id/guideline3"
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_max_rate_label" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>