Added a label to exercise sets that shows the minimum time it takes to complete an exercise set. Also some minor bugfixes.

This commit is contained in:
Christopher Beckmann 2018-05-07 13:19:54 +02:00
commit 11ff7ae10f
23 changed files with 367 additions and 69 deletions

77
.idea/codeStyles/Project.xml generated Normal file
View file

@ -0,0 +1,77 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<DBN-PSQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<DBN-PSQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
</code_scheme>
</component>

View file

@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '26.0.2'
buildToolsVersion '26.0.3'
defaultConfig {
applicationId "org.secuso.privacyfriendlybreakreminder"
@ -12,6 +12,12 @@ android {
versionName "2.1"
vectorDrawables.useSupportLibrary = true
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
buildTypes {
release {
minifyEnabled false
@ -34,11 +40,11 @@ dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.android.support:design:25.4.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.github.bumptech.glide:glide:4.0.0'
compile 'com.android.support:support-v4:25.4.0'
compile 'com.android.support:support-annotations:27.0.0'
compile 'com.android.support:support-annotations:27.1.1'
compile 'com.android.support:cardview-v7:25.4.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support.constraint:constraint-layout:1.1.0'
compile 'com.nex3z:flow-layout:1.0.0'
compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:2.0.1'
testCompile 'junit:junit:4.12'

View file

@ -1,6 +1,8 @@
package org.secuso.privacyfriendlybreakreminder.activities;
import android.content.Intent;
import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.Pair;
import android.support.v7.app.ActionBar;
@ -20,6 +22,7 @@ import android.widget.ToggleButton;
import org.secuso.privacyfriendlybreakreminder.R;
import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter;
import org.secuso.privacyfriendlybreakreminder.activities.helper.IExerciseTimeUpdateable;
import org.secuso.privacyfriendlybreakreminder.database.SQLiteHelper;
import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
import com.nex3z.flowlayout.FlowLayout;
@ -40,7 +43,7 @@ import static org.secuso.privacyfriendlybreakreminder.activities.adapter.Exercis
* @version 2.0
* @see EditExerciseSetActivity
*/
public class ChooseExerciseActivity extends AppCompatActivity {
public class ChooseExerciseActivity extends AppCompatActivity implements IExerciseTimeUpdateable {
private static final String TAG = ChooseExerciseActivity.class.getSimpleName();
@ -48,6 +51,7 @@ public class ChooseExerciseActivity extends AppCompatActivity {
FlowLayout filterButtonLayout;
RecyclerView exerciseList;
TextView exerciseSetTimeText;
ExerciseAdapter exerciseAdapter;
SQLiteHelper databaseHelper;
@ -76,12 +80,19 @@ public class ChooseExerciseActivity extends AppCompatActivity {
exerciseAdapter.setCheckedItems(chosenExercisesList);
}
@Override
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
update(0);
}
private void initResources() {
databaseHelper = new SQLiteHelper(this);
filterButtonLayout = (FlowLayout) findViewById(R.id.layout_filter_buttons);
exerciseList = (RecyclerView) findViewById(R.id.exercise_list);
exerciseAdapter = new ExerciseAdapter(this, ID_COMPARATOR);
exerciseAdapter = new ExerciseAdapter(this, ID_COMPARATOR, this);
exerciseAdapter.showCheckboxes(true);
GridLayoutManager gridLayout = new GridLayoutManager(this, 3);
@ -120,12 +131,16 @@ public class ChooseExerciseActivity extends AppCompatActivity {
exerciseAdapter.replaceAll(databaseHelper.getExerciseListBySections(ExerciseLocale.getLocale(), filterSections));
exerciseList.scrollToPosition(0);
update(0);
}
});
buttons.add(button);
filterButtonLayout.addView(view);
}
exerciseSetTimeText = (TextView) findViewById(R.id.exercise_set_time);
update(0);
}
@ -171,4 +186,9 @@ public class ChooseExerciseActivity extends AppCompatActivity {
result.putExtra(EXTRA_SELECTED_EXERCISES, selectedIds);
setResult(RESULT_OK, result);
}
@Override
public void update(int i) {
exerciseSetTimeText.setText(getString(R.string.exercise_time, exerciseAdapter.getExerciseTimeString()));
}
}

View file

@ -4,6 +4,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.DialogInterface;
import android.content.Intent;
import android.preference.PreferenceManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar;
@ -27,6 +28,8 @@ import android.widget.TextView;
import android.widget.Toast;
import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter;
import org.secuso.privacyfriendlybreakreminder.activities.helper.IExerciseTimeUpdateable;
import org.secuso.privacyfriendlybreakreminder.activities.tutorial.FirstLaunchManager;
import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
import org.secuso.privacyfriendlybreakreminder.exercises.ExerciseLocale;
import org.secuso.privacyfriendlybreakreminder.R;
@ -34,7 +37,15 @@ import org.secuso.privacyfriendlybreakreminder.database.SQLiteHelper;
import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.xml.datatype.Duration;
import static org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter.ID_COMPARATOR;
@ -69,6 +80,7 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
private boolean nameChanged = false;
private boolean modificationsDone = false;
private SQLiteHelper mDbHelper;
private TextView exerciseSetTimeText;
//methods
@ -89,6 +101,16 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
initResources();
getSupportLoaderManager().initLoader(0, null, this);
updateExerciseTime();
}
private void updateExerciseTime() {
List<Integer> ids = new LinkedList<>();
for(Exercise e : mAdapter.getExercises()) {
ids.add(e.getId());
}
exerciseSetTimeText.setText(getString(R.string.exercise_time, mAdapter.getExerciseTimeString(ids)));
}
private void initResources() {
@ -96,10 +118,11 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
toolbar = (Toolbar) findViewById(R.id.toolbar);
exerciseSetNameText = (TextView) findViewById(R.id.exercise_set_name);
exerciseList = (RecyclerView) findViewById(R.id.exercise_list);
mAdapter = new ExerciseAdapter(this, ID_COMPARATOR);
mAdapter = new ExerciseAdapter(this, ID_COMPARATOR, null);
exerciseList.setAdapter(mAdapter);
exerciseList.setLayoutManager(new GridLayoutManager(this, 3));
loadingSpinner = (ProgressBar) findViewById(R.id.loading_spinner);
exerciseSetTimeText = (TextView) findViewById(R.id.exercise_set_time);
exerciseSetNameText.setText(exerciseSetName);
exerciseSetNameText.addTextChangedListener(new TextWatcher() {
@ -165,6 +188,7 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
if(set != null) {
mAdapter.replaceAll(set.getExercises());
}
updateExerciseTime();
// load data only once
getSupportLoaderManager().destroyLoader(0);
@ -334,6 +358,7 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
}
mAdapter.replaceAll(newList);
updateExerciseTime();
}
}
}

View file

@ -157,6 +157,7 @@ public class ExerciseActivity extends AppCompatActivity implements android.suppo
prevButton = (ImageButton) findViewById(R.id.button_prev);
nextButton = (ImageButton) findViewById(R.id.button_next);
exerciseInfoButton = (ImageButton) findViewById(R.id.exercise_info_button);
toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
toast.setGravity(toast.getGravity(), 0, 250);

View file

@ -1,6 +1,7 @@
package org.secuso.privacyfriendlybreakreminder.activities.adapter;
import android.content.Context;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AlertDialog;
@ -16,17 +17,22 @@ import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import org.secuso.privacyfriendlybreakreminder.R;
import org.secuso.privacyfriendlybreakreminder.activities.ChooseExerciseActivity;
import org.secuso.privacyfriendlybreakreminder.activities.helper.IExerciseTimeUpdateable;
import org.secuso.privacyfriendlybreakreminder.activities.tutorial.FirstLaunchManager;
import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
import org.secuso.privacyfriendlybreakreminder.dialog.ExerciseDialog;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
/**
* @author Christopher Beckmann
@ -36,6 +42,7 @@ import java.util.List;
*/
public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private IExerciseTimeUpdateable mListener;
private Context mContext;
private List<Integer> checkedIds = new ArrayList<>();
private boolean mShowCheckboxes = false;
@ -43,12 +50,13 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public static final Comparator<Exercise> ID_COMPARATOR = new Comparator<Exercise>() {
@Override
public int compare(Exercise a, Exercise b) {
return (a.getId() < b.getId()) ? -1 : ((a.getId() == b.getId()) ? 0 : 1);
return Integer.compare(a.getId(), b.getId());
}
};
private final LayoutInflater mInflater;
private final Comparator<Exercise> mComparator;
private final List<Exercise> mAllExercises = new ArrayList<>();
private final SortedList<Exercise> mSortedList = new SortedList<>(Exercise.class, new SortedList.Callback<Exercise>() {
@Override
public void onInserted(int position, int count) {
@ -86,7 +94,8 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
});
public ExerciseAdapter(Context context, Comparator<Exercise> comparator) {
public ExerciseAdapter(Context context, Comparator<Exercise> comparator, IExerciseTimeUpdateable listener) {
this.mListener = listener;
this.mContext = context;
this.mComparator = comparator;
this.mInflater = LayoutInflater.from(context);
@ -122,10 +131,12 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
vh.checkbox.setChecked(!vh.checkbox.isChecked());
notifyListeners();
}
};
Glide.with(mContext).load(exercise.getImageResIds(mContext)[0]).into(vh.image);
Glide.with(mContext).load(exercise.getImageResIds(mContext)[0]).transition(DrawableTransitionOptions.withCrossFade()).into(vh.image);
//vh.image.setImageResource(exercise.getImageResIds(mContext)[0]);
if(checkedIds != null)
@ -146,6 +157,12 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
vh.infoButton.setOnClickListener(infoClick);
}
private void notifyListeners() {
if(mListener != null) {
mListener.update(getExerciseCount(null));
}
}
@Override
public int getItemCount() {
return mSortedList.size();
@ -161,6 +178,16 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
mSortedList.addAll(exercises);
mSortedList.endBatchedUpdates();
setAllExercises(exercises);
notifyListeners();
}
public void setAllExercises(List<Exercise> exercises) {
for(Exercise e : exercises) {
if(!mAllExercises.contains(e)) {
mAllExercises.add(e);
}
}
}
public List<Integer> getCheckedIds() {
@ -169,14 +196,19 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public void add(Exercise model) {
mSortedList.add(model);
setAllExercises(Collections.singletonList(model));
notifyListeners();
}
public void remove(Exercise model) {
mSortedList.remove(model);
notifyListeners();
}
public void add(List<Exercise> models) {
mSortedList.addAll(models);
setAllExercises(models);
notifyListeners();
}
public void remove(List<Exercise> models) {
@ -185,10 +217,12 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
mSortedList.remove(model);
}
mSortedList.endBatchedUpdates();
notifyListeners();
}
public void setCheckedItems(@NonNull List<Integer> checkedItems) {
this.checkedIds = checkedItems;
notifyListeners();
}
public List<Exercise> getExercises() {
@ -202,6 +236,31 @@ public class ExerciseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return result;
}
public int getExerciseCount(List<Integer> specificIds) {
int result = 0;
for (int id : (specificIds == null ? checkedIds : specificIds)) {
for (Exercise e : mAllExercises) {
if (e.getId() == id) {
result += e.getImageID().split(",").length;
break;
}
}
}
return result;
}
public String getExerciseTimeString() {
return getExerciseTimeString(null);
}
public String getExerciseTimeString(List<Integer> specificIds) {
long exerciseDuration = Long.parseLong(PreferenceManager.getDefaultSharedPreferences(mContext).getString(FirstLaunchManager.EXERCISE_DURATION, "30"));
int seconds = (int) (getExerciseCount(specificIds) * exerciseDuration);
return String.format(Locale.getDefault(), "%02d:%02d", (seconds / 60), (seconds % 60));
}
public class ExerciseViewHolder extends RecyclerView.ViewHolder {
ImageView image;

View file

@ -15,16 +15,19 @@ import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import org.secuso.privacyfriendlybreakreminder.R;
import org.secuso.privacyfriendlybreakreminder.activities.EditExerciseSetActivity;
import org.secuso.privacyfriendlybreakreminder.activities.ManageExerciseSetsActivity;
import org.secuso.privacyfriendlybreakreminder.activities.tutorial.FirstLaunchManager;
import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
/**
@ -114,6 +117,11 @@ public class ExerciseSetListAdapter extends RecyclerView.Adapter<RecyclerView.Vi
}
} else {
if(set.isDefaultSet()) {
Toast.makeText(mContext, R.string.exercise_set_can_not_be_edited, Toast.LENGTH_SHORT).show();
return;
}
Intent i = new Intent(mContext, EditExerciseSetActivity.class);
i.putExtra(EditExerciseSetActivity.EXTRA_EXERCISE_SET_ID, set.getId());
i.putExtra(EditExerciseSetActivity.EXTRA_EXERCISE_SET_NAME, set.getName());
@ -152,15 +160,26 @@ public class ExerciseSetListAdapter extends RecyclerView.Adapter<RecyclerView.Vi
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_round_exercise_image, null, false);
ImageView image = (ImageView) view.findViewById(R.id.exercise_image);
Glide.with(mContext).load(set.get(i).getImageResIds(mContext)[0]).into(image);
Glide.with(mContext).load(set.get(i).getImageResIds(mContext)[0]).transition(DrawableTransitionOptions.withCrossFade()).into(image);
vh.exerciseList.addView(view);
}
if(set.size() == 0) {
vh.noExercisesText.setVisibility(View.VISIBLE);
vh.exerciseTime.setVisibility(View.GONE);
} else {
vh.noExercisesText.setVisibility(View.GONE);
vh.exerciseTime.setVisibility(View.VISIBLE);
int result = 0;
for(Exercise e : set.getExercises()) {
result += e.getImageID().split(",").length;
}
long exerciseDuration = Long.parseLong(PreferenceManager.getDefaultSharedPreferences(mContext).getString(FirstLaunchManager.EXERCISE_DURATION, "30"));
int seconds = (int) (result * exerciseDuration);
vh.exerciseTime.setText(String.format(Locale.getDefault(), "%02d:%02d", (seconds / 60), (seconds % 60)));
}
}
@ -193,6 +212,7 @@ public class ExerciseSetListAdapter extends RecyclerView.Adapter<RecyclerView.Vi
CardView card;
TextView noExercisesText;
CheckBox deleteCheckBox;
TextView exerciseTime;
public ExerciseSetViewHolder(View itemView) {
super(itemView);
@ -202,6 +222,7 @@ public class ExerciseSetListAdapter extends RecyclerView.Adapter<RecyclerView.Vi
exerciseList = (LinearLayout) itemView.findViewById(R.id.exercise_list);
noExercisesText = (TextView) itemView.findViewById(R.id.exercise_none_available);
deleteCheckBox = (CheckBox) itemView.findViewById(R.id.delete_check_box);
exerciseTime = (TextView) itemView.findViewById(R.id.exercise_set_time_short);
}
}
}

View file

@ -15,13 +15,16 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import org.secuso.privacyfriendlybreakreminder.R;
import org.secuso.privacyfriendlybreakreminder.activities.tutorial.FirstLaunchManager;
import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
/**
* @author Christopher Beckmann
@ -68,6 +71,7 @@ public class ExerciseSetSpinnerAdapter extends ArrayAdapter<ExerciseSet> {
TextView name = (TextView) row.findViewById(R.id.exercise_set_name);
LinearLayout exerciseList = (LinearLayout) row.findViewById(R.id.exercise_list);
TextView noExercisesText = (TextView) row.findViewById(R.id.exercise_none_available);
TextView exerciseTime = (TextView) row.findViewById(R.id.exercise_set_time_short);
card.setClickable(false);
card.setLongClickable(false);
@ -80,15 +84,26 @@ public class ExerciseSetSpinnerAdapter extends ArrayAdapter<ExerciseSet> {
View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_round_exercise_image, null, false);
ImageView image = (ImageView) view.findViewById(R.id.exercise_image);
Glide.with(getContext()).load(set.get(i).getImageResIds(getContext())[0]).into(image);
Glide.with(getContext()).load(set.get(i).getImageResIds(getContext())[0]).transition(DrawableTransitionOptions.withCrossFade()).into(image);
exerciseList.addView(view);
}
if(set.size() == 0) {
noExercisesText.setVisibility(View.VISIBLE);
exerciseTime.setVisibility(View.GONE);
} else {
noExercisesText.setVisibility(View.GONE);
exerciseTime.setVisibility(View.VISIBLE);
int result = 0;
for(Exercise e : set.getExercises()) {
result += e.getImageID().split(",").length;
}
long exerciseDuration = Long.parseLong(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(FirstLaunchManager.EXERCISE_DURATION, "30"));
int seconds = (int) (result * exerciseDuration);
exerciseTime.setText(String.format(Locale.getDefault(), "%02d:%02d", (seconds / 60), (seconds % 60)));
}
return row;

View file

@ -0,0 +1,11 @@
package org.secuso.privacyfriendlybreakreminder.activities.helper;
/**
* @author Christopher Beckmann (Kamuno)
* @version 1.0
* @since 04.05.2018
* created 04.05.2018
*/
public interface IExerciseTimeUpdateable {
void update(int i);
}

View file

@ -48,7 +48,6 @@ public class TutorialActivity extends AppCompatActivity {
private FirstLaunchManager firstLaunchManager;
private static final String TAG = TutorialActivity.class.getSimpleName();
public static final String ACTION_SHOW_ANYWAYS = TAG + ".ACTION_SHOW_ANYWAYS";
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -80,14 +79,12 @@ public class TutorialActivity extends AppCompatActivity {
viewPager.setAdapter(myViewPagerAdapter);
viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
btnSkip.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick (View v){
launchHomeScreen();
}
});
btnSkip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick (View v){
launchHomeScreen();
}
});
btnNext.setOnClickListener(new View.OnClickListener()

View file

@ -25,6 +25,7 @@ public final class ExerciseColumns {
SECTION,
IMAGE_ID,
};
public static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + TABLE_NAME;
public static Exercise fromCursor(Cursor c) {

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M22,5.72l-4.6,-3.86 -1.29,1.53 4.6,3.86L22,5.72zM7.88,3.39L6.6,1.86 2,5.71l1.29,1.53 4.59,-3.85zM12.5,8L11,8v6l4.75,2.85 0.75,-1.23 -4,-2.37L12.5,8zM12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"
android:fillColor="#FFFFFF"/>
</vector>

View file

@ -10,18 +10,34 @@
android:id="@+id/layout_filter_buttons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:flChildSpacing="8dp"
app:flChildSpacingForLastRow="align"
app:flRowSpacing="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@+id/exercise_set_time"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/exercise_set_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" />
android:drawableStart="@drawable/ic_alarm_black"
android:gravity="center"
android:text="@string/exercise_time"
android:textColor="@color/black"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/layout_filter_buttons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/exercise_list"

View file

@ -7,6 +7,7 @@
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -22,21 +23,48 @@
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
<EditText
android:id="@+id/exercise_set_name"
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:background="@color/transparent"
android:hint="@string/activity_edit_exercise_set_name_hint"
android:inputType="textAutoCorrect"
android:maxLength="40"
android:maxLines="1"
android:textColor="@color/white"
android:textColorHint="@color/white"/>
android:layout_height="match_parent">
<EditText
android:id="@+id/exercise_set_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginStart="8dp"
android:background="@color/transparent"
android:hint="@string/activity_edit_exercise_set_name_hint"
android:inputType="textAutoCorrect"
android:maxLength="35"
android:maxLines="1"
android:textColor="@color/white"
android:textColorHint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/exercise_set_time"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/exercise_set_time"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:drawableStart="@drawable/ic_alarm_white"
android:gravity="center"
android:text="@string/exercise_time"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.AppBarLayout>
@ -50,12 +78,8 @@
android:id="@+id/exercise_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
@ -83,12 +107,11 @@
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_alignParentBottom="true"
android:clickable="true"
android:focusable="true"
android:onClick="onClick"
app:fabSize="normal"
app:layout_anchor="@id/constraintLayout2"
app:layout_anchorGravity="bottom|end"
android:layout_gravity="bottom|end"
app:srcCompat="@drawable/ic_edit_white_24dp" />
</android.support.design.widget.CoordinatorLayout>

View file

@ -122,13 +122,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:clickable="true"
android:onClick="onClick"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ProgressBar

View file

@ -9,6 +9,7 @@
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.secuso.privacyfriendlybreakreminder.activities.EditExerciseSetActivity">
@ -68,11 +69,11 @@
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end"
android:clickable="true"
android:onClick="onClick"
app:fabSize="normal"
app:layout_anchor="@id/main_content"
app:layout_anchorGravity="bottom|end"
app:srcCompat="@drawable/ic_add_white_24dp" />
</android.support.design.widget.CoordinatorLayout>

View file

@ -2,27 +2,25 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/exercise_layout"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:padding="0dp"
app:layout_constraintDimensionRatio="h,1:1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="120dp">
android:layout_marginBottom="4dp"
android:layout_marginEnd="4dp"
android:minHeight="120dp"
android:padding="0dp"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintHeight_min="120dp">
<ImageView
android:id="@+id/exercise_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/exercise_info_button"
@ -31,9 +29,9 @@
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:padding="4dp"
android:background="?android:selectableItemBackgroundBorderless"
android:hapticFeedbackEnabled="true"
android:padding="4dp"
app:layout_constraintRight_toRightOf="@+id/exercise_image"
app:layout_constraintTop_toTopOf="@+id/exercise_image"
app:srcCompat="@drawable/ic_about" />

View file

@ -56,6 +56,20 @@
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_mode_edit_black_24dp" />
<TextView
android:id="@+id/exercise_set_time_short"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:drawableStart="@drawable/ic_alarm_black"
android:gravity="center"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/exercise_set_name"
android:layout_width="wrap_content"

View file

@ -147,7 +147,11 @@
<string name="set_default_4">Hüftbeschwerden</string>
<string name="set_default_5">Kniebeschwerden</string>
<string name="pref_category_default_exercise_sets">Standard Übungssets</string>
<string name="pref_hide_default_exercise_sets">Standard Übungssets verstecken</string>
<string name="exercise_set_can_not_be_deleted">Dieses Set kann nicht gelöscht werden. In den Einstellungen können die voreingespeicherten Sets ausgeblendet werden.</string>
<string name="exercise_set_can_not_be_edited">Dieses Set kann nicht editiert werden.</string>
<string name="activity_exercise_button_prev">vorherige Übung</string>
<string name="activity_exercise_button_next">nächste Übung</string>

View file

@ -12,7 +12,7 @@
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<!-- <item name="android:statusBarColor">@android:color/transparent</item> -->
</style>
<style name="TimePickerDialogStyle" parent="@android:style/Widget.Material.Light.TimePicker">

View file

@ -144,6 +144,7 @@
<string name="pref_hide_default_exercise_sets">Hide default exercise sets</string>
<string name="exercise_set_can_not_be_deleted">This set can not be deleted. These sets can be hidden via the settings page.</string>
<string name="exercise_set_can_not_be_edited">This set can not be edited.</string>
<string name="activity_exercise_button_prev">previous exercise</string>
<string name="activity_exercise_button_next">next exercise</string>
@ -151,6 +152,7 @@
<string name="activity_exercise_button_repeat_off">repeat exercises off</string>
<string name="activity_exercise_button_continuous_on">start timers automatically</string>
<string name="activity_exercise_button_continuous_off">start timers manually</string>
<string name="exercise_time">Execise Time:\n%s</string>
</resources>

View file

@ -7,6 +7,7 @@ buildscript {
url 'https://maven.google.com/'
name 'Google'
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'

View file

@ -1,6 +1,6 @@
#Fri Oct 27 05:33:03 CEST 2017
#Thu May 03 14:39:54 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip