forked from upstream-mirrors/OpenTracks
IntervalsFragment/IntervalStatisticsModel refactoring: better performance with AndroidViewModel (it doesn't recreate the model every track point done anymore).
Also, it doesn't jump anymore. Fixes #669.
This commit is contained in:
@@ -4,73 +4,84 @@ import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||
|
||||
public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.Interval> {
|
||||
public class IntervalStatisticsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private List<IntervalStatistics.Interval> intervalList;
|
||||
private final Context context;
|
||||
private final StackMode stackMode;
|
||||
private final boolean metricUnits;
|
||||
private final String category;
|
||||
private boolean metricUnits;
|
||||
private boolean isReportSpeed;
|
||||
|
||||
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList, String category, StackMode stackMode) {
|
||||
super(context, R.layout.interval_stats_list_item, intervalList);
|
||||
metricUnits = PreferencesUtils.isMetricUnits(PreferencesUtils.getSharedPreferences(context), context);
|
||||
this.category = category;
|
||||
public IntervalStatisticsAdapter(Context context, StackMode stackMode, boolean metricUnits, boolean isReportSpeed) {
|
||||
this.metricUnits = metricUnits;
|
||||
this.context = context;
|
||||
this.stackMode = stackMode;
|
||||
this.isReportSpeed = isReportSpeed;
|
||||
}
|
||||
|
||||
//TODO Check preference handling! Should not be accessed in getView()
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, @Nullable View intervalView, @NonNull ViewGroup parent) {
|
||||
int actualPosition = stackMode == StackMode.STACK_FROM_TOP ? position : getCount() - 1 - position;
|
||||
IntervalStatistics.Interval interval = getItem(actualPosition);
|
||||
ViewHolder viewHolder;
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.interval_stats_list_item, parent, false);
|
||||
return new IntervalStatisticsAdapter.ViewHolder(view);
|
||||
}
|
||||
|
||||
if (intervalView == null) {
|
||||
viewHolder = new ViewHolder();
|
||||
|
||||
intervalView = LayoutInflater.from(getContext()).inflate(R.layout.interval_stats_list_item, parent, false);
|
||||
|
||||
viewHolder.distance = intervalView.findViewById(R.id.interval_item_distance);
|
||||
viewHolder.rate = intervalView.findViewById(R.id.interval_item_rate);
|
||||
viewHolder.gain = intervalView.findViewById(R.id.interval_item_gain);
|
||||
viewHolder.loss = intervalView.findViewById(R.id.interval_item_loss);
|
||||
|
||||
intervalView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (ViewHolder) intervalView.getTag();
|
||||
}
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
int actualPosition = stackMode == StackMode.STACK_FROM_TOP ? position : getItemCount() - 1 - position;
|
||||
int nextPosition = actualPosition + 1;
|
||||
boolean isLast = actualPosition == getItemCount() - 1;
|
||||
IntervalStatisticsAdapter.ViewHolder viewHolder = (IntervalStatisticsAdapter.ViewHolder) holder;
|
||||
IntervalStatistics.Interval interval = intervalList.get(actualPosition);
|
||||
viewHolder.itemView.setTag(actualPosition);
|
||||
|
||||
float sumDistance_m;
|
||||
if (actualPosition + 1 == getCount() && actualPosition > 0) {
|
||||
sumDistance_m = actualPosition * getItem(actualPosition - 1).getDistance_m() + interval.getDistance_m();
|
||||
if (isLast && actualPosition > 0) {
|
||||
sumDistance_m = actualPosition * intervalList.get(actualPosition - 1).getDistance_m() + interval.getDistance_m();
|
||||
} else {
|
||||
sumDistance_m = (actualPosition + 1) * interval.getDistance_m();
|
||||
sumDistance_m = nextPosition * interval.getDistance_m();
|
||||
}
|
||||
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
|
||||
viewHolder.distance.setText(StringUtils.formatDistance(context, sumDistance_m, metricUnits));
|
||||
|
||||
if (PreferencesUtils.isReportSpeed(PreferencesUtils.getSharedPreferences(getContext()), getContext(), category)) {
|
||||
viewHolder.rate.setText(StringUtils.formatSpeed(getContext(), interval.getSpeed_ms(), metricUnits, true));
|
||||
} else {
|
||||
viewHolder.rate.setText(StringUtils.formatSpeed(getContext(), interval.getSpeed_ms(), metricUnits, false));
|
||||
viewHolder.rate.setText(StringUtils.formatSpeed(context, interval.getSpeed_ms(), metricUnits, isReportSpeed));
|
||||
|
||||
viewHolder.gain.setText(StringUtils.formatDistance(context, interval.getGain_m(), metricUnits));
|
||||
viewHolder.loss.setText(StringUtils.formatDistance(context, interval.getLoss_m(), metricUnits));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (intervalList == null) {
|
||||
return 0;
|
||||
}
|
||||
return intervalList.size();
|
||||
}
|
||||
|
||||
public List<IntervalStatistics.Interval> swapData(List<IntervalStatistics.Interval> data, boolean metricUnits, boolean isReportSpeed) {
|
||||
if (intervalList == data && this.metricUnits == metricUnits && this.isReportSpeed == isReportSpeed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
viewHolder.gain.setText(StringUtils.formatDistance(getContext(), interval.getGain_m(), metricUnits));
|
||||
viewHolder.loss.setText(StringUtils.formatDistance(getContext(), interval.getLoss_m(), metricUnits));
|
||||
this.metricUnits = metricUnits;
|
||||
this.isReportSpeed = isReportSpeed;
|
||||
intervalList = data;
|
||||
|
||||
return intervalView;
|
||||
if (data != null) {
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,10 +92,18 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
||||
STACK_FROM_TOP
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
private TextView distance;
|
||||
private TextView rate;
|
||||
private TextView gain;
|
||||
private TextView loss;
|
||||
private static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView distance;
|
||||
TextView rate;
|
||||
TextView gain;
|
||||
TextView loss;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
distance = itemView.findViewById(R.id.interval_item_distance);
|
||||
rate = itemView.findViewById(R.id.interval_item_rate);
|
||||
gain = itemView.findViewById(R.id.interval_item_gain);
|
||||
loss = itemView.findViewById(R.id.interval_item_loss);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user