Recording stats layout customizable.

Users can select the order, visibility and importance (primary or secondary) of all stats for recording layout from the Settings.
Also, users can select the number of columns per row in the recording layout: 1, 2 or 3.
Finally, show altitude/coordinate from settings have been removed (not needed anymore).
Fixes #659.
Fixes #302.
Fixes #820.
This commit is contained in:
Román Martínez
2021-06-19 21:29:06 +02:00
parent 7f10ae5c3f
commit 9c4c8131f5
93 changed files with 2146 additions and 1126 deletions
@@ -0,0 +1,170 @@
package de.dennisguse.opentracks.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ScrollView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.stream.IntStream;
import de.dennisguse.opentracks.AbstractActivity;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.adapters.SettingsCustomLayoutAdapter;
import de.dennisguse.opentracks.content.data.Layout;
import de.dennisguse.opentracks.content.data.DataField;
import de.dennisguse.opentracks.databinding.ActivitySettingsCustomLayoutBinding;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.StatisticsUtils;
public class SettingsCustomLayoutActivity extends AbstractActivity implements SettingsCustomLayoutAdapter.SettingsCustomLayoutItemClickListener {
private ActivitySettingsCustomLayoutBinding viewBinding;
private GridLayoutManager gridLayoutManager;
private SettingsCustomLayoutAdapter adapterFieldsVisible;
private SettingsCustomLayoutAdapter adapterFieldsHidden;
private Layout layoutFieldsVisible;
private Layout layoutFieldsHidden;
private SharedPreferences sharedPreferences;
private int numColumns;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPreferences = PreferencesUtils.getSharedPreferences(this);
// Recycler view with visible stats.
layoutFieldsVisible = StatisticsUtils.filterVisible(PreferencesUtils.getCustomLayout(sharedPreferences, this), true);
adapterFieldsVisible = new SettingsCustomLayoutAdapter(this, this, layoutFieldsVisible);
numColumns = PreferencesUtils.getLayoutColumns(sharedPreferences, this);
RecyclerView recyclerViewVisible = viewBinding.recyclerViewVisible;
gridLayoutManager = new GridLayoutManager(this, numColumns);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (adapterFieldsVisible.isItemWide(position)) {
return numColumns;
}
return 1;
}
});
recyclerViewVisible.setLayoutManager(gridLayoutManager);
recyclerViewVisible.setAdapter(adapterFieldsVisible);
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END, 0) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
layoutFieldsVisible = adapterFieldsVisible.move(fromPosition, toPosition);
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(recyclerViewVisible);
// Spinner with items per row.
ArrayAdapter<Integer> spinnerAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item,
IntStream.of(getResources().getIntArray(R.array.stats_custom_layout_fields_columns_per_row)).boxed().toArray(Integer[]::new));
viewBinding.spinnerOptions.setAdapter(spinnerAdapter);
viewBinding.spinnerOptions.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
numColumns = position + 1;
gridLayoutManager.setSpanCount(numColumns);
PreferencesUtils.setLayoutColumns(sharedPreferences, SettingsCustomLayoutActivity.this, position + 1);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
viewBinding.spinnerOptions.setSelection(PreferencesUtils.getLayoutColumns(sharedPreferences, SettingsCustomLayoutActivity.this) - 1);
// Recycler view with not visible stats.
layoutFieldsHidden = StatisticsUtils.filterVisible(PreferencesUtils.getCustomLayout(sharedPreferences, this), false);
adapterFieldsHidden = new SettingsCustomLayoutAdapter(this, this, layoutFieldsHidden);
RecyclerView recyclerViewNotVisible = viewBinding.recyclerViewNotVisible;
recyclerViewNotVisible.setLayoutManager(new LinearLayoutManager(this));
recyclerViewNotVisible.setAdapter(adapterFieldsHidden);
}
@Override
protected void onPause() {
super.onPause();
if (!layoutFieldsVisible.getFields().isEmpty() || !layoutFieldsHidden.getFields().isEmpty()) {
Layout newLayout = new Layout(layoutFieldsVisible.getProfile());
newLayout.addFields(layoutFieldsVisible.getFields());
newLayout.addFields(layoutFieldsHidden.getFields());
PreferencesUtils.setCustomLayout(sharedPreferences, this, newLayout);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
sharedPreferences = null;
layoutFieldsVisible = null;
}
@Override
protected void setupActionBarBack(Toolbar toolbar) {
super.setupActionBarBack(toolbar);
toolbar.setTitle(R.string.menu_settings);
}
@Override
protected View getRootView() {
viewBinding = ActivitySettingsCustomLayoutBinding.inflate(getLayoutInflater());
return viewBinding.getRoot();
}
@Override
public void onSettingsCustomLayoutItemClicked(@NonNull DataField field) {
if (field.isVisible()) {
new AlertDialog.Builder(this)
.setTitle(R.string.generic_choose_an_option)
.setItems(new String[]{getString(field.isPrimary() ? R.string.field_set_secondary : R.string.field_set_primary), getString(R.string.field_remove_from_layout)}, (dialog, which) -> {
if (which == 0) {
field.togglePrimary();
} else {
layoutFieldsVisible.removeField(field);
field.toggleVisibility();
layoutFieldsHidden.addField(field);
}
adapterFieldsVisible.swapValues(layoutFieldsVisible);
adapterFieldsHidden.swapValues(layoutFieldsHidden);
})
.create()
.show();
} else {
layoutFieldsHidden.removeField(field);
field.toggleVisibility();
layoutFieldsVisible.addField(field);
viewBinding.scrollView.fullScroll(ScrollView.FOCUS_UP);
adapterFieldsVisible.swapValues(layoutFieldsVisible);
adapterFieldsHidden.swapValues(layoutFieldsHidden);
}
}
}