Gradebook Design Update
This commit is contained in:
@@ -13,6 +13,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.services.kvv.types.Grade;
|
||||
import de.sebse.fuplanner.services.kvv.types.Gradebook;
|
||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||
import de.sebse.fuplanner.tools.ui.StringViewHolder;
|
||||
|
||||
@@ -20,9 +21,12 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
private static final int TYPE_TOTAL = 0;
|
||||
private static final int TYPE_GRADE = 1;
|
||||
|
||||
private static final int SECTION_GRADE = 0;
|
||||
private static final int SECTION_EXAM = 0;
|
||||
private static final int SECTION_ASSIGNMENT = 1;
|
||||
private static final int SECTION_OTHER = 2;
|
||||
|
||||
private Modules.Module mValue;
|
||||
private Gradebook.CategorizedGrades mGrades;
|
||||
private final ArrayList<Pair<Integer, Integer>> mPositionalData;
|
||||
|
||||
ModDetailGradebookAdapter() {
|
||||
@@ -38,9 +42,32 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
|
||||
private void setModule() {
|
||||
mPositionalData.clear();
|
||||
mPositionalData.add(new Pair<>(TYPE_TOTAL, SECTION_GRADE));
|
||||
for (int i = 0; i < getGradesCount(); i++) {
|
||||
mPositionalData.add(new Pair<>(TYPE_GRADE, SECTION_GRADE +1024*i));
|
||||
if (mValue != null && mValue.gradebook != null) {
|
||||
mGrades = mValue.gradebook.getAutoCategorizedGrades();
|
||||
int size;
|
||||
size = mGrades.getExams().grades.size();
|
||||
if (size > 0) {
|
||||
mPositionalData.add(new Pair<>(setViewType(TYPE_TOTAL, SECTION_EXAM), 0));
|
||||
for (int i = 0; i < size; i++) {
|
||||
mPositionalData.add(new Pair<>(setViewType(TYPE_GRADE, SECTION_EXAM), i));
|
||||
}
|
||||
}
|
||||
size = mGrades.getAssignments().grades.size();
|
||||
if (size > 0) {
|
||||
mPositionalData.add(new Pair<>(setViewType(TYPE_TOTAL, SECTION_ASSIGNMENT), 0));
|
||||
for (int i = 0; i < size; i++) {
|
||||
mPositionalData.add(new Pair<>(setViewType(TYPE_GRADE, SECTION_ASSIGNMENT), i));
|
||||
}
|
||||
}
|
||||
size = mGrades.getOthers().grades.size();
|
||||
if (size > 0) {
|
||||
mPositionalData.add(new Pair<>(setViewType(TYPE_TOTAL, SECTION_OTHER), 0));
|
||||
for (int i = 0; i < size; i++) {
|
||||
mPositionalData.add(new Pair<>(setViewType(TYPE_GRADE, SECTION_OTHER), i));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mGrades = null;
|
||||
}
|
||||
|
||||
this.notifyDataSetChanged();
|
||||
@@ -53,8 +80,8 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
switch (viewType) {
|
||||
case TYPE_TOTAL:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_caption, parent, false);
|
||||
return new StringViewHolder(view);
|
||||
.inflate(R.layout.list_moddetails_gradebook_title, parent, false);
|
||||
return new GradeTitleViewHolder(view);
|
||||
case TYPE_GRADE:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_moddetails_gradebook, parent, false);
|
||||
@@ -69,7 +96,7 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
public int getItemViewType(int position) {
|
||||
// Note that unlike in ListView adapters, types don't have to be contiguous
|
||||
if (position < mPositionalData.size())
|
||||
return mPositionalData.get(position).first;
|
||||
return getViewType(mPositionalData.get(position).first);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
@@ -79,19 +106,45 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
if (mValue == null || position > mPositionalData.size())
|
||||
return;
|
||||
Pair<Integer, Integer> data = mPositionalData.get(position);
|
||||
switch (data.first) {
|
||||
int viewType = getViewType(data.first);
|
||||
int viewSection = getViewSection(data.first);
|
||||
Gradebook.GradebookOutput gradebook = getViewSectionGradebook(viewSection);
|
||||
switch (viewType) {
|
||||
case TYPE_TOTAL:
|
||||
StringViewHolder h = (StringViewHolder) holder;
|
||||
h.mString.setText(h.mView.getResources().getString(R.string.current_percentage, mValue.getGradebookPercent()*100));
|
||||
break;
|
||||
case TYPE_GRADE:
|
||||
int index = data.second / 1024;
|
||||
GradeViewHolder i = (GradeViewHolder) holder;
|
||||
Grade gradebook = mValue.gradebook.get(index);
|
||||
GradeTitleViewHolder h = (GradeTitleViewHolder) holder;
|
||||
|
||||
i.mTitle.setText(gradebook.getItemName());
|
||||
i.mGrade.setText(String.valueOf(gradebook.getPoints()));
|
||||
i.mGradeMax.setText(String.valueOf(gradebook.getMaxPoints()));
|
||||
if (gradebook != null) {
|
||||
String title = "";
|
||||
switch (viewSection) {
|
||||
case SECTION_EXAM: title = h.mView.getResources().getString(R.string.exam); break;
|
||||
case SECTION_ASSIGNMENT: title = h.mView.getResources().getString(R.string.assignments); break;
|
||||
case SECTION_OTHER: title = h.mView.getResources().getString(R.string.others); break;
|
||||
}
|
||||
h.mTitle.setText(title);
|
||||
Grade bestGrade = gradebook.getBestGrade();
|
||||
h.mString.setText(h.mView.getResources().getString(
|
||||
R.string.current_percentage,
|
||||
gradebook.getUserPointSum(),
|
||||
gradebook.getMaxPointSum(),
|
||||
gradebook.getPercentage() * 100,
|
||||
bestGrade.getPoints(),
|
||||
bestGrade.getMaxPoints(),
|
||||
bestGrade.getPoints() / bestGrade.getMaxPoints() * 100,
|
||||
bestGrade.getItemName()
|
||||
));
|
||||
}
|
||||
break;
|
||||
case TYPE_GRADE:
|
||||
int index = data.second;
|
||||
GradeViewHolder i = (GradeViewHolder) holder;
|
||||
|
||||
if (gradebook != null) {
|
||||
Grade grade = gradebook.grades.get(index);
|
||||
|
||||
i.mTitle.setText(grade.getItemName());
|
||||
i.mGrade.setText(String.valueOf(grade.getPoints()));
|
||||
i.mGradeMax.setText(String.valueOf(grade.getMaxPoints()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -101,10 +154,27 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
return mPositionalData.size();
|
||||
}
|
||||
|
||||
private int getGradesCount() {
|
||||
if (mValue.gradebook != null)
|
||||
return mValue.gradebook.size();
|
||||
return 0;
|
||||
private int setViewType(int type, int section) {
|
||||
return type * 1024 + section;
|
||||
}
|
||||
|
||||
private int getViewType(int combinedViewType) {
|
||||
return combinedViewType / 1024;
|
||||
}
|
||||
|
||||
private int getViewSection(int combinedViewType) {
|
||||
return combinedViewType - getViewType(combinedViewType) * 1024;
|
||||
}
|
||||
|
||||
private Gradebook.GradebookOutput getViewSectionGradebook(int viewSection) {
|
||||
if (mGrades != null) {
|
||||
switch (viewSection) {
|
||||
case SECTION_EXAM: return mGrades.getExams();
|
||||
case SECTION_ASSIGNMENT: return mGrades.getAssignments();
|
||||
case SECTION_OTHER: return mGrades.getOthers();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,4 +203,19 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
return super.toString() + " '" + mTitle.getText() + " '" + mGrade.getText() + " '" + mGradeMax.getText() + "'";
|
||||
}
|
||||
}
|
||||
|
||||
private class GradeTitleViewHolder extends StringViewHolder {
|
||||
private final TextView mTitle;
|
||||
|
||||
GradeTitleViewHolder(View view) {
|
||||
super(view);
|
||||
mTitle = view.findViewById(R.id.title);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " '" + mTitle.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,31 +9,32 @@ import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.sebse.fuplanner.services.kvv.types.Grade;
|
||||
import de.sebse.fuplanner.services.kvv.types.Gradebook;
|
||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
public class ModulesGradebook extends PartModules<Gradebook> {
|
||||
|
||||
ModulesGradebook(Login login, ModulesList list, Context context) {
|
||||
super(login, list, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Grade> getPart(Modules.Module module) {
|
||||
protected Gradebook getPart(Modules.Module module) {
|
||||
return module.gradebook;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setPart(Modules.Module module, ArrayList<Grade> part) {
|
||||
protected boolean setPart(Modules.Module module, Gradebook part) {
|
||||
boolean changed = module.gradebook == null || module.gradebook.hashCode() != part.hashCode();
|
||||
module.gradebook = part;
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void upgradeKVV(final String ID, final NetworkCallback<ArrayList<Grade>> callback, final NetworkErrorCallback errorCallback) {
|
||||
protected void upgradeKVV(final String ID, final NetworkCallback<Gradebook> callback, final NetworkErrorCallback errorCallback) {
|
||||
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null || !mLogin.getLoginTokenKVV().isAvailable()) {
|
||||
errorCallback.onError(new NetworkError(101504, 500, "Currently running in offline mode!"));
|
||||
return;
|
||||
@@ -44,7 +45,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
errorCallback.onError(new NetworkError(101501, 403, "No gradebook retrieved!"));
|
||||
return;
|
||||
}
|
||||
ArrayList<Grade> gradebook = new ArrayList<>();
|
||||
Gradebook gradebook = new Gradebook();
|
||||
JSONArray sites;
|
||||
try {
|
||||
JSONObject json = new JSONObject(body);
|
||||
@@ -62,7 +63,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
String itemName = site.optString("itemName", null);
|
||||
double maxPoints = site.optDouble("points", -1);
|
||||
|
||||
gradebook.add(0, new Grade(itemName, grade, maxPoints));
|
||||
gradebook.addGrade(new Grade(itemName, grade, maxPoints));
|
||||
} catch (JSONException e) {
|
||||
log.e(new NetworkError(101505, 403, "Cannot parse gradebook!"));
|
||||
log.e("ID:", i, "JSON:", sites);
|
||||
@@ -73,14 +74,14 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
callback.onResponse(gradebook);
|
||||
}, error -> {
|
||||
if (error.networkResponse.statusCode == 400)
|
||||
callback.onResponse(new ArrayList<>());
|
||||
callback.onResponse(new Gradebook());
|
||||
else
|
||||
errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook!"));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void upgradeBB(String ID, NetworkCallback<ArrayList<Grade>> callback, NetworkErrorCallback errorCallback) {
|
||||
protected void upgradeBB(String ID, NetworkCallback<Gradebook> callback, NetworkErrorCallback errorCallback) {
|
||||
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenBB() == null || !mLogin.getLoginTokenBB().isAvailable()) {
|
||||
errorCallback.onError(new NetworkError(101510, 500, "Currently running in offline mode!"));
|
||||
return;
|
||||
@@ -117,7 +118,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<Grade> result = new ArrayList<>();
|
||||
Gradebook result = new Gradebook();
|
||||
for (int i = 0; i < grades.length(); i++) {
|
||||
for (int j = 0; j < gradeColumns.length(); j++) {
|
||||
try {
|
||||
@@ -133,7 +134,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
JSONObject score = column.optJSONObject("score");
|
||||
double maxPoints = score != null ? score.optDouble("possible", 0) : 0;
|
||||
|
||||
result.add(new Grade(name, points, maxPoints));
|
||||
result.addGrade(new Grade(name, points, maxPoints));
|
||||
} catch (JSONException e) {
|
||||
log.e(new NetworkError(101515, 400, "Cannot parse grades!"));
|
||||
log.e("ID:", i, "JSON-grades:", grades);
|
||||
@@ -147,7 +148,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
||||
}, error -> errorCallback.onError(new NetworkError(101516, error.networkResponse.statusCode, "Cannot get gradebook columns!")));
|
||||
}, error -> {
|
||||
if (error.networkResponse.statusCode == 403)
|
||||
callback.onResponse(new ArrayList<>());
|
||||
callback.onResponse(new Gradebook());
|
||||
else
|
||||
errorCallback.onError(new NetworkError(101517, error.networkResponse.statusCode, "Cannot get gradebook entries!"));
|
||||
});
|
||||
|
||||
@@ -23,6 +23,7 @@ import de.sebse.fuplanner.services.kvv.types.Assignment;
|
||||
import de.sebse.fuplanner.services.kvv.types.AssignmentList;
|
||||
import de.sebse.fuplanner.services.kvv.types.EventList;
|
||||
import de.sebse.fuplanner.services.kvv.types.Grade;
|
||||
import de.sebse.fuplanner.services.kvv.types.Gradebook;
|
||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||
import de.sebse.fuplanner.services.kvv.types.Resource;
|
||||
import de.sebse.fuplanner.tools.CustomNotificationManager;
|
||||
@@ -126,7 +127,7 @@ public class KVVSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
final ArrayList<Announcement> announcements = module.announcements;
|
||||
final AssignmentList assignments = module.assignments;
|
||||
final EventList events = module.events;
|
||||
final ArrayList<Grade> gradebook = module.gradebook;
|
||||
final Gradebook gradebook = module.gradebook;
|
||||
final ArrayList<Resource> resources = module.resources;
|
||||
mKVV.modules().details().recv(module, success1 -> {
|
||||
if (success1.second) {
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
package de.sebse.fuplanner.services.kvv.types;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class Gradebook implements Serializable, Iterable<Grade> {
|
||||
private ArrayList<Grade> gradebook = new ArrayList<>();
|
||||
private final static String[] EXAM_KEYWORDS = new String[] {"exam", "klausur", "prüfung"};
|
||||
private final static String[] ASSIGNMENT_KEYWORDS = new String[] {"übung", "assignment", "blatt", "sheet", "exercise"};
|
||||
|
||||
public void addGrade(Grade grade) {
|
||||
gradebook.add(0, grade);
|
||||
}
|
||||
|
||||
public CategorizedGrades getAutoCategorizedGrades() {
|
||||
ArrayList<Grade> exams = new ArrayList<>();
|
||||
ArrayList<Grade> assignments = new ArrayList<>();
|
||||
ArrayList<Grade> others = new ArrayList<>();
|
||||
for (Grade grade : gradebook) {
|
||||
boolean found = false;
|
||||
String name = grade.getItemName().toLowerCase();
|
||||
for (String keyword : EXAM_KEYWORDS) {
|
||||
if (name.contains(keyword)) {
|
||||
exams.add(grade);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
for (String keyword : ASSIGNMENT_KEYWORDS) {
|
||||
if (name.contains(keyword)) {
|
||||
assignments.add(grade);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
others.add(grade);
|
||||
}
|
||||
return new CategorizedGrades(exams, assignments, others);
|
||||
}
|
||||
|
||||
public GradebookOutput getUncategorizedGrades() {
|
||||
return new GradebookOutput(gradebook);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Iterator<Grade> iterator() {
|
||||
return gradebook.iterator();
|
||||
}
|
||||
|
||||
public class CategorizedGrades {
|
||||
private GradebookOutput exams;
|
||||
private GradebookOutput assignments;
|
||||
private GradebookOutput others;
|
||||
|
||||
private CategorizedGrades(List<Grade> exams, List<Grade> assignments, List<Grade> others) {
|
||||
this.exams = new GradebookOutput(exams);
|
||||
this.assignments = new GradebookOutput(assignments);
|
||||
this.others = new GradebookOutput(others);
|
||||
}
|
||||
|
||||
public GradebookOutput getExams() {
|
||||
return exams;
|
||||
}
|
||||
|
||||
public GradebookOutput getAssignments() {
|
||||
return assignments;
|
||||
}
|
||||
|
||||
public GradebookOutput getOthers() {
|
||||
return others;
|
||||
}
|
||||
}
|
||||
|
||||
public class GradebookOutput {
|
||||
public List<Grade> grades;
|
||||
|
||||
private GradebookOutput(List<Grade> grades) {
|
||||
this.grades = Collections.unmodifiableList(grades);
|
||||
}
|
||||
|
||||
public float getPercentage() {
|
||||
float maxPoints = 0;
|
||||
float userPoints = 0;
|
||||
if (grades != null) {
|
||||
for (Grade g : grades){
|
||||
maxPoints += g.getMaxPoints();
|
||||
userPoints += g.getPoints();
|
||||
}
|
||||
}
|
||||
if (maxPoints == 0)
|
||||
return 0;
|
||||
return userPoints / maxPoints;
|
||||
}
|
||||
|
||||
public float getMaxPointSum() {
|
||||
float maxPoints = 0;
|
||||
if (grades != null) {
|
||||
for (Grade g : grades){
|
||||
maxPoints += g.getMaxPoints();
|
||||
}
|
||||
}
|
||||
return maxPoints;
|
||||
}
|
||||
|
||||
public float getUserPointSum() {
|
||||
float userPoints = 0;
|
||||
if (grades != null) {
|
||||
for (Grade g : grades){
|
||||
userPoints += g.getPoints();
|
||||
}
|
||||
}
|
||||
return userPoints;
|
||||
}
|
||||
|
||||
public Grade getBestGrade() {
|
||||
Grade bestGrade = null;
|
||||
double bestValue = -1;
|
||||
if (grades != null) {
|
||||
for (Grade g : grades){
|
||||
double perc = g.getPoints() / g.getMaxPoints();
|
||||
if (perc > bestValue) {
|
||||
bestValue = perc;
|
||||
bestGrade = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestGrade;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,23 +178,9 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
@Nullable public ArrayList<Announcement> announcements;
|
||||
@Nullable public AssignmentList assignments;
|
||||
@Nullable public EventList events;
|
||||
@Nullable public ArrayList<Grade> gradebook;
|
||||
@Nullable public Gradebook gradebook;
|
||||
@Nullable public ArrayList<Resource> resources;
|
||||
|
||||
public float getGradebookPercent(){
|
||||
float maxPoint = 0;
|
||||
float userPoint = 0;
|
||||
if (gradebook != null) {
|
||||
for (Grade g : gradebook){
|
||||
maxPoint += g.getMaxPoints();
|
||||
userPoint += g.getPoints();
|
||||
}
|
||||
}
|
||||
if (maxPoint == 0)
|
||||
return 0;
|
||||
return userPoint/maxPoint;
|
||||
}
|
||||
|
||||
private Module(@Nullable Semester semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull LinkedHashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID, int moduleType) {
|
||||
|
||||
title = title.replaceAll("(.*?) (S[0-9]{2}|W[0-9/]{5})", "$1");
|
||||
|
||||
@@ -1,49 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dip" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_margin="@dimen/cardview_margin"
|
||||
card_view:cardElevation="@dimen/cardview_elevation">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/FUTheme.itemTitle"
|
||||
android:layout_toStartOf="@+id/grade"
|
||||
android:layout_marginEnd="10dip"
|
||||
tools:text="Test this new stuff!" />
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dip" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/grade"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginTop="5dip"
|
||||
style="@style/FUTheme.itemValue"
|
||||
tools:text="8"
|
||||
android:layout_toStartOf="@id/slash"
|
||||
android:layout_alignTop="@id/title" />
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/FUTheme.itemTitle"
|
||||
android:layout_toStartOf="@+id/grade"
|
||||
android:layout_marginEnd="10dip"
|
||||
tools:text="Test this new stuff!" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/slash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:textColor="@color/fuHeaderText2"
|
||||
android:textSize="30sp"
|
||||
android:text="@string/grade_separator"
|
||||
android:layout_toStartOf="@id/grade_max"
|
||||
android:layout_alignTop="@id/title" />
|
||||
<TextView
|
||||
android:id="@+id/grade"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginTop="5dip"
|
||||
style="@style/FUTheme.itemValue"
|
||||
tools:text="8"
|
||||
android:layout_toStartOf="@id/slash"
|
||||
android:layout_alignTop="@id/title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/grade_max"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@id/slash"
|
||||
android:layout_alignBottom="@id/slash"
|
||||
style="@style/FUTheme.itemValue"
|
||||
android:layout_alignParentEnd="true"
|
||||
tools:text="10" />
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:id="@+id/slash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:textColor="@color/fuHeaderText2"
|
||||
android:textSize="30sp"
|
||||
android:text="@string/grade_separator"
|
||||
android:layout_toStartOf="@id/grade_max"
|
||||
android:layout_alignTop="@id/title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/grade_max"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@id/slash"
|
||||
android:layout_alignBottom="@id/slash"
|
||||
style="@style/FUTheme.itemValue"
|
||||
android:layout_alignParentEnd="true"
|
||||
tools:text="10" />
|
||||
</RelativeLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
31
app/src/main/res/layout/list_moddetails_gradebook_title.xml
Normal file
31
app/src/main/res/layout/list_moddetails_gradebook_title.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/cardview_margin"
|
||||
android:layout_marginStart="@dimen/cardview_margin"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginRight="@dimen/cardview_margin"
|
||||
android:layout_marginEnd="@dimen/cardview_margin"
|
||||
tools:text="Caption"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/string"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/cardview_margin"
|
||||
android:layout_marginStart="@dimen/cardview_margin"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginRight="@dimen/cardview_margin"
|
||||
android:layout_marginEnd="@dimen/cardview_margin"
|
||||
tools:text="Caption"
|
||||
style="@style/FUTheme.itemValue" />
|
||||
</LinearLayout>
|
||||
@@ -28,7 +28,7 @@
|
||||
<string name="no_items_available">Keine Einträge vorhanden!</string>
|
||||
<string name="events">Veranstaltungen</string>
|
||||
<string name="gradebook">Noten</string>
|
||||
<string name="current_percentage">Aktuelle Prozentzahl: %1$.2f \%%</string>
|
||||
<string name="current_percentage">Punkte: %1$.1f / %2$.1f\nProzentsatz: %3$.1f \%%\nBeste Note: %4$.1f / %5$.1f - %6$.1f \%% (%7$s)</string>
|
||||
<string name="offline_mode">Offline-Modus</string>
|
||||
<string name="refresh_failed">Aktualisieren fehlgeschlagen…</string>
|
||||
<string name="share_intent">Hey, schau\' dir die neue KVV App an: %1$s</string>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<string name="no_items_available">No items available!</string>
|
||||
<string name="events">Events</string>
|
||||
<string name="gradebook">Gradebook</string>
|
||||
<string name="current_percentage">Current Percentage: %1$.2f \%%</string>
|
||||
<string name="current_percentage">Points: %1$.1f / %2$.1f\nPercentage: %3$.1f \%%\nBest Grade: %4$.1f / %5$.1f - %6$.1f \%% (%7$s)</string>
|
||||
<string name="offline_mode">Offline Mode</string>
|
||||
<string name="refresh_failed">Refresh failed…</string>
|
||||
<string name="share_intent">Hey, check out the new KVV app: %1$s</string>
|
||||
|
||||
Reference in New Issue
Block a user