Add more features to ActivitySummariesFilter

Add possibility to pick individual SportsItem items into filtered view
Add quick time range selector
add deviceFilter for devices that supportsActivityTracks
add baseAltitude
add average speed, calculated from from distance/active time
make Activity Details layout scrollable
This commit is contained in:
vanous 2020-08-31 23:22:17 +02:00
parent faef4fd92f
commit 874b510784
17 changed files with 772 additions and 310 deletions

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 24 24"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg10"
sodipodi:docname="filter_alt_plus.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs14" />
<sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1042"
id="namedview12"
showgrid="false"
inkscape:zoom="22.185475"
inkscape:cx="11.10688"
inkscape:cy="13.735124"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="svg10" />
<g
id="g8">
<path
d="M0,0h24 M24,24H0"
fill="none"
id="path2" />
<path
d="M 5.0390625 4 C 4.2090625 4 3.74 4.949375 4.25 5.609375 C 6.27 8.199375 10 13 10 13 L 10 19 C 10 19.55 10.45 20 11 20 L 13 20 C 13.55 20 14 19.55 14 19 L 14 13 C 14 13 14.561178 12.276632 14.648438 12.164062 A 6.0985484 6.0985484 0 0 1 13.175781 10.810547 L 11.990234 12.300781 L 7 6 L 11.978516 6 A 6.0985484 6.0985484 0 0 1 12.707031 4 L 5.0390625 4 z "
id="path4" />
<path
d="M0,0h24v24H0V0z"
fill="none"
id="path6" />
</g>
<g
aria-label="+"
transform="matrix(2.3775617,0,0,2.3738594,-12.403443,-12.287874)"
id="text843"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.38504px;line-height:124%;font-family:Sans;-inkscape-font-specification:'Sans Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.420925px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
<path
d="m 12.25254,6.4481113 v 1.7365562 h 1.736556 V 8.7146757 H 12.25254 V 10.451232 H 11.728767 V 8.7146757 H 9.9922108 V 8.1846675 H 11.728767 V 6.4481113 Z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.38504px;font-family:Sans;-inkscape-font-specification:'Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.420925px"
id="path835" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;
import android.widget.ListView;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.AbstractItemAdapter;
@ -51,6 +53,14 @@ public abstract class AbstractListActivity<T> extends AbstractGBActivity {
this.itemAdapter.setNameContainsFilter(name);
}
public void setItemsFilter(List items) {
this.itemAdapter.setItemsFilter(items);
}
public void setDeviceFilter(long device) {
this.itemAdapter.setDeviceFilter(device);
}
public AbstractItemAdapter<T> getItemAdapter() {
return itemAdapter;
}

View File

@ -54,6 +54,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
@ -67,7 +68,10 @@ import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.ActivitySummariesAdapter;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummary;
@ -86,6 +90,8 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
int activityFilter=0;
long dateFromFilter=0;
long dateToFilter=0;
long deviceFilter;
List<Long>itemsFilter;
String nameContainsFilter;
boolean offscreen = true;
static final int ACTIVITY_FILTER=1;
@ -141,15 +147,7 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
break;
case R.id.activity_action_filter:
if (!offscreen) processSummaryStatistics(); //hide drawer with stats if shown
Intent filterIntent = new Intent(this, ActivitySummariesFilter.class);
Bundle bundle = new Bundle();
bundle.putSerializable("activityKindMap",activityKindMap);
bundle.putInt("activityFilter",activityFilter);
bundle.putLong("dateFromFilter",dateFromFilter);
bundle.putLong("dateToFilter",dateToFilter);
bundle.putString("nameContainsFilter",nameContainsFilter);
filterIntent.putExtras(bundle);
startActivityForResult(filterIntent,ACTIVITY_FILTER);
runFilterActivity();
return true;
case R.id.activity_action_calculate_summary_stats:
processSummaryStatistics();
@ -232,14 +230,20 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == ACTIVITY_FILTER && resultData != null) {
activityFilter = resultData.getIntExtra("activityFilter", 0);
dateFromFilter = resultData.getLongExtra("dateFromFilter", 0);
dateToFilter = resultData.getLongExtra("dateToFilter", 0);
nameContainsFilter = resultData.getStringExtra("nameContainsFilter");
Bundle bundle = resultData.getExtras();
activityFilter = bundle.getInt("activityFilter", 0);
dateFromFilter = bundle.getLong("dateFromFilter", 0);
dateToFilter = bundle.getLong("dateToFilter", 0);
deviceFilter = bundle.getLong("deviceFilter", 0);
nameContainsFilter = bundle.getString("nameContainsFilter");
itemsFilter = (List<Long>) bundle.getSerializable("itemsFilter");
setActivityKindFilter(activityFilter);
setActivityKindFilter(activityFilter);
setDateFromFilter(dateFromFilter);
setDateToFilter(dateToFilter);
setNameContainsFilter(nameContainsFilter);
setItemsFilter(itemsFilter);
setDeviceFilter(deviceFilter);
refresh();
}
if (requestCode == ACTIVITY_DETAIL) {
@ -255,13 +259,13 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
} else {
throw new IllegalArgumentException("Must provide a device when invoking this activity");
}
deviceFilter=getDeviceId(mGBDevice);
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(GBDevice.ACTION_DEVICE_CHANGED);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
super.onCreate(savedInstanceState);
ActivitySummariesAdapter activitySummariesAdapter = new ActivitySummariesAdapter(this, mGBDevice,activityFilter,dateFromFilter,dateToFilter,nameContainsFilter);
ActivitySummariesAdapter activitySummariesAdapter = new ActivitySummariesAdapter(this, mGBDevice, activityFilter, dateFromFilter, dateToFilter, nameContainsFilter, deviceFilter, itemsFilter);
int backgroundColor = getBackgroundColor(ActivitySummariesActivity.this);
activitySummariesAdapter.setBackgroundColor(backgroundColor);
setItemAdapter(activitySummariesAdapter);
@ -347,6 +351,24 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
getItemListView().setItemChecked(i, true);
}
return true; //don't finish actionmode in this case!
case R.id.activity_action_addto_filter:
List<Long> toFilter = new ArrayList<>();
for (int i = 0; i < checked.size(); i++) {
if (checked.valueAt(i)) {
BaseActivitySummary item = getItemAdapter().getItem(checked.keyAt(i));
if (item != null) {
ActivitySummary summary = item;
Long id = summary.getId();
toFilter.add(id);
}
}
}
itemsFilter = toFilter;
setItemsFilter(itemsFilter);
refresh();
processed = true;
break;
default:
break;
}
@ -425,20 +447,6 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
refresh();
}
private void showActivityDetail(int position){
Intent ActivitySummaryDetailIntent = new Intent(this, ActivitySummaryDetail.class);
ActivitySummaryDetailIntent.putExtra("position", position);
ActivitySummaryDetailIntent.putExtra("filter", activityFilter);
ActivitySummaryDetailIntent.putExtra("dateFromFilter",dateFromFilter);
ActivitySummaryDetailIntent.putExtra("dateToFilter",dateToFilter);
ActivitySummaryDetailIntent.putExtra("nameContainsFilter",nameContainsFilter);
ActivitySummaryDetailIntent.putExtra(GBDevice.EXTRA_DEVICE, mGBDevice);
startActivityForResult(ActivitySummaryDetailIntent,ACTIVITY_DETAIL);
}
private void fetchTrackData() {
if (mGBDevice.isInitialized() && !mGBDevice.isBusy()) {
GBApplication.deviceService().onFetchRecordedData(RecordedDataTypes.TYPE_GPS_TRACKS);
@ -476,4 +484,44 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
return typedValue.data;
}
private void showActivityDetail(int position) {
Intent ActivitySummaryDetailIntent = new Intent(this, ActivitySummaryDetail.class);
Bundle bundle = new Bundle();
bundle.putInt("position", position);
bundle.putSerializable("activityKindMap", activityKindMap);
bundle.putSerializable("itemsFilter", (Serializable) itemsFilter);
bundle.putInt("activityFilter", activityFilter);
bundle.putLong("dateFromFilter", dateFromFilter);
bundle.putLong("dateToFilter", dateToFilter);
bundle.putLong("deviceFilter", deviceFilter);
bundle.putString("nameContainsFilter", nameContainsFilter);
ActivitySummaryDetailIntent.putExtras(bundle);
ActivitySummaryDetailIntent.putExtra(GBDevice.EXTRA_DEVICE, mGBDevice);
startActivityForResult(ActivitySummaryDetailIntent, ACTIVITY_DETAIL);
}
private void runFilterActivity() {
Intent filterIntent = new Intent(this, ActivitySummariesFilter.class);
Bundle bundle = new Bundle();
bundle.putSerializable("activityKindMap", activityKindMap);
bundle.putSerializable("itemsFilter", (Serializable) itemsFilter);
bundle.putInt("activityFilter", activityFilter);
bundle.putLong("dateFromFilter", dateFromFilter);
bundle.putLong("dateToFilter", dateToFilter);
bundle.putLong("deviceFilter", deviceFilter);
bundle.putString("nameContainsFilter", nameContainsFilter);
filterIntent.putExtras(bundle);
startActivityForResult(filterIntent, ACTIVITY_FILTER);
}
private long getDeviceId(GBDevice device) {
try (DBHandler handler = GBApplication.acquireDB()) {
Device dbDevice = DBHelper.findDevice(device, handler.getDaoSession());
return dbDevice.getId();
} catch (Exception e) {
}
return 0;
}
}

View File

@ -19,13 +19,11 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
@ -40,29 +38,45 @@ import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
public class ActivitySummariesFilter extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummariesActivity.class);
private static final String DATE_FILTER_FROM = "dateFromFilter";
private static final String DATE_FILTER_TO = "dateToFilter";
public static long ALL_DEVICES = 999;
int activityFilter = 0;
long dateFromFilter = 0;
long dateToFilter = 0;
String nameContainsFilter;
HashMap<String, Integer> activityKindMap = new HashMap<>(1);
List<Long> itemsFilter;
long deviceFilter;
long initial_deviceFilter;
int BACKGROUND_COLOR;
LinkedHashMap<String, Long> allDevices;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -70,9 +84,11 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
Bundle bundle = this.getIntent().getExtras();
activityKindMap = (HashMap<String, Integer>) bundle.getSerializable("activityKindMap");
itemsFilter = (List<Long>) bundle.getSerializable("itemsFilter");
activityFilter = bundle.getInt("activityFilter", 0);
dateFromFilter = bundle.getLong("dateFromFilter", 0);
dateToFilter = bundle.getLong("dateToFilter", 0);
initial_deviceFilter = deviceFilter = bundle.getLong("deviceFilter", 0);
nameContainsFilter = bundle.getString("nameContainsFilter");
Context appContext = this.getApplicationContext();
@ -81,28 +97,50 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
}
BACKGROUND_COLOR = GBApplication.getBackgroundColor(appContext);
//get spinner ready - assign data, set selected item...
final Spinner filterKindSpinner = findViewById(R.id.select_kind);
ArrayList<String> spinnerArray = new ArrayList<>(activityKindMap.keySet());
//ensure that all items is always first in the list
spinnerArray.remove(getString(R.string.activity_summaries_all_activities));
spinnerArray.add(0, getString(R.string.activity_summaries_all_activities));
allDevices = getAllDevices(appContext);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, spinnerArray);
filterKindSpinner.setAdapter(dataAdapter);
filterKindSpinner.setSelection(dataAdapter.getPosition(getKeyByValue(activityFilter)));
addListenerOnSpinnerItemSelection();
//device filter spinner
final Spinner deviceFilterSpinner = findViewById(R.id.select_device);
ArrayList<String> filterDevicesArray = new ArrayList<String>(allDevices.keySet());
final ArrayAdapter<String> filterDevicesAdapter = new ArrayAdapter<String>(this,
R.layout.simple_spinner_item_themed, filterDevicesArray);
deviceFilterSpinner.setAdapter(filterDevicesAdapter);
deviceFilterSpinner.setSelection(filterDevicesAdapter.getPosition(getDeviceById(deviceFilter)));
addListenerOnSpinnerDeviceSelection();
//Kind filter spinner - assign data, set selected item...
final Spinner filterKindSpinner = findViewById(R.id.select_kind);
ArrayList<String> kindArray = new ArrayList<>(activityKindMap.keySet());
//ensure that all items is always first in the list
kindArray.remove(getString(R.string.activity_summaries_all_activities));
kindArray.add(0, getString(R.string.activity_summaries_all_activities));
ArrayAdapter<String> filterKindAdapter = new ArrayAdapter<String>(this,
R.layout.simple_spinner_item_themed, kindArray);
filterKindSpinner.setAdapter(filterKindAdapter);
filterKindSpinner.setSelection(filterKindAdapter.getPosition(getKindByValue(activityFilter)));
addListenerOnSpinnerKindSelection();
//quick date filter selection
final Spinner quick_filter_period_select = findViewById(R.id.quick_filter_period_select);
ArrayList<String> quickDateArray = new ArrayList<>(activityKindMap.keySet());
ArrayList activity_filter_quick_filter_period_items = new ArrayList(Arrays.asList(getResources().getStringArray(R.array.activity_filter_quick_filter_period_items)));
ArrayAdapter<String> filterDateAdapter = new ArrayAdapter<String>(this,
R.layout.simple_spinner_item_themed, activity_filter_quick_filter_period_items);
quick_filter_period_select.setAdapter(filterDateAdapter);
addListenerOnQuickFilterSelection();
//set current values coming from parent
update_filter_fields();
final LinearLayout filterfrom = findViewById(R.id.filterfrom);
final LinearLayout filterto = findViewById(R.id.filterto);
final EditText nameContainsFilterdata = findViewById(R.id.textViewNameData);
nameContainsFilterdata.setBackgroundDrawable(null);
final Button reset_filter_button = findViewById(R.id.reset_filter_button);
final Button apply_filter_button = findViewById(R.id.apply_filter_button);
nameContainsFilterdata.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
@ -129,6 +167,10 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
dateToFilter = 0;
nameContainsFilter = "";
filterKindSpinner.setSelection(0);
itemsFilter = null;
deviceFilter = initial_deviceFilter;
deviceFilterSpinner.setSelection(filterDevicesAdapter.getPosition(getDeviceById(deviceFilter)));
quick_filter_period_select.setSelection(0);
update_filter_fields();
}
});
@ -140,24 +182,27 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
if (text != null && text.length() > 0) {
nameContainsFilter = text;
}
Intent intent = new Intent();
intent.putExtra("activityFilter", activityFilter);
intent.putExtra("dateFromFilter", dateFromFilter);
intent.putExtra("dateToFilter", dateToFilter);
intent.putExtra("nameContainsFilter", nameContainsFilter);
Bundle bundle = new Bundle();
bundle.putInt("activityFilter", activityFilter);
bundle.putSerializable("itemsFilter", (Serializable) itemsFilter);
bundle.putLong("dateFromFilter", dateFromFilter);
bundle.putLong("dateToFilter", dateToFilter);
bundle.putLong("deviceFilter", deviceFilter);
bundle.putString("nameContainsFilter", nameContainsFilter);
intent.putExtras(bundle);
setResult(1, intent);
finish();
}
});
//set current values coming from parent
update_filter_fields();
filterfrom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getDate(DATE_FILTER_FROM, dateFromFilter);
quick_filter_period_select.setSelection(0);
}
});
@ -166,30 +211,44 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
@Override
public void onClick(View v) {
getDate(DATE_FILTER_TO, dateToFilter);
quick_filter_period_select.setSelection(0);
}
});
}
public String getKeyByValue(Integer value) {
for (Map.Entry<String, Integer> entry : activityKindMap.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
return entry.getKey();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// back button
finish();
return true;
}
return null;
return super.onOptionsItemSelected(item);
}
private void addListenerOnSpinnerDeviceSelection() {
Spinner spinner = findViewById(R.id.select_device);
spinner.setOnItemSelectedListener(new CustomOnDeviceSelectedListener());
}
public void addListenerOnSpinnerItemSelection() {
public void addListenerOnSpinnerKindSelection() {
Spinner spinner = findViewById(R.id.select_kind);
spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
spinner.setOnItemSelectedListener(new CustomOnKindSelectedListener());
}
public void addListenerOnQuickFilterSelection() {
Spinner spinner = findViewById(R.id.quick_filter_period_select);
spinner.setOnItemSelectedListener(new CustomQuickFilterSelectionListener());
}
public void update_filter_fields() {
TextView filterDateFromDataView = findViewById(R.id.textViewFromData);
TextView filterDateToDataView = findViewById(R.id.textViewToData);
Button reset_filter_button = findViewById(R.id.reset_filter_button);
TextView textViewItemsData = findViewById(R.id.textViewItemsData);
final EditText nameContainsFilterdata = findViewById(R.id.textViewNameData);
if (dateFromFilter > 0) {
@ -211,10 +270,17 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
filterDateFromDataView.setBackgroundColor(BACKGROUND_COLOR);
filterDateToDataView.setBackgroundColor(BACKGROUND_COLOR);
}
if (itemsFilter != null) {
textViewItemsData.setText(String.format("%s", itemsFilter.size()));
} else {
textViewItemsData.setText("0");
}
if (nameContainsFilter != null && !nameContainsFilter.equals(nameContainsFilterdata.getText().toString())) {
nameContainsFilterdata.setText(nameContainsFilter);
}
if (dateToFilter != 0 || dateFromFilter != 0 || activityFilter != 0 || nameContainsFilterdata.length() > 0) {
if (dateToFilter != 0 || dateFromFilter != 0 || activityFilter != 0 || nameContainsFilterdata.length() > 0 || itemsFilter != null || deviceFilter != initial_deviceFilter) {
reset_filter_button.getBackground().clearColorFilter();
} else {
@ -234,7 +300,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Calendar date = Calendar.getInstance();
if (filter == DATE_FILTER_FROM) {
if (filter.equals(DATE_FILTER_FROM)) {
date.set(year, monthOfYear, dayOfMonth, 0, 0);
dateFromFilter = date.getTimeInMillis();
} else {
@ -246,18 +312,101 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
}, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// back button
finish();
return true;
private void setTimePeriodFilter(String selection) {
Calendar date = Calendar.getInstance();
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
long firstdate;
long lastdate;
switch (selection) {
case "thisweek":
date.set(Calendar.DAY_OF_WEEK, date.getFirstDayOfWeek());
firstdate = date.getTimeInMillis();
lastdate = Calendar.getInstance().getTimeInMillis();
break;
case "thismonth":
date.set(Calendar.DAY_OF_MONTH, 1);
firstdate = date.getTimeInMillis();
lastdate = Calendar.getInstance().getTimeInMillis();
break;
case "lastweek":
int i = date.get(Calendar.DAY_OF_WEEK) - date.getFirstDayOfWeek();
date.add(Calendar.DATE, -i - 7);
firstdate = date.getTimeInMillis();
date.add(Calendar.DATE, 6);
lastdate = date.getTimeInMillis();
break;
case "lastmonth":
date.set(Calendar.DATE, 1);
date.add(Calendar.DAY_OF_MONTH, -1);
lastdate = date.getTimeInMillis();
date.set(Calendar.DATE, 1);
firstdate = date.getTimeInMillis();
break;
case "7days":
date.add(Calendar.DATE, -7);
firstdate = date.getTimeInMillis();
lastdate = Calendar.getInstance().getTimeInMillis();
break;
case "30days":
date.add(Calendar.DATE, -30);
firstdate = date.getTimeInMillis();
lastdate = Calendar.getInstance().getTimeInMillis();
break;
default:
return;
}
return super.onOptionsItemSelected(item);
dateFromFilter = firstdate;
dateToFilter = lastdate;
update_filter_fields();
}
public class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
private LinkedHashMap getAllDevices(Context appContext) {
DaoSession daoSession;
GBApplication gbApp = (GBApplication) appContext;
LinkedHashMap<String, Long> newMap = new LinkedHashMap<>(1);
List<? extends GBDevice> devices = gbApp.getDeviceManager().getDevices();
newMap.put(getString(R.string.activity_summaries_all_devices), ALL_DEVICES);
try (DBHandler handler = GBApplication.acquireDB()) {
daoSession = handler.getDaoSession();
for (GBDevice device : devices) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
Device dbDevice = DBHelper.findDevice(device, daoSession);
if (dbDevice != null && coordinator != null
&& coordinator.supportsActivityTracks()
&& !newMap.containsKey(device.getAliasOrName())) {
newMap.put(device.getAliasOrName(), dbDevice.getId());
}
}
} catch (Exception e) {
LOG.debug("Error getting list of all devices: " + e);
}
return newMap;
}
public String getKindByValue(Integer value) {
for (Map.Entry<String, Integer> entry : activityKindMap.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
return entry.getKey();
}
}
return null;
}
public String getDeviceById(long id) {
for (Map.Entry<String, Long> device : allDevices.entrySet()) {
if (Objects.equals(id, device.getValue())) {
return device.getKey();
}
}
return null;
}
public class CustomOnKindSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
activityFilter = activityKindMap.get(parent.getItemAtPosition(pos));
@ -271,4 +420,34 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
}
public class CustomOnDeviceSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
deviceFilter = allDevices.get(parent.getItemAtPosition(pos));
update_filter_fields();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
public class CustomQuickFilterSelectionListener implements AdapterView.OnItemSelectedListener {
ArrayList activity_filter_quick_filter_period_values = new ArrayList(Arrays.asList(getResources().getStringArray(R.array.activity_filter_quick_filter_period_values)));
String selection;
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
selection = activity_filter_quick_filter_period_values.get(pos).toString();
setTimePeriodFilter(selection);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
}

View File

@ -37,7 +37,7 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
@ -53,6 +53,7 @@ import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -67,6 +68,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.SwipeEvents;
//import nodomain.freeyourgadget.gadgetbridge.util.OnSwipeTouchListener;
public class ActivitySummaryDetail extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummaryDetail.class);
private GBDevice gbDevice;
@ -86,15 +89,20 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
}
Intent intent = getIntent();
gbDevice = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
final int filter = intent.getIntExtra("filter", 0);
final int position = intent.getIntExtra("position", 0);
final long dateFromFilter = intent.getLongExtra("dateFromFilter", 0);
final long dateToFilter = intent.getLongExtra("dateToFilter", 0);
final String nameContainsFilter = intent.getStringExtra("nameContainsFilter");
final ActivitySummaryItems items = new ActivitySummaryItems(this, gbDevice, filter, dateFromFilter, dateToFilter, nameContainsFilter);
final LinearLayout layout = findViewById(R.id.activity_summary_detail_relative_layout);
Bundle bundle = intent.getExtras();
gbDevice = bundle.getParcelable(GBDevice.EXTRA_DEVICE);
final int position = bundle.getInt("position", 0);
final int activityFilter = bundle.getInt("activityFilter", 0);
final long dateFromFilter = bundle.getLong("dateFromFilter", 0);
final long dateToFilter = bundle.getLong("dateToFilter", 0);
final long deviceFilter = bundle.getLong("deviceFilter", 0);
final String nameContainsFilter = bundle.getString("nameContainsFilter");
final List itemsFilter = (List<Long>) bundle.getSerializable("itemsFilter");
final ActivitySummaryItems items = new ActivitySummaryItems(this, gbDevice, activityFilter, dateFromFilter, dateToFilter, nameContainsFilter, deviceFilter, itemsFilter);
final ScrollView layout = findViewById(R.id.activity_summary_detail_scroll_layout);
//final LinearLayout layout = findViewById(R.id.activity_summary_detail_relative_layout);
alternateColor = getAlternateColor(this);
final Animation animFadeRight;
@ -115,7 +123,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
this,
R.anim.bounceright);
layout.setOnTouchListener(new SwipeEvents(this) {
@Override
public void onSwipeRight() {
@ -145,7 +152,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
}
});
currentItem = items.getItem(position);
if (currentItem != null) {
makeSummaryHeader(currentItem);
@ -193,7 +199,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
currentItem.update();
makeSummaryHeader(currentItem);
makeSummaryContent(currentItem);
}
})
.setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
@ -205,8 +210,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
.show();
}
});
}
private void makeSummaryHeader(BaseActivitySummary item) {
@ -265,7 +268,6 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
TableLayout fieldLayout = findViewById(R.id.summaryDetails);
fieldLayout.removeAllViews(); //remove old widgets
ActivitySummaryJsonSummary activitySummaryJsonSummary = new ActivitySummaryJsonSummary(item);
//JSONObject summarySubdata = activitySummaryJsonSummary.getSummaryData();
JSONObject data = activitySummaryJsonSummary.getSummaryGroupedList(); //get list, grouped by groups
if (data == null) return;
@ -275,12 +277,12 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
while (keys.hasNext()) {
String key = keys.next();
try {
LOG.error("SportsActivity:" + key + ": " + data.get(key) + "\n");
JSONArray innerList = (JSONArray) data.get(key);
TableRow label_row = new TableRow(ActivitySummaryDetail.this);
TextView label_field = new TextView(ActivitySummaryDetail.this);
label_field.setTextSize(16);
label_field.setPadding(0,10,0,0);
label_field.setTypeface(null, Typeface.BOLD);
label_field.setText(String.format("%s", getStringResourceByName(key)));
label_row.addView(label_field);
@ -306,13 +308,19 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
unit = "km_h";
break;
case "seconds_m":
value = value * (1000 / 60);
value = value * (1000 / 60D);
unit = "minutes_km";
break;
case "seconds_km":
value = value / 60;
unit = "minutes_km";
break;
case "meters":
if (value > 2000) {
value = value / 1000;
unit = "km";
}
break;
}
}

View File

@ -18,8 +18,6 @@
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.content.Context;
import android.content.res.Resources;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -79,6 +77,14 @@ public abstract class AbstractItemAdapter<T> extends ArrayAdapter<T> {
this.setNameContainsFilter(name);
}
public void setItemsFilter(List items) {
this.setItemsFilter(items);
}
public void setDeviceFilter(long device) {
this.setDeviceFilter(device);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
T item = getItem(position);
@ -143,5 +149,4 @@ public abstract class AbstractItemAdapter<T> extends ArrayAdapter<T> {
notifyDataSetChanged();
}
}
}

View File

@ -38,20 +38,26 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import static nodomain.freeyourgadget.gadgetbridge.activities.ActivitySummariesFilter.ALL_DEVICES;
public class ActivitySummariesAdapter extends AbstractItemAdapter<BaseActivitySummary> {
private final GBDevice device;
private int activityKindFilter;
long dateFromFilter=0;
long dateToFilter=0;
long deviceFilter;
String nameContainsFilter;
List<Long>itemsFilter;
public ActivitySummariesAdapter(Context context, GBDevice device, int activityKindFilter, long dateFromFilter, long dateToFilter, String nameContainsFilter) {
public ActivitySummariesAdapter(Context context, GBDevice device, int activityKindFilter, long dateFromFilter, long dateToFilter, String nameContainsFilter, long deviceFilter, List itemsFilter) {
super(context);
this.device = device;
this.activityKindFilter = activityKindFilter;
this.dateFromFilter=dateFromFilter;
this.dateToFilter=dateToFilter;
this.nameContainsFilter=nameContainsFilter;
this.dateFromFilter = dateFromFilter;
this.dateToFilter = dateToFilter;
this.nameContainsFilter = nameContainsFilter;
this.deviceFilter = deviceFilter;
this.itemsFilter = itemsFilter;
loadItems();
}
@ -62,9 +68,18 @@ public class ActivitySummariesAdapter extends AbstractItemAdapter<BaseActivitySu
Device dbDevice = DBHelper.findDevice(device, handler.getDaoSession());
QueryBuilder<BaseActivitySummary> qb = summaryDao.queryBuilder();
qb.where(
BaseActivitySummaryDao.Properties.DeviceId.eq(
dbDevice.getId())).orderDesc(BaseActivitySummaryDao.Properties.StartTime);
if (deviceFilter == ALL_DEVICES) {
qb.orderDesc(BaseActivitySummaryDao.Properties.StartTime);
} else if (deviceFilter != 0) {
qb.where(
BaseActivitySummaryDao.Properties.DeviceId.eq(
deviceFilter)).orderDesc(BaseActivitySummaryDao.Properties.StartTime);
} else {
qb.where(
BaseActivitySummaryDao.Properties.DeviceId.eq(
dbDevice.getId())).orderDesc(BaseActivitySummaryDao.Properties.StartTime);
}
if (activityKindFilter !=0) {
qb.where(
@ -83,7 +98,10 @@ public class ActivitySummariesAdapter extends AbstractItemAdapter<BaseActivitySu
qb.where(
BaseActivitySummaryDao.Properties.Name.like("%" + nameContainsFilter + "%"));
}
if (itemsFilter !=null) {
qb.where(
BaseActivitySummaryDao.Properties.Id.in(itemsFilter));
}
List<BaseActivitySummary> allSummaries = qb.build().list();
setItems(allSummaries, true);
} catch (Exception e) {
@ -103,7 +121,8 @@ public class ActivitySummariesAdapter extends AbstractItemAdapter<BaseActivitySu
public void setNameContainsFilter(String name){
this.nameContainsFilter=name;
}
public void setItemsFilter(List items) { this.itemsFilter = items; }
public void setDeviceFilter(long device) { this.deviceFilter = device; }
@Override
protected String getName(BaseActivitySummary item) {

View File

@ -9,21 +9,12 @@ import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class ActivitySummaryItems {
private final GBDevice device;
private int activityKindFilter;
List<BaseActivitySummary> allItems;
ActivitySummariesAdapter itemsAdapter;
private int current_position = 0;
long dateFromFilter=0;
long dateToFilter=0;
public ActivitySummaryItems(Context context, GBDevice device, int activityKindFilter, long dateFromFilter, long dateToFilter, String nameContainsFilter, long deviceFilter, List itemsFilter) {
public ActivitySummaryItems(Context context, GBDevice device, int activityKindFilter, long dateFromFilter, long dateToFilter, String nameContainsFilter) {
this.device = device;
this.activityKindFilter = activityKindFilter;
this.dateFromFilter=dateFromFilter;
this.dateToFilter=dateToFilter;
this.itemsAdapter = new ActivitySummariesAdapter(context, device, activityKindFilter, dateFromFilter, dateToFilter, nameContainsFilter);
this.itemsAdapter = new ActivitySummariesAdapter(context, device, activityKindFilter, dateFromFilter, dateToFilter, nameContainsFilter, deviceFilter, itemsFilter);
}
public BaseActivitySummary getItem(int position){
@ -35,10 +26,6 @@ public class ActivitySummaryItems {
return itemsAdapter.getPosition(item);
}
public List<BaseActivitySummary> getAllItems(){
return itemsAdapter.getItems();
}
public BaseActivitySummary getNextItem(){
if (current_position+1 < itemsAdapter.getCount()){
current_position+=1;
@ -54,9 +41,4 @@ public class ActivitySummaryItems {
}
return null;
}
public int getCurrent_position(){
return current_position;
}
}

View File

@ -25,6 +25,37 @@ public class ActivitySummaryJsonSummary {
private JSONObject setSummaryData(BaseActivitySummary item){
String summary = getCorrectSummary(item);
JSONObject jsonSummary = getJSONSummary(summary);
if (jsonSummary != null) {
//add additionally computed values here
if (item.getBaseAltitude() != null) {
JSONObject baseAltitudeValues;
try {
baseAltitudeValues = new JSONObject();
baseAltitudeValues.put("value", item.getBaseAltitude());
baseAltitudeValues.put("unit", "meters");
jsonSummary.put("baseAltitude", baseAltitudeValues);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (jsonSummary.has("distanceMeters") && jsonSummary.has("activeSeconds")) {
JSONObject averageSpeed;
try {
JSONObject distanceMeters = (JSONObject) jsonSummary.get("distanceMeters");
JSONObject activeSeconds = (JSONObject) jsonSummary.get("activeSeconds");
double distance = distanceMeters.getDouble("value");
double duration = activeSeconds.getDouble("value");
averageSpeed = new JSONObject();
averageSpeed.put("value", distance / duration);
averageSpeed.put("unit", "meters_second");
jsonSummary.put("averageSpeed", averageSpeed);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return jsonSummary;
}
@ -114,8 +145,8 @@ public class ActivitySummaryJsonSummary {
private JSONObject createActivitySummaryGroups(){
String groupDefinitions = "{'Strokes':['averageStrokeDistance','averageStrokesPerSecond','strokes'], " +
"'Swimming':['swolfIndex','swimStyle'], " +
"'Elevation':['ascentMeters','descentMeters','maxAltitude','minAltitude','ascentSeconds','descentSeconds','flatSeconds'], " +
"'Speed':['maxSpeed','minPace','maxPace','averageKMPaceSeconds'], " +
"'Elevation':['ascentMeters','descentMeters','maxAltitude','minAltitude','ascentSeconds','descentSeconds','flatSeconds', 'baseAltitude'], " +
"'Speed':['maxSpeed','minPace','maxPace','averageKMPaceSeconds', 'averageSpeed', 'averageSpeed2'], " +
"'Activity':['distanceMeters','steps','activeSeconds','caloriesBurnt','totalStride'," +
"'averageHR','averageStride'], " +
"'Laps':['averageLapPace','laps']}";

View File

@ -30,7 +30,12 @@ public class SwipeEvents implements View.OnTouchListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
@Override

View File

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/secondarytext"
android:pathData="M5.0391,4C4.2091,4 3.74,4.9494 4.25,5.6094C6.27,8.1994 10,13 10,13L10,19C10,19.55 10.45,20 11,20L13,20C13.55,20 14,19.55 14,19L14,13C14,13 14.5612,12.2766 14.6484,12.1641A6.0985,6.0985 0,0 1,13.1758 10.8105L11.9902,12.3008L7,6L11.9785,6A6.0985,6.0985 0,0 1,12.707 4L5.0391,4z"/>
<path
android:pathData="m16.7277,3.019l0,4.1223l4.1288,0L20.8565,8.3995L16.7277,8.3995L16.7277,12.5219L15.4824,12.5219L15.4824,8.3995L11.3537,8.3995L11.3537,7.1414L15.4824,7.1414L15.4824,3.019Z"
android:strokeLineJoin="miter"
android:strokeWidth="0.420925"
android:fillColor="@color/secondarytext"
android:strokeColor="#00000000"
android:strokeLineCap="butt"/>
</vector>

View File

@ -1,176 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_summary_detail_relative_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="false"
android:focusable="auto"
android:orientation="vertical"
android:padding="8dp">
android:id="@+id/activity_summary_detail_scroll_layout"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:scrollbars="vertical">
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/activity_summary_detail_relative_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?attr/sports_activity_summary_background"
android:orientation="horizontal">
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:id="@+id/item_image"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="false"
android:layout_gravity="center_vertical"
android:contentDescription="activity image" />
<LinearLayout
android:id="@+id/top_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="false"
android:clickable="false"
android:foregroundGravity="top"
android:gravity="top"
android:orientation="vertical"
android:paddingStart="8dp"
android:paddingEnd="8dp">
android:background="?attr/sports_activity_summary_background"
android:orientation="horizontal">
<ImageView
android:id="@+id/item_image"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:contentDescription="@string/icon_placeholder" />
<LinearLayout
android:id="@+id/top_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
android:layout_height="wrap_content"
android:foregroundGravity="top"
android:gravity="top"
android:orientation="vertical"
android:paddingStart="8dp"
android:paddingEnd="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/activitykind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-black"
android:maxLines="1"
android:scrollHorizontally="false"
android:textSize="18sp" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.1" />
<ImageView
android:id="@+id/activity_summary_detail_edit_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_weight="0.1"
android:contentDescription="@string/icon_placeholder"
android:scaleType="fitEnd"
app:srcCompat="@drawable/ic_create" />
</LinearLayout>
<TextView
android:id="@+id/activitykind"
android:id="@+id/activityname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-black"
android:maxLines="1"
android:scrollHorizontally="false"
android:singleLine="true"
android:textSize="18sp" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.1" />
<TableLayout
android:id="@+id/summaryHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/starttime_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/activity_detail_start_label" />
<TextView
android:id="@+id/starttime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/endtime_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/activity_detail_end_label" />
<TextView
android:id="@+id/endtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/duration_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/activity_detail_duration_label" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end" />
</TableRow>
</TableLayout>
<ImageView
android:id="@+id/activity_summary_detail_edit_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:layout_weight="0.1"
android:scaleType="fitEnd"
app:srcCompat="@drawable/ic_create" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/activityname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-black"
android:scrollHorizontally="false"
android:singleLine="true"
android:textSize="18sp" />
<LinearLayout
android:id="@+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />
<TableLayout
android:id="@+id/summaryHeader"
android:id="@+id/summaryDetails"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/starttime_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/activity_detail_start_label" />
<TextView
android:id="@+id/starttime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/endtime_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/activity_detail_end_label" />
<TextView
android:id="@+id/endtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/duration_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:text="@string/activity_detail_duration_label" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end" />
</TableRow>
</TableLayout>
android:layout_height="wrap_content" />
<Button
android:id="@+id/showTrack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/activity_detail_show_gps_label" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />
<TableLayout
android:id="@+id/summaryDetails"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/showTrack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/activity_detail_show_gps_label" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,11 @@
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="0dp"
android:paddingTop="0dp"
android:textSize="16sp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textColor="?android:attr/textColorTertiary" />

View File

@ -4,73 +4,65 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textView4"
<Spinner
android:id="@+id/select_device"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-black"
android:text="@string/activity_filter_filter_title" />
android:gravity="start|center_vertical"
android:spinnerMode="dropdown"
android:textAlignment="gravity" />
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Space android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" />
<Spinner
android:id="@+id/select_kind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/abc_spinner_textfield_background_material"
android:gravity="left|center_vertical"
android:gravity="start|center_vertical"
android:spinnerMode="dropdown"
android:textAlignment="gravity" />
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Space android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" />
<LinearLayout
android:id="@+id/filtername"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/abc_spinner_textfield_background_material"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingStart="10dp"
android:paddingEnd="4dp"
android:paddingBottom="20dp">
<TextView
android:id="@+id/textViewNamelabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activity_filter_name_contains"
android:textAlignment="textStart"
android:textSize="18sp" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
android:orientation="horizontal"
android:paddingBottom="5dp">
<EditText
android:id="@+id/textViewNameData"
android:layout_width="fill_parent"
android:hint="@string/activity_filter_name_contains"
android:layout_height="wrap_content"
android:inputType="text"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textAlignment="textStart"
android:textSize="18sp" />
android:textSize="16sp"
android:autofillHints="@string/activity_filter_name_contains" />
</LinearLayout>
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Space android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" />
<LinearLayout
android:id="@+id/filterfrom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/abc_spinner_textfield_background_material"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="4dp"
android:paddingBottom="20dp">
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/textViewFromLabel"
@ -78,7 +70,7 @@
android:layout_height="wrap_content"
android:text="@string/activity_filter_date_from"
android:textAlignment="textStart"
android:textSize="18sp" />
android:textSize="16sp" />
<View
android:layout_width="0dp"
@ -89,21 +81,20 @@
android:id="@+id/textViewFromData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="30dp"
android:textAlignment="textStart"
android:textSize="18sp" />
android:textSize="16sp" />
</LinearLayout>
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Space android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" />
<LinearLayout
android:id="@+id/filterto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/abc_spinner_textfield_background_material"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="4dp"
android:paddingBottom="20dp">
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/textViewTolabel"
@ -111,7 +102,7 @@
android:layout_height="wrap_content"
android:text="@string/activity_filter_date_to"
android:textAlignment="textStart"
android:textSize="18sp" />
android:textSize="16sp" />
<View
android:layout_width="0dp"
@ -122,12 +113,54 @@
android:id="@+id/textViewToData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="30dp"
android:textAlignment="textStart"
android:textSize="18sp" />
android:textSize="16sp" />
</LinearLayout>
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Spinner
android:id="@+id/quick_filter_period_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
android:spinnerMode="dropdown"
android:textAlignment="gravity" />
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Space android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" />
<LinearLayout
android:id="@+id/filteritems"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/textViewItemslabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activity_filter_individual_items"
android:textAlignment="textStart"
android:textSize="16sp" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:id="@+id/textViewItemsData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="textStart"
android:textSize="16sp" />
</LinearLayout>
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1.5dp"/>
<Space android:background="#000" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" />
<Button
android:id="@+id/reset_filter_button"
@ -137,7 +170,7 @@
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button

View File

@ -2,6 +2,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/activity_action_addto_filter"
android:icon="@drawable/ic_filter_alt_plus"
android:title="@string/addto_filter"
app:showAsAction="ifRoom" />
<item
android:id="@+id/activity_action_select_all"
@ -19,6 +24,5 @@
android:id="@+id/activity_action_delete"
android:icon="@drawable/ic_delete_forever"
android:title="@string/Delete"
app:showAsAction="always"/>
app:showAsAction="never"/>
</menu>

View File

@ -958,4 +958,22 @@
<item>workoutApp</item>
</string-array>
<string-array name="activity_filter_quick_filter_period_items">
<item>@string/sports_activity_quick_filter_select</item>
<item>@string/sports_activity_quick_filter_this_week</item>
<item>@string/sports_activity_quick_filter_this_month</item>
<item>@string/sports_activity_quick_filter_last_week</item>
<item>@string/sports_activity_quick_filter_last_month</item>
<item>@string/sports_activity_quick_filter_7days</item>
<item>@string/sports_activity_quick_filter_30days</item>
</string-array>
<string-array name="activity_filter_quick_filter_period_values">
<item>noselection</item>
<item>thisweek</item>
<item>thismonth</item>
<item>lastweek</item>
<item>lastmonth</item>
<item>7days</item>
<item>30days</item>
</string-array>
</resources>

View File

@ -938,6 +938,8 @@
<string name="ascentSeconds">Ascending</string>
<string name="descentSeconds">Descending</string>
<string name="flatSeconds">Flat</string>
<string name="baseAltitude">Base Elevation</string>
<string name="averageSpeed">Average Speed</string>
<!-- activity summary units-->
<string name="meters">m</string>
<string name="cm">cm</string>
@ -988,8 +990,21 @@
<string name="activity_filter_filter_title">Filter</string>
<string name="activity_filter_name_contains">Label</string>
<string name="activity_filter_apply_filter">Apply Filter</string>
<string name="addto_filter">Add to filter</string>
<string name="activity_filter_individual_items">Individually selected items</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="activity_summaries_statistics">Statistics</string>
<string name="activity_summaries_all_activities">All Activities</string>
<string name="sports_activity_quick_filter_this_week">This week</string>
<string name="sports_activity_quick_filter_last_week">Previous week</string>
<string name="sports_activity_quick_filter_this_month">This month</string>
<string name="sports_activity_quick_filter_last_month">Previous month</string>
<string name="sports_activity_quick_filter_7days">7 days</string>
<string name="sports_activity_quick_filter_30days">30 days</string>
<string name="sports_activity_quick_filter_select">Time period</string>
<string name="activity_summaries_all_devices">All devices</string>
<!-- swim styles -->
<string name="breaststroke">Breaststroke</string>