forked from github/wulkanowy-mirror
Add a summary of grades (#127)
This commit is contained in:

committed by
Mikołaj Pich

parent
dde5775a41
commit
0e16519baf
@ -24,12 +24,12 @@ import eu.davidea.viewholders.ExpandableViewHolder;
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Day;
|
||||
|
||||
public class AttendanceHeaderItem
|
||||
extends AbstractExpandableHeaderItem<AttendanceHeaderItem.HeaderViewHolder, AttendanceSubItem> {
|
||||
public class AttendanceHeader
|
||||
extends AbstractExpandableHeaderItem<AttendanceHeader.HeaderViewHolder, AttendanceSubItem> {
|
||||
|
||||
private Day day;
|
||||
|
||||
AttendanceHeaderItem(Day day) {
|
||||
AttendanceHeader(Day day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public class AttendanceHeaderItem
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
AttendanceHeaderItem that = (AttendanceHeaderItem) o;
|
||||
AttendanceHeader that = (AttendanceHeader) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(day, that.day)
|
@ -23,11 +23,11 @@ import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
|
||||
import io.github.wulkanowy.ui.main.attendance.AttendanceDialogFragment;
|
||||
|
||||
class AttendanceSubItem
|
||||
extends AbstractSectionableItem<AttendanceSubItem.SubItemViewHolder, AttendanceHeaderItem> {
|
||||
extends AbstractSectionableItem<AttendanceSubItem.SubItemViewHolder, AttendanceHeader> {
|
||||
|
||||
private AttendanceLesson lesson;
|
||||
|
||||
AttendanceSubItem(AttendanceHeaderItem header, AttendanceLesson lesson) {
|
||||
AttendanceSubItem(AttendanceHeader header, AttendanceLesson lesson) {
|
||||
super(header);
|
||||
this.lesson = lesson;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ public interface AttendanceTabContract {
|
||||
|
||||
interface View extends BaseContract.View {
|
||||
|
||||
void updateAdapterList(List<AttendanceHeaderItem> headerItems);
|
||||
void updateAdapterList(List<AttendanceHeader> headerItems);
|
||||
|
||||
void onRefreshSuccess();
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab
|
||||
AttendanceTabContract.Presenter presenter;
|
||||
|
||||
@Inject
|
||||
FlexibleAdapter<AttendanceHeaderItem> adapter;
|
||||
FlexibleAdapter<AttendanceHeader> adapter;
|
||||
|
||||
private boolean isFragmentVisible = false;
|
||||
|
||||
@ -83,7 +83,7 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdapterList(List<AttendanceHeaderItem> headerItems) {
|
||||
public void updateAdapterList(List<AttendanceHeader> headerItems) {
|
||||
adapter.updateDataSet(headerItems);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ public abstract class AttendanceTabModule {
|
||||
|
||||
@PerChildFragment
|
||||
@Provides
|
||||
static FlexibleAdapter<AttendanceHeaderItem> provideAdapter() {
|
||||
static FlexibleAdapter<AttendanceHeader> provideAdapter() {
|
||||
return new FlexibleAdapter<>(null);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class AttendanceTabPresenter extends BasePresenter<AttendanceTabContract.
|
||||
|
||||
private AbstractTask loadingTask;
|
||||
|
||||
private List<AttendanceHeaderItem> headerItems = new ArrayList<>();
|
||||
private List<AttendanceHeader> headerItems = new ArrayList<>();
|
||||
|
||||
private String date;
|
||||
|
||||
@ -115,7 +115,7 @@ public class AttendanceTabPresenter extends BasePresenter<AttendanceTabContract.
|
||||
|
||||
for (Day day : dayList) {
|
||||
day.resetAttendanceLessons();
|
||||
AttendanceHeaderItem headerItem = new AttendanceHeaderItem(day);
|
||||
AttendanceHeader headerItem = new AttendanceHeader(day);
|
||||
|
||||
if (isEmptyWeek) {
|
||||
isEmptyWeek = day.getAttendanceLessons().isEmpty();
|
||||
|
@ -18,11 +18,11 @@ import eu.davidea.viewholders.FlexibleViewHolder;
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Day;
|
||||
|
||||
public class ExamsHeaderItem extends AbstractHeaderItem<ExamsHeaderItem.HeaderVieHolder> {
|
||||
public class ExamsHeader extends AbstractHeaderItem<ExamsHeader.HeaderVieHolder> {
|
||||
|
||||
private Day day;
|
||||
|
||||
ExamsHeaderItem(Day day) {
|
||||
ExamsHeader(Day day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ public class ExamsHeaderItem extends AbstractHeaderItem<ExamsHeaderItem.HeaderVi
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ExamsHeaderItem that = (ExamsHeaderItem) o;
|
||||
ExamsHeader that = (ExamsHeader) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(day, that.day)
|
@ -21,11 +21,11 @@ import io.github.wulkanowy.data.db.dao.entities.Exam;
|
||||
import io.github.wulkanowy.ui.main.exams.ExamsDialogFragment;
|
||||
|
||||
public class ExamsSubItem
|
||||
extends AbstractSectionableItem<ExamsSubItem.SubItemViewHolder, ExamsHeaderItem> {
|
||||
extends AbstractSectionableItem<ExamsSubItem.SubItemViewHolder, ExamsHeader> {
|
||||
|
||||
private Exam exam;
|
||||
|
||||
ExamsSubItem(ExamsHeaderItem header, Exam exam) {
|
||||
ExamsSubItem(ExamsHeader header, Exam exam) {
|
||||
super(header);
|
||||
this.exam = exam;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public class ExamsTabPresenter extends BasePresenter<ExamsTabContract.View>
|
||||
|
||||
for (Day day : dayList) {
|
||||
day.resetExams();
|
||||
ExamsHeaderItem headerItem = new ExamsHeaderItem(day);
|
||||
ExamsHeader headerItem = new ExamsHeader(day);
|
||||
|
||||
List<Exam> examList = day.getExams();
|
||||
|
||||
|
@ -12,7 +12,9 @@ public interface GradesContract {
|
||||
|
||||
interface View extends BaseContract.View, SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
void updateAdapterList(List<GradeHeaderItem> headerItems);
|
||||
void updateAdapterList(List<GradesHeader> headerItems);
|
||||
|
||||
void updateSummaryAdapterList(List<GradesSummarySubItem> summarySubItems);
|
||||
|
||||
void showNoItem(boolean show);
|
||||
|
||||
@ -28,6 +30,8 @@ public interface GradesContract {
|
||||
|
||||
boolean isMenuVisible();
|
||||
|
||||
void setSummaryAverages(String calculatedValue, String predictedValue, String finalValue );
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BaseContract.Presenter<View> {
|
||||
|
@ -71,7 +71,7 @@ public class GradesDialogFragment extends DialogFragment {
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.grade_dialog, container, false);
|
||||
View view = inflater.inflate(R.layout.grades_dialog, container, false);
|
||||
|
||||
ButterKnife.bind(this, view);
|
||||
|
||||
|
@ -13,6 +13,7 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -27,17 +28,38 @@ import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener;
|
||||
|
||||
public class GradesFragment extends BaseFragment implements GradesContract.View {
|
||||
|
||||
@BindView(R.id.grade_fragment_summary_container)
|
||||
View summary;
|
||||
|
||||
@BindView(R.id.grade_fragment_details_container)
|
||||
View details;
|
||||
|
||||
@BindView(R.id.grade_fragment_recycler)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.grade_fragment_summary_recycler)
|
||||
RecyclerView summaryRecyclerView;
|
||||
|
||||
@BindView(R.id.grade_fragment_no_item_container)
|
||||
View noItemView;
|
||||
|
||||
@BindView(R.id.grade_fragment_swipe_refresh)
|
||||
SwipeRefreshLayout refreshLayout;
|
||||
|
||||
@BindView(R.id.grade_fragment_summary_predicted_average)
|
||||
TextView predictedAverage;
|
||||
|
||||
@BindView(R.id.grade_fragment_summary_calculated_average)
|
||||
TextView calculatedAverage;
|
||||
|
||||
@BindView(R.id.grade_fragment_summary_final_average)
|
||||
TextView finalAverage;
|
||||
|
||||
@Inject
|
||||
FlexibleAdapter<GradeHeaderItem> adapter;
|
||||
FlexibleAdapter<GradesHeader> adapter;
|
||||
|
||||
@Inject
|
||||
FlexibleAdapter<GradesSummarySubItem> summaryAdapter;
|
||||
|
||||
@Inject
|
||||
GradesContract.Presenter presenter;
|
||||
@ -66,43 +88,57 @@ public class GradesFragment extends BaseFragment implements GradesContract.View
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.semester_switch, menu);
|
||||
inflater.inflate(R.menu.grades_action_menu, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_filter) {
|
||||
presenter.onSemesterSwitchActive();
|
||||
CharSequence[] items = new CharSequence[]{
|
||||
getResources().getString(R.string.semester_text, 1),
|
||||
getResources().getString(R.string.semester_text, 2),
|
||||
};
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.switch_semester)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setSingleChoiceItems(items, this.currentSemester, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
presenter.onSemesterChange(which);
|
||||
dialog.cancel();
|
||||
}
|
||||
}).show();
|
||||
return true;
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_semester_switch:
|
||||
presenter.onSemesterSwitchActive();
|
||||
CharSequence[] items = new CharSequence[]{
|
||||
getResources().getString(R.string.semester_text, 1),
|
||||
getResources().getString(R.string.semester_text, 2),
|
||||
};
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.switch_semester)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setSingleChoiceItems(items, this.currentSemester, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
presenter.onSemesterChange(which);
|
||||
dialog.cancel();
|
||||
}
|
||||
}).show();
|
||||
return true;
|
||||
case R.id.action_summary_switch:
|
||||
boolean isDetailsVisible = details.getVisibility() == View.VISIBLE;
|
||||
|
||||
item.setTitle(isDetailsVisible ? R.string.action_title_details : R.string.action_title_summary);
|
||||
details.setVisibility(isDetailsVisible ? View.INVISIBLE : View.VISIBLE);
|
||||
summary.setVisibility(isDetailsVisible ? View.VISIBLE : View.INVISIBLE);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
noItemView.setVisibility(View.GONE);
|
||||
summary.setVisibility(View.INVISIBLE);
|
||||
details.setVisibility(View.VISIBLE);
|
||||
|
||||
adapter.setAutoCollapseOnExpand(true);
|
||||
adapter.setAutoScrollOnExpand(true);
|
||||
adapter.expandItemsAtStartUp();
|
||||
summaryAdapter.setDisplayHeadersAtStartUp(true);
|
||||
|
||||
recyclerView.setLayoutManager(new SmoothScrollLinearLayoutManager(view.getContext()));
|
||||
recyclerView.setAdapter(adapter);
|
||||
summaryRecyclerView.setLayoutManager(new SmoothScrollLinearLayoutManager(view.getContext()));
|
||||
summaryRecyclerView.setAdapter(summaryAdapter);
|
||||
summaryRecyclerView.setNestedScrollingEnabled(false);
|
||||
|
||||
refreshLayout.setColorSchemeResources(android.R.color.black);
|
||||
refreshLayout.setOnRefreshListener(this);
|
||||
@ -116,6 +152,13 @@ public class GradesFragment extends BaseFragment implements GradesContract.View
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSummaryAverages(String calculatedValue, String predictedValue, String finalValue) {
|
||||
calculatedAverage.setText(calculatedValue);
|
||||
predictedAverage.setText(predictedValue);
|
||||
finalAverage.setText(finalValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivityTitle() {
|
||||
setTitle(getString(R.string.grades_text));
|
||||
@ -141,10 +184,15 @@ public class GradesFragment extends BaseFragment implements GradesContract.View
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdapterList(List<GradeHeaderItem> headerItems) {
|
||||
public void updateAdapterList(List<GradesHeader> headerItems) {
|
||||
adapter.updateDataSet(headerItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSummaryAdapterList(List<GradesSummarySubItem> summarySubItems) {
|
||||
summaryAdapter.updateDataSet(summarySubItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshSuccessNoGrade() {
|
||||
showMessage(R.string.snackbar_no_grades);
|
||||
|
@ -20,14 +20,14 @@ import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
import io.github.wulkanowy.utils.AnimationUtils;
|
||||
import io.github.wulkanowy.utils.GradeUtils;
|
||||
|
||||
public class GradeHeaderItem
|
||||
extends AbstractExpandableHeaderItem<GradeHeaderItem.HeaderViewHolder, GradesSubItem> {
|
||||
public class GradesHeader
|
||||
extends AbstractExpandableHeaderItem<GradesHeader.HeaderViewHolder, GradesSubItem> {
|
||||
|
||||
private Subject subject;
|
||||
|
||||
private final boolean isShowSummary;
|
||||
|
||||
GradeHeaderItem(Subject subject, boolean isShowSummary) {
|
||||
GradesHeader(Subject subject, boolean isShowSummary) {
|
||||
this.subject = subject;
|
||||
this.isShowSummary = isShowSummary;
|
||||
}
|
||||
@ -38,7 +38,7 @@ public class GradeHeaderItem
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GradeHeaderItem that = (GradeHeaderItem) o;
|
||||
GradesHeader that = (GradesHeader) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(subject, that.subject)
|
||||
@ -54,7 +54,7 @@ public class GradeHeaderItem
|
||||
|
||||
@Override
|
||||
public int getLayoutRes() {
|
||||
return R.layout.grade_header;
|
||||
return R.layout.grades_header;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,7 +126,7 @@ public class GradeHeaderItem
|
||||
}
|
||||
|
||||
private String getGradesAverageString() {
|
||||
float average = GradeUtils.calculate(item.getGradeList());
|
||||
float average = GradeUtils.calculateWeightedAverage(item.getGradeList());
|
||||
|
||||
if (average < 0) {
|
||||
return resources.getString(R.string.info_no_average);
|
@ -12,7 +12,12 @@ public abstract class GradesModule {
|
||||
abstract GradesContract.Presenter provideGradesPresenter(GradesPresenter gradesPresenter);
|
||||
|
||||
@Provides
|
||||
static FlexibleAdapter<GradeHeaderItem> provideGradesAdapter() {
|
||||
static FlexibleAdapter<GradesHeader> provideGradesAdapter() {
|
||||
return new FlexibleAdapter<>(null);
|
||||
}
|
||||
|
||||
@Provides
|
||||
static FlexibleAdapter<GradesSummarySubItem> provideGradesSummaryAdapter() {
|
||||
return new FlexibleAdapter<>(null);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import org.threeten.bp.LocalDate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -18,6 +19,7 @@ import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
import io.github.wulkanowy.ui.base.BasePresenter;
|
||||
import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener;
|
||||
import io.github.wulkanowy.utils.FabricUtils;
|
||||
import io.github.wulkanowy.utils.GradeUtils;
|
||||
import io.github.wulkanowy.utils.async.AbstractTask;
|
||||
import io.github.wulkanowy.utils.async.AsyncListeners;
|
||||
|
||||
@ -31,12 +33,20 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
|
||||
|
||||
private OnFragmentIsReadyListener listener;
|
||||
|
||||
private List<GradeHeaderItem> headerItems = new ArrayList<>();
|
||||
private List<GradesHeader> headerItems = new ArrayList<>();
|
||||
|
||||
private List<GradesSummarySubItem> summarySubItems = new ArrayList<>();
|
||||
|
||||
private boolean isFirstSight = false;
|
||||
|
||||
private int semesterName;
|
||||
|
||||
private float finalAverage;
|
||||
|
||||
private float predictedAverage;
|
||||
|
||||
private float calculatedAverage;
|
||||
|
||||
@Inject
|
||||
GradesPresenter(RepositoryContract repository) {
|
||||
super(repository);
|
||||
@ -56,7 +66,6 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
|
||||
|
||||
if (!isFirstSight) {
|
||||
isFirstSight = true;
|
||||
|
||||
reloadGrades();
|
||||
}
|
||||
}
|
||||
@ -76,12 +85,6 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
|
||||
.putCustomAttribute("Name", semesterName));
|
||||
}
|
||||
|
||||
private void reloadGrades() {
|
||||
loadingTask = new AbstractTask();
|
||||
loadingTask.setOnFirstLoadingListener(this);
|
||||
loadingTask.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFragmentVisible(boolean isVisible) {
|
||||
if (isVisible) {
|
||||
@ -140,13 +143,17 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
|
||||
boolean isShowSummary = getRepository().getSharedRepo().isShowGradesSummary();
|
||||
|
||||
headerItems = new ArrayList<>();
|
||||
summarySubItems = new ArrayList<>();
|
||||
|
||||
for (Subject subject : subjectList) {
|
||||
subject.resetGradeList();
|
||||
List<Grade> gradeList = subject.getGradeList();
|
||||
|
||||
GradesSummaryHeader summaryHeader = new GradesSummaryHeader(subject, GradeUtils.calculateWeightedAverage(gradeList));
|
||||
summarySubItems.add(new GradesSummarySubItem(summaryHeader, subject));
|
||||
|
||||
if (!gradeList.isEmpty()) {
|
||||
GradeHeaderItem headerItem = new GradeHeaderItem(subject, isShowSummary);
|
||||
GradesHeader headerItem = new GradesHeader(subject, isShowSummary);
|
||||
|
||||
List<GradesSubItem> subItems = new ArrayList<>();
|
||||
|
||||
@ -159,6 +166,10 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
|
||||
headerItems.add(headerItem);
|
||||
}
|
||||
}
|
||||
|
||||
finalAverage = GradeUtils.calculateSubjectsAverage(subjectList, false);
|
||||
predictedAverage = GradeUtils.calculateSubjectsAverage(subjectList, true);
|
||||
calculatedAverage = GradeUtils.calculateDetailedSubjectsAverage(subjectList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,9 +181,35 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
|
||||
public void onEndLoadingAsync(boolean result, Exception exception) {
|
||||
getView().showNoItem(headerItems.isEmpty());
|
||||
getView().updateAdapterList(headerItems);
|
||||
|
||||
setSummaryAverages();
|
||||
getView().updateSummaryAdapterList(summarySubItems);
|
||||
|
||||
listener.onFragmentIsReady();
|
||||
}
|
||||
|
||||
private void setSummaryAverages() {
|
||||
getView().setSummaryAverages(
|
||||
getFormattedAverage(calculatedAverage),
|
||||
getFormattedAverage(predictedAverage),
|
||||
getFormattedAverage(finalAverage)
|
||||
);
|
||||
}
|
||||
|
||||
private String getFormattedAverage(float average) {
|
||||
if (-1.0f == average) {
|
||||
return "-- --";
|
||||
}
|
||||
|
||||
return String.format(Locale.FRANCE, "%.2f", average);
|
||||
}
|
||||
|
||||
private void reloadGrades() {
|
||||
loadingTask = new AbstractTask();
|
||||
loadingTask.setOnFirstLoadingListener(this);
|
||||
loadingTask.execute();
|
||||
}
|
||||
|
||||
private void cancelAsyncTasks() {
|
||||
if (refreshTask != null) {
|
||||
refreshTask.cancel(true);
|
||||
|
@ -21,7 +21,7 @@ import io.github.wulkanowy.data.db.dao.entities.Grade;
|
||||
import io.github.wulkanowy.utils.GradeUtils;
|
||||
|
||||
public class GradesSubItem
|
||||
extends AbstractSectionableItem<GradesSubItem.SubItemViewHolder, GradeHeaderItem> {
|
||||
extends AbstractSectionableItem<GradesSubItem.SubItemViewHolder, GradesHeader> {
|
||||
|
||||
private Grade grade;
|
||||
|
||||
@ -29,7 +29,7 @@ public class GradesSubItem
|
||||
|
||||
private View subjectAlertImage;
|
||||
|
||||
GradesSubItem(GradeHeaderItem header, Grade grade) {
|
||||
GradesSubItem(GradesHeader header, Grade grade) {
|
||||
super(header);
|
||||
this.grade = grade;
|
||||
}
|
||||
@ -64,7 +64,7 @@ public class GradesSubItem
|
||||
|
||||
@Override
|
||||
public int getLayoutRes() {
|
||||
return R.layout.grade_subitem;
|
||||
return R.layout.grades_subitem;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,87 @@
|
||||
package io.github.wulkanowy.ui.main.grades;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem;
|
||||
import eu.davidea.flexibleadapter.items.IFlexible;
|
||||
import eu.davidea.viewholders.FlexibleViewHolder;
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
|
||||
class GradesSummaryHeader extends AbstractHeaderItem<GradesSummaryHeader.HeaderViewHolder> {
|
||||
|
||||
private Subject subject;
|
||||
|
||||
private String average;
|
||||
|
||||
GradesSummaryHeader(Subject subject, float average) {
|
||||
this.subject = subject;
|
||||
this.average = String.format(Locale.FRANCE, "%.2f", average);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GradesSummaryHeader that = (GradesSummaryHeader) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(subject, that.subject)
|
||||
.append(average, that.average)
|
||||
.isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 37)
|
||||
.append(subject)
|
||||
.append(average)
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutRes() {
|
||||
return R.layout.grades_summary_header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeaderViewHolder createViewHolder(View view, FlexibleAdapter<IFlexible> adapter) {
|
||||
return new HeaderViewHolder(view, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, HeaderViewHolder holder, int position, List<Object> payloads) {
|
||||
holder.onBind(subject, average);
|
||||
}
|
||||
|
||||
static class HeaderViewHolder extends FlexibleViewHolder {
|
||||
|
||||
@BindView(R.id.grades_summary_header_name)
|
||||
TextView name;
|
||||
|
||||
@BindView(R.id.grades_summary_header_average)
|
||||
TextView average;
|
||||
|
||||
HeaderViewHolder(View view, FlexibleAdapter adapter) {
|
||||
super(view, adapter);
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
|
||||
void onBind(Subject item, String value) {
|
||||
name.setText(item.getName());
|
||||
average.setText("-1,00".equals(value) ? "" : value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package io.github.wulkanowy.ui.main.grades;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem;
|
||||
import eu.davidea.flexibleadapter.items.IFlexible;
|
||||
import eu.davidea.viewholders.FlexibleViewHolder;
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
|
||||
public class GradesSummarySubItem
|
||||
extends AbstractSectionableItem<GradesSummarySubItem.SubItemViewHolder, GradesSummaryHeader> {
|
||||
|
||||
private Subject subject;
|
||||
|
||||
public GradesSummarySubItem(GradesSummaryHeader header, Subject subject) {
|
||||
super(header);
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GradesSummarySubItem that = (GradesSummarySubItem) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(subject, that.subject)
|
||||
.isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 37)
|
||||
.append(subject)
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutRes() {
|
||||
return R.layout.grades_summary_subitem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubItemViewHolder createViewHolder(View view, FlexibleAdapter<IFlexible> adapter) {
|
||||
return new SubItemViewHolder(view, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, SubItemViewHolder holder, int position, List<Object> payloads) {
|
||||
holder.onBind(subject);
|
||||
}
|
||||
|
||||
static class SubItemViewHolder extends FlexibleViewHolder {
|
||||
|
||||
@BindView(R.id.grades_summary_subitem_final_grade)
|
||||
TextView finalGrade;
|
||||
|
||||
@BindView(R.id.grades_summary_subitem_predicted_grade)
|
||||
TextView predictedGrade;
|
||||
|
||||
SubItemViewHolder(View view, FlexibleAdapter adapter) {
|
||||
super(view, adapter);
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
|
||||
void onBind(Subject item) {
|
||||
predictedGrade.setText(item.getPredictedRating());
|
||||
finalGrade.setText(item.getFinalRating());
|
||||
}
|
||||
}
|
||||
}
|
@ -24,12 +24,12 @@ import eu.davidea.viewholders.ExpandableViewHolder;
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Day;
|
||||
|
||||
public class TimetableHeaderItem
|
||||
extends AbstractExpandableHeaderItem<TimetableHeaderItem.HeaderViewHolder, TimetableSubItem> {
|
||||
public class TimetableHeader
|
||||
extends AbstractExpandableHeaderItem<TimetableHeader.HeaderViewHolder, TimetableSubItem> {
|
||||
|
||||
private Day day;
|
||||
|
||||
TimetableHeaderItem(Day day) {
|
||||
TimetableHeader(Day day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public class TimetableHeaderItem
|
||||
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
TimetableHeaderItem that = (TimetableHeaderItem) o;
|
||||
TimetableHeader that = (TimetableHeader) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(day, that.day)
|
@ -25,11 +25,11 @@ import io.github.wulkanowy.ui.main.timetable.TimetableDialogFragment;
|
||||
|
||||
|
||||
public class TimetableSubItem
|
||||
extends AbstractSectionableItem<TimetableSubItem.SubItemViewHolder, TimetableHeaderItem> {
|
||||
extends AbstractSectionableItem<TimetableSubItem.SubItemViewHolder, TimetableHeader> {
|
||||
|
||||
private TimetableLesson lesson;
|
||||
|
||||
TimetableSubItem(TimetableHeaderItem header, TimetableLesson lesson) {
|
||||
TimetableSubItem(TimetableHeader header, TimetableLesson lesson) {
|
||||
super(header);
|
||||
this.lesson = lesson;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ public interface TimetableTabContract {
|
||||
|
||||
interface View extends BaseContract.View {
|
||||
|
||||
void updateAdapterList(List<TimetableHeaderItem> headerItems);
|
||||
void updateAdapterList(List<TimetableHeader> headerItems);
|
||||
|
||||
void expandItem(int item);
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo
|
||||
TimetableTabContract.Presenter presenter;
|
||||
|
||||
@Inject
|
||||
FlexibleAdapter<TimetableHeaderItem> adapter;
|
||||
FlexibleAdapter<TimetableHeader> adapter;
|
||||
|
||||
private boolean isFragmentVisible = false;
|
||||
|
||||
@ -86,7 +86,7 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdapterList(List<TimetableHeaderItem> headerItems) {
|
||||
public void updateAdapterList(List<TimetableHeader> headerItems) {
|
||||
adapter.updateDataSet(headerItems);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ public abstract class TimetableTabModule {
|
||||
|
||||
@PerChildFragment
|
||||
@Provides
|
||||
static FlexibleAdapter<TimetableHeaderItem> provideTimetableAdapter() {
|
||||
static FlexibleAdapter<TimetableHeader> provideTimetableAdapter() {
|
||||
return new FlexibleAdapter<>(null);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.Vi
|
||||
|
||||
private AbstractTask loadingTask;
|
||||
|
||||
private List<TimetableHeaderItem> headerItems = new ArrayList<>();
|
||||
private List<TimetableHeader> headerItems = new ArrayList<>();
|
||||
|
||||
private String date;
|
||||
|
||||
@ -117,7 +117,7 @@ public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.Vi
|
||||
|
||||
for (Day day : dayList) {
|
||||
day.resetTimetableLessons();
|
||||
TimetableHeaderItem headerItem = new TimetableHeaderItem(day);
|
||||
TimetableHeader headerItem = new TimetableHeader(day);
|
||||
|
||||
if (isFreeWeek) {
|
||||
isFreeWeek = day.getFreeDay();
|
||||
|
@ -6,6 +6,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Grade;
|
||||
import io.github.wulkanowy.data.db.dao.entities.Subject;
|
||||
|
||||
public final class GradeUtils {
|
||||
|
||||
@ -16,53 +17,33 @@ public final class GradeUtils {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static float calculate(List<Grade> gradeList) {
|
||||
public static float calculateWeightedAverage(List<Grade> gradeList) {
|
||||
|
||||
float counter = 0f;
|
||||
float denominator = 0f;
|
||||
|
||||
for (Grade grade : gradeList) {
|
||||
int integerWeight = getIntegerForWeightOfGrade(grade.getWeight());
|
||||
float floatValue = getMathematicalValueOfGrade(grade.getValue());
|
||||
int weight = getWeightValue(grade.getWeight());
|
||||
float value = getWeightedGradeValue(grade.getValue());
|
||||
|
||||
if (floatValue != -1f) {
|
||||
counter += floatValue * integerWeight;
|
||||
denominator += integerWeight;
|
||||
if (value != -1.0f) {
|
||||
counter += value * weight;
|
||||
denominator += weight;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter == 0f) {
|
||||
return -1f;
|
||||
} else {
|
||||
return counter / denominator;
|
||||
return -1.0f;
|
||||
}
|
||||
return counter / denominator;
|
||||
}
|
||||
|
||||
private static float getMathematicalValueOfGrade(String valueOfGrade) {
|
||||
if (valueOfGrade.matches("[-|+|=]{0,2}[0-6]")
|
||||
|| valueOfGrade.matches("[0-6][-|+|=]{0,2}")) {
|
||||
if (valueOfGrade.matches("[-][0-6]")
|
||||
|| valueOfGrade.matches("[0-6][-]")) {
|
||||
String replacedValue = valueOfGrade.replaceAll("[-]", "");
|
||||
return Float.valueOf(replacedValue) - 0.33f;
|
||||
} else if (valueOfGrade.matches("[+][0-6]")
|
||||
|| valueOfGrade.matches("[0-6][+]")) {
|
||||
String replacedValue = valueOfGrade.replaceAll("[+]", "");
|
||||
return Float.valueOf((replacedValue)) + 0.33f;
|
||||
} else if (valueOfGrade.matches("[-|=]{1,2}[0-6]")
|
||||
|| valueOfGrade.matches("[0-6][-|=]{1,2}")) {
|
||||
String replacedValue = valueOfGrade.replaceAll("[-|=]{1,2}", "");
|
||||
return Float.valueOf((replacedValue)) - 0.5f;
|
||||
} else {
|
||||
return Float.valueOf(valueOfGrade);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
public static float calculateSubjectsAverage(List<Subject> subjectList, boolean usePredicted) {
|
||||
return calculateSubjectsAverage(subjectList, usePredicted, false);
|
||||
}
|
||||
|
||||
private static int getIntegerForWeightOfGrade(String weightOfGrade) {
|
||||
return Integer.valueOf(weightOfGrade.substring(0, weightOfGrade.length() - 3));
|
||||
public static float calculateDetailedSubjectsAverage(List<Subject> subjectList) {
|
||||
return calculateSubjectsAverage(subjectList, false, true);
|
||||
}
|
||||
|
||||
public static int getValueColor(String value) {
|
||||
@ -93,4 +74,80 @@ public final class GradeUtils {
|
||||
return R.color.default_grade;
|
||||
}
|
||||
}
|
||||
|
||||
private static float calculateSubjectsAverage(List<Subject> subjectList, boolean usePredicted, boolean useSubjectsAverages) {
|
||||
float counter = 0f;
|
||||
float denominator = 0f;
|
||||
|
||||
for (Subject subject : subjectList) {
|
||||
float value;
|
||||
|
||||
if (useSubjectsAverages) {
|
||||
value = calculateWeightedAverage(subject.getGradeList());
|
||||
} else {
|
||||
value = getGradeValue(usePredicted ? subject.getPredictedRating() : subject.getFinalRating());
|
||||
}
|
||||
|
||||
if (value != -1.0f) {
|
||||
counter += Math.round(value);
|
||||
denominator++;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter == 0) {
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
return counter / denominator;
|
||||
}
|
||||
|
||||
private static float getGradeValue(String grade) {
|
||||
if (validGradePattern.matcher(grade).matches()) {
|
||||
return getWeightedGradeValue(grade);
|
||||
}
|
||||
|
||||
return getVerbalGradeValue(grade);
|
||||
}
|
||||
|
||||
private static float getVerbalGradeValue(String grade) {
|
||||
switch (grade) {
|
||||
case "celujący":
|
||||
return 6f;
|
||||
case "bardzo dobry":
|
||||
return 5f;
|
||||
case "dobry":
|
||||
return 4f;
|
||||
case "dostateczny":
|
||||
return 3f;
|
||||
case "dopuszczający":
|
||||
return 2f;
|
||||
case "niedostateczny":
|
||||
return 1f;
|
||||
default:
|
||||
return -1f;
|
||||
}
|
||||
}
|
||||
|
||||
private static float getWeightedGradeValue(String value) {
|
||||
if (validGradePattern.matcher(value).matches()) {
|
||||
if (value.matches("[-][0-6]") || value.matches("[0-6][-]")) {
|
||||
String replacedValue = value.replaceAll("[-]", "");
|
||||
return Float.valueOf(replacedValue) - 0.33f;
|
||||
} else if (value.matches("[+][0-6]") || value.matches("[0-6][+]")) {
|
||||
String replacedValue = value.replaceAll("[+]", "");
|
||||
return Float.valueOf((replacedValue)) + 0.33f;
|
||||
} else if (value.matches("[-|=]{1,2}[0-6]") || value.matches("[0-6][-|=]{1,2}")) {
|
||||
String replacedValue = value.replaceAll("[-|=]{1,2}", "");
|
||||
return Float.valueOf((replacedValue)) - 0.5f;
|
||||
} else {
|
||||
return Float.valueOf(value);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getWeightValue(String weightOfGrade) {
|
||||
return Integer.valueOf(weightOfGrade.substring(0, weightOfGrade.length() - 3));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user