Event overview updated
This commit is contained in:
@@ -6,26 +6,40 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.services.KVV.types.Event;
|
||||
import de.sebse.fuplanner.services.KVV.types.EventList;
|
||||
import de.sebse.fuplanner.services.KVV.types.GroupedEvents;
|
||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||
import de.sebse.fuplanner.tools.Triplet;
|
||||
import de.sebse.fuplanner.tools.UtilsDate;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
import de.sebse.fuplanner.tools.ui.CustomViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.ItemViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.ListViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.StringViewHolder;
|
||||
|
||||
class ModDetailEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private static final int TYPE_HEADER = 0;
|
||||
private static final int TYPE_ITEM = 1;
|
||||
class ModDetailEventAdapter extends RecyclerView.Adapter<CustomViewHolder> {
|
||||
private static final String VALUE_LECTURE = "Class section - Lecture";
|
||||
private static final String VALUE_TUTORIAL = "Class section - Small Group";
|
||||
private static final String VALUE_EXAM = "Exam";
|
||||
private static final String VALUE_DEADLINE = "Deadline";
|
||||
private static final String VALUE_OTHER = "Other";
|
||||
private static final String[] VALUES_GROUPED = {VALUE_LECTURE, VALUE_TUTORIAL};
|
||||
private static final String[] VALUES_UNGROUPED = {VALUE_EXAM, VALUE_DEADLINE};
|
||||
|
||||
private static final int SECTION_UPCOMING = 0;
|
||||
private static final int SECTION_PAST = 1;
|
||||
private static final int TYPE_NONE = 0;
|
||||
private static final int TYPE_GROUPED = 1;
|
||||
private static final int TYPE_UNGROUPED = 2;
|
||||
|
||||
private Modules.Module mValue;
|
||||
private final ArrayList<Pair<Integer, Integer>> mPositionalData;
|
||||
private final ArrayList<Triplet<Integer, String, Object>> mPositionalData;
|
||||
|
||||
private final Logger log = new Logger(this);
|
||||
|
||||
@@ -41,36 +55,55 @@ class ModDetailEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
}
|
||||
|
||||
public void setModule() {
|
||||
LinkedHashMap<String, GroupedEvents> listsGrouped = new LinkedHashMap<>();
|
||||
LinkedHashMap<String, EventList> listsUngrouped = new LinkedHashMap<>();
|
||||
for (String value : VALUES_GROUPED) listsGrouped.put(value, new GroupedEvents());
|
||||
for (String value : VALUES_UNGROUPED) listsUngrouped.put(value, new EventList());
|
||||
listsUngrouped.put(VALUE_OTHER, new EventList());
|
||||
for (int i = 0; i < getEventsCount(); i++) {
|
||||
assert mValue.events != null;
|
||||
Event event = mValue.events.get(i);
|
||||
String type = event.getType();
|
||||
GroupedEvents groupedEvents = listsGrouped.get(type);
|
||||
if (groupedEvents != null) {
|
||||
groupedEvents.add(event);
|
||||
} else {
|
||||
EventList ungroupedEvents = listsUngrouped.get(type);
|
||||
if (ungroupedEvents == null) {
|
||||
ungroupedEvents = listsUngrouped.get(VALUE_OTHER);
|
||||
}
|
||||
assert ungroupedEvents != null;
|
||||
ungroupedEvents.add(event);
|
||||
}
|
||||
}
|
||||
|
||||
mPositionalData.clear();
|
||||
addPositionalListData(getUpcomingEventsCount(), SECTION_UPCOMING);
|
||||
mPositionalData.add(new Pair<>(TYPE_HEADER, SECTION_PAST));
|
||||
addPositionalListData(getPastEventsCount(), SECTION_PAST);
|
||||
|
||||
for (Map.Entry<String, GroupedEvents> value: listsGrouped.entrySet()) {
|
||||
if (value.getValue().getGroups().size() > 0)
|
||||
mPositionalData.add(new Triplet<>(TYPE_GROUPED, value.getKey(), value.getValue()));
|
||||
}
|
||||
for (Map.Entry<String, EventList> value: listsUngrouped.entrySet()) {
|
||||
if (value.getValue().size() > 0)
|
||||
mPositionalData.add(new Triplet<>(TYPE_UNGROUPED, value.getKey(), value.getValue()));
|
||||
}
|
||||
if (mPositionalData.size() == 0)
|
||||
mPositionalData.add(new Triplet<>(TYPE_NONE, null, null));
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void addPositionalListData(int count, int category) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
mPositionalData.add(new Pair<>(TYPE_ITEM, category+1024*i));
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
switch (viewType) {
|
||||
case TYPE_HEADER:
|
||||
case TYPE_NONE:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_caption, parent, false);
|
||||
return new StringViewHolder(view);
|
||||
case TYPE_ITEM:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_items, parent, false);
|
||||
return new ItemViewHolder(view);
|
||||
.inflate(R.layout.list_all_no_items, parent, false);
|
||||
return new CustomViewHolder(view);
|
||||
default:
|
||||
//noinspection ConstantConditions
|
||||
return null;
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_cardview_list, parent, false);
|
||||
return new ListViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,51 +116,25 @@ class ModDetailEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull final CustomViewHolder holder, int position) {
|
||||
if (mValue == null || position > mPositionalData.size())
|
||||
return;
|
||||
Pair<Integer, Integer> data = mPositionalData.get(position);
|
||||
Triplet<Integer, String, Object> data = mPositionalData.get(position);
|
||||
if (data.first != TYPE_NONE) {
|
||||
ListViewHolder h;
|
||||
ModDetailEventAdapterInner adapter;
|
||||
h = (ListViewHolder) holder;
|
||||
adapter = new ModDetailEventAdapterInner();
|
||||
h.mString.setText(data.second);
|
||||
switch (data.first) {
|
||||
case TYPE_HEADER:
|
||||
StringViewHolder h = (StringViewHolder) holder;
|
||||
switch (data.second) {
|
||||
case SECTION_PAST:
|
||||
h.mString.setText(R.string.past_events);
|
||||
case TYPE_GROUPED:
|
||||
adapter.setData((GroupedEvents) data.third, h.mView.getContext());
|
||||
break;
|
||||
case SECTION_UPCOMING:
|
||||
h.mString.setText(R.string.upcoming_events);
|
||||
case TYPE_UNGROUPED:
|
||||
adapter.setData((EventList) data.third, h.mView.getContext());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TYPE_ITEM:
|
||||
int section = data.second % 1024;
|
||||
int index = data.second / 1024;
|
||||
ItemViewHolder i = (ItemViewHolder) holder;
|
||||
Event event = null;
|
||||
switch (section) {
|
||||
case SECTION_UPCOMING:
|
||||
event = mValue.events.getUpcoming(index);
|
||||
break;
|
||||
case SECTION_PAST:
|
||||
event = mValue.events.getPast(index);
|
||||
break;
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
i.mTitle.setText(event.getTitle());
|
||||
i.mSubLeft.setText(event.getType());
|
||||
String start, end;
|
||||
if (UtilsDate.dateEquals(event.getStartDate(), System.currentTimeMillis()))
|
||||
start = UtilsDate.getModifiedTime(i.mView.getContext(), event.getStartDate());
|
||||
else
|
||||
start = UtilsDate.getModifiedDateTime(i.mView.getContext(), event.getStartDate());
|
||||
if (UtilsDate.dateEquals(event.getStartDate(), event.getEndDate()))
|
||||
end = UtilsDate.getModifiedTime(i.mView.getContext(), event.getEndDate());
|
||||
else
|
||||
end = UtilsDate.getModifiedDateTime(i.mView.getContext(), event.getEndDate());
|
||||
i.mSubRight.setText(i.mView.getResources().getString(R.string.date_scale,
|
||||
start, end
|
||||
));
|
||||
break;
|
||||
h.mList.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,15 +143,9 @@ class ModDetailEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
return mPositionalData.size();
|
||||
}
|
||||
|
||||
private int getUpcomingEventsCount() {
|
||||
private int getEventsCount() {
|
||||
if (mValue.events != null)
|
||||
return mValue.events.sizeUpcoming();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int getPastEventsCount() {
|
||||
if (mValue.events != null)
|
||||
return mValue.events.sizePast();
|
||||
return mValue.events.size();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package de.sebse.fuplanner.fragments.moddetails;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.services.KVV.types.Event;
|
||||
import de.sebse.fuplanner.services.KVV.types.EventList;
|
||||
import de.sebse.fuplanner.services.KVV.types.GroupedEvents;
|
||||
import de.sebse.fuplanner.tools.Triplet;
|
||||
import de.sebse.fuplanner.tools.UtilsDate;
|
||||
import de.sebse.fuplanner.tools.ui.CustomViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.ItemViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.ListViewHolder;
|
||||
|
||||
class ModDetailEventAdapterInner extends RecyclerView.Adapter<ItemViewHolder> {
|
||||
private final ArrayList<Entry> mPositionalData;
|
||||
|
||||
ModDetailEventAdapterInner() {
|
||||
mPositionalData = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setData(GroupedEvents events, final Context context) {
|
||||
mPositionalData.clear();
|
||||
for (GroupedEvents.Group group : events.getGroups()) {
|
||||
long firstDateTime = group.getFirstDate()+group.getStartTime();
|
||||
long lastDateTime = group.getLastDate()+group.getStartTime()+group.getDuration();
|
||||
String start, end, weekday, startTime, endTime;
|
||||
StringBuilder excepts = null;
|
||||
start = UtilsDate.getModifiedDate(firstDateTime);
|
||||
end = UtilsDate.getModifiedDate(lastDateTime);
|
||||
weekday = UtilsDate.getModifiedDate(context, firstDateTime, "E");
|
||||
startTime = UtilsDate.getModifiedTime(context, firstDateTime);
|
||||
endTime = UtilsDate.getModifiedTime(context, lastDateTime);
|
||||
for (long skippedDate : group.getSkippedDates()) {
|
||||
if (excepts == null) {
|
||||
excepts = new StringBuilder(UtilsDate.getModifiedDate(skippedDate));
|
||||
} else {
|
||||
excepts.append(", ").append(UtilsDate.getModifiedDate(skippedDate));
|
||||
}
|
||||
}
|
||||
mPositionalData.add(new Entry(
|
||||
context.getString(R.string.event_scale, weekday, startTime, endTime),
|
||||
context.getString(R.string.date_scale, start, end),
|
||||
excepts != null ? context.getString(R.string.except_list, excepts.toString()) : ""));
|
||||
}
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setData(EventList events, final Context context) {
|
||||
mPositionalData.clear();
|
||||
for (Event event : events) {
|
||||
String date;
|
||||
String start, end;
|
||||
if (UtilsDate.dateEquals(event.getStartDate(), System.currentTimeMillis()))
|
||||
start = UtilsDate.getModifiedTime(context, event.getStartDate());
|
||||
else
|
||||
start = UtilsDate.getModifiedDateTime(context, event.getStartDate());
|
||||
if (UtilsDate.dateEquals(event.getStartDate(), event.getEndDate()))
|
||||
end = UtilsDate.getModifiedTime(context, event.getEndDate());
|
||||
else
|
||||
end = UtilsDate.getModifiedDateTime(context, event.getEndDate());
|
||||
date = context.getString(R.string.date_scale, start, end);
|
||||
mPositionalData.add(new Entry(event.getTitle(), date, ""));
|
||||
}
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_items, parent, false);
|
||||
return new ItemViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ItemViewHolder holder, int position) {
|
||||
holder.mTitle.setText(mPositionalData.get(position).title);
|
||||
holder.mSubLeft.setText(mPositionalData.get(position).subtitleLeft);
|
||||
holder.mSubRight.setText(mPositionalData.get(position).subtitleRight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mPositionalData.size();
|
||||
}
|
||||
|
||||
private class Entry {
|
||||
private String title;
|
||||
private String subtitleLeft;
|
||||
private String subtitleRight;
|
||||
|
||||
private Entry(String title, String subtitleLeft, String subtitleRight) {
|
||||
this.title = title;
|
||||
this.subtitleLeft = subtitleLeft;
|
||||
this.subtitleRight = subtitleRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package de.sebse.fuplanner.services.KVV.types;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
|
||||
public class GroupedEvents {
|
||||
private ArrayList<Group> arrayList = new ArrayList<>();
|
||||
private Logger log = new Logger(this);
|
||||
|
||||
public void add(Event event) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(event.getStartDate());
|
||||
long dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
for (Group group : arrayList) {
|
||||
if (group.add(event)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
arrayList.add(new Group(event));
|
||||
}
|
||||
|
||||
public List<Group> getGroups() {
|
||||
return Collections.unmodifiableList(arrayList);
|
||||
}
|
||||
|
||||
public class Group {
|
||||
private long firstDate;
|
||||
private long lastDate;
|
||||
private ArrayList<Long> skippedDates;
|
||||
|
||||
private int dayOfWeek;
|
||||
private long startTime;
|
||||
private long duration;
|
||||
|
||||
private Group(Event event) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(event.getStartDate());
|
||||
dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
startTime = calendar.get(Calendar.HOUR_OF_DAY)*3600000+calendar.get(Calendar.MINUTE)*60000+calendar.get(Calendar.SECOND)*1000+calendar.get(Calendar.MILLISECOND);
|
||||
duration = event.getEndDate()-event.getStartDate();
|
||||
|
||||
skippedDates = new ArrayList<>();
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
firstDate = calendar.getTimeInMillis();
|
||||
lastDate = firstDate;
|
||||
}
|
||||
|
||||
private boolean add(Event event) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(event.getStartDate());
|
||||
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
int startTime = calendar.get(Calendar.HOUR_OF_DAY)*3600000+calendar.get(Calendar.MINUTE)*60000+calendar.get(Calendar.SECOND)*1000+calendar.get(Calendar.MILLISECOND);
|
||||
long length = event.getEndDate()-event.getStartDate();
|
||||
if (this.dayOfWeek != dayOfWeek || this.startTime != startTime || this.duration != length)
|
||||
return false;
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
long date = calendar.getTimeInMillis();
|
||||
if (date < firstDate) {
|
||||
firstDate = addDays(firstDate, -7);
|
||||
while (firstDate > date) {
|
||||
skippedDates.add(firstDate);
|
||||
firstDate = addDays(firstDate, -7);
|
||||
}
|
||||
} else if (date > lastDate) {
|
||||
lastDate = addDays(lastDate, 7);
|
||||
while (lastDate < date) {
|
||||
skippedDates.add(lastDate);
|
||||
lastDate = addDays(lastDate, 7);
|
||||
}
|
||||
} else {
|
||||
skippedDates.remove(date);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private long addDays(long timeInMillis, int days) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(timeInMillis);
|
||||
calendar.add(Calendar.DAY_OF_YEAR, days);
|
||||
return calendar.getTimeInMillis();
|
||||
}
|
||||
|
||||
public long getFirstDate() {
|
||||
return firstDate;
|
||||
}
|
||||
|
||||
public long getLastDate() {
|
||||
return lastDate;
|
||||
}
|
||||
|
||||
public List<Long> getSkippedDates() {
|
||||
return Collections.unmodifiableList(skippedDates);
|
||||
}
|
||||
|
||||
public int getDayOfWeek() {
|
||||
return dayOfWeek;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%d - %d - %d - %s", dayOfWeek, startTime, duration, skippedDates);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
app/src/main/java/de/sebse/fuplanner/tools/Triplet.java
Normal file
14
app/src/main/java/de/sebse/fuplanner/tools/Triplet.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package de.sebse.fuplanner.tools;
|
||||
|
||||
public class Triplet<T, U, V> {
|
||||
|
||||
public final T first;
|
||||
public final U second;
|
||||
public final V third;
|
||||
|
||||
public Triplet(T first, U second, V third) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
this.third = third;
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,8 @@ public class UtilsDate {
|
||||
|
||||
if (context != null && DateFormat.is24HourFormat(context))
|
||||
skeleton = skeleton.replaceAll("h", "H");
|
||||
if (context != null && !DateFormat.is24HourFormat(context))
|
||||
skeleton = skeleton.replaceAll("H", "h");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
dateFormat = new SimpleDateFormat(getDateFormat(locale, skeleton));
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package de.sebse.fuplanner.tools.ui;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.sebse.fuplanner.R;
|
||||
|
||||
public class ListViewHolder extends StringViewHolder {
|
||||
public final RecyclerView mList;
|
||||
|
||||
public ListViewHolder(View view) {
|
||||
super(view);
|
||||
mList = view.findViewById(R.id.list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " '" + mString.getText() + "'";
|
||||
}
|
||||
}
|
||||
25
app/src/main/res/layout/list_all_cardview_list.xml
Normal file
25
app/src/main/res/layout/list_all_cardview_list.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_margin="4dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/string"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
tools:text="Caption"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -68,4 +68,6 @@
|
||||
<string name="vegetarian">Vegetarisch</string>
|
||||
<string name="bio">Aus biologischem Anbau</string>
|
||||
<string name="attachment_nr">%1$d. Anhang</string>
|
||||
<string name="event_scale">%1$s, %2$s - %3$s</string>
|
||||
<string name="except_list">Entfällt: %1$s</string>
|
||||
</resources>
|
||||
@@ -76,4 +76,6 @@
|
||||
<string name="bio">Organic Food</string>
|
||||
<string name="msc" translatable="false">MSC</string>
|
||||
<string name="attachment_nr">Attachment #%1$d</string>
|
||||
<string name="event_scale">%1$s, %2$s - %3$s</string>
|
||||
<string name="except_list">Except: %1$s</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user