Implemented Cards for Canteen

This commit is contained in:
Caesar2011
2018-08-12 00:53:51 +02:00
parent f0bd6d1454
commit 4a1fc3e28b
20 changed files with 609 additions and 85 deletions

View File

@@ -19,7 +19,7 @@ import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.KVV.KVV; import de.sebse.fuplanner.services.KVV.KVV;
import de.sebse.fuplanner.services.KVV.types.Event; import de.sebse.fuplanner.services.KVV.types.Event;
import de.sebse.fuplanner.services.KVV.types.Modules; import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
import de.sebse.fuplanner.tools.MainAcitivityListener; import de.sebse.fuplanner.tools.MainAcitivityListener;
import de.sebse.fuplanner.tools.logging.Logger; import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.ui.weekview.MonthLoader; import de.sebse.fuplanner.tools.ui.weekview.MonthLoader;
@@ -144,7 +144,7 @@ public class ScheduleFragment extends Fragment implements MonthLoader.MonthChang
public void onFirstVisibleDayChanged(Calendar newFirstVisibleDay, Calendar oldFirstVisibleDay) { public void onFirstVisibleDayChanged(Calendar newFirstVisibleDay, Calendar oldFirstVisibleDay) {
Calendar newLastVisibleDay = (Calendar) newFirstVisibleDay.clone(); Calendar newLastVisibleDay = (Calendar) newFirstVisibleDay.clone();
newLastVisibleDay.add(Calendar.HOUR, 24*mWeekView.getNumberOfVisibleDays()); newLastVisibleDay.add(Calendar.HOUR, 24*mWeekView.getNumberOfVisibleDays());
mListener.onTitleTextChange(getResources().getString(R.string.date_scale, DateUtils.getModifiedDate(newFirstVisibleDay.getTimeInMillis()), DateUtils.getModifiedDate(newLastVisibleDay.getTimeInMillis()))); mListener.onTitleTextChange(getResources().getString(R.string.date_scale, UtilsDate.getModifiedDate(newFirstVisibleDay.getTimeInMillis()), UtilsDate.getModifiedDate(newLastVisibleDay.getTimeInMillis())));
} }
@@ -191,7 +191,7 @@ public class ScheduleFragment extends Fragment implements MonthLoader.MonthChang
.setMessage( .setMessage(
getResources().getString(R.string.module_name, moduleName) + "\n" + getResources().getString(R.string.module_name, moduleName) + "\n" +
getResources().getString(R.string.location_name, event.getLocation()) + "\n" + getResources().getString(R.string.location_name, event.getLocation()) + "\n" +
getResources().getString(R.string.date_scale, DateUtils.getModifiedTime(getContext(), event.getStartTime().getTimeInMillis()), DateUtils.getModifiedTime(getContext(), event.getEndTime().getTimeInMillis()+1)) getResources().getString(R.string.date_scale, UtilsDate.getModifiedTime(getContext(), event.getStartTime().getTimeInMillis()), UtilsDate.getModifiedTime(getContext(), event.getEndTime().getTimeInMillis()+1))
) )
.setCancelable(true) .setCancelable(true)
.setNeutralButton(R.string.close, (dialog, id) -> dialog.cancel()); .setNeutralButton(R.string.close, (dialog, id) -> dialog.cancel());

View File

@@ -5,7 +5,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentStatePagerAdapter;
import de.sebse.fuplanner.services.Canteen.types.Canteen; import de.sebse.fuplanner.services.Canteen.types.Canteen;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
class DaySwitcherAdapter extends FragmentStatePagerAdapter { class DaySwitcherAdapter extends FragmentStatePagerAdapter {
private Canteen mCanteen = null; private Canteen mCanteen = null;
@@ -39,7 +39,7 @@ class DaySwitcherAdapter extends FragmentStatePagerAdapter {
// Returns the page title for the top indicator // Returns the page title for the top indicator
@Override @Override
public CharSequence getPageTitle(int position) { public CharSequence getPageTitle(int position) {
return DateUtils.getModifiedDate(mCanteen.get(position).getCalendar().getTimeInMillis()); return UtilsDate.getModifiedDate(mCanteen.get(position).getCalendar().getTimeInMillis());
} }
} }

View File

@@ -1,19 +1,20 @@
package de.sebse.fuplanner.fragments.canteen; package de.sebse.fuplanner.fragments.canteen;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import de.sebse.fuplanner.R; import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.Canteen.types.Day; import de.sebse.fuplanner.services.Canteen.types.Day;
import de.sebse.fuplanner.services.Canteen.types.Meal; import de.sebse.fuplanner.services.Canteen.types.Meal;
import de.sebse.fuplanner.tools.Preferences; import de.sebse.fuplanner.tools.Preferences;
import de.sebse.fuplanner.tools.ui.ItemViewHolder; import de.sebse.fuplanner.tools.ui.ItemViewHolder;
import de.sebse.fuplanner.tools.ui.StringViewHolder; import de.sebse.fuplanner.tools.ui.MealViewHolder;
class MealAdapter extends BaseExpandableListAdapter { class MealAdapter extends RecyclerView.Adapter<MealViewHolder> {
private Day mDay = null; private Day mDay = null;
private final Context mContext; private final Context mContext;
@@ -22,7 +23,51 @@ class MealAdapter extends BaseExpandableListAdapter {
mContext = context; mContext = context;
} }
@NonNull
@Override @Override
public MealViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.list_canteen_items, viewGroup, false);
return new MealViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MealViewHolder viewHolder, int i) {
Meal meal = getItem(i);
viewHolder.mTitle.setText(meal.getName());
String value;
switch (Preferences.getString(mContext, R.array.pref_price_group)) {
case "student":
value = mContext.getString(R.string.price, meal.getPriceStdnt());
break;
case "employee":
value = mContext.getString(R.string.price, meal.getPriceEmply());
break;
case "other":
value = mContext.getString(R.string.price, meal.getPriceOther());
break;
default:
value = mContext.getString(R.string.prices, meal.getPriceStdnt(), meal.getPriceEmply(), meal.getPriceOther());
}
viewHolder.mSubTitle.setText(value);
}
public Meal getItem(int groupPosition) {
if (this.mDay != null)
return this.mDay.get(groupPosition);
else
return null;
}
@Override
public int getItemCount() {
if (this.mDay != null)
return this.mDay.size();
else
return 0;
}
/*@Override
public String getChild(int groupPosition, int childPosititon) { public String getChild(int groupPosition, int childPosititon) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("\n\n"); sb.append("\n\n");
@@ -92,8 +137,8 @@ class MealAdapter extends BaseExpandableListAdapter {
} }
ItemViewHolder itemHolder = new ItemViewHolder(convertView); ItemViewHolder itemHolder = new ItemViewHolder(convertView);
itemHolder.mTitle.setText(meal.getName()); //itemHolder.mTitle.setText(meal.getName());
itemHolder.mSubLeft.setText(meal.getCategory()); //itemHolder.mSubLeft.setText(meal.getCategory());
String value; String value;
switch (Preferences.getString(mContext, R.array.pref_price_group)) { switch (Preferences.getString(mContext, R.array.pref_price_group)) {
case "student": case "student":
@@ -108,7 +153,7 @@ class MealAdapter extends BaseExpandableListAdapter {
default: default:
value = mContext.getString(R.string.prices, meal.getPriceStdnt(), meal.getPriceEmply(), meal.getPriceOther()); value = mContext.getString(R.string.prices, meal.getPriceStdnt(), meal.getPriceEmply(), meal.getPriceOther());
} }
itemHolder.mSubRight.setText(value); //itemHolder.mSubRight.setText(value);
return convertView; return convertView;
} }
@@ -121,7 +166,7 @@ class MealAdapter extends BaseExpandableListAdapter {
@Override @Override
public boolean isChildSelectable(int groupPosition, int childPosition) { public boolean isChildSelectable(int groupPosition, int childPosition) {
return false; return false;
} }*/
public void setDay(Day day) { public void setDay(Day day) {
this.mDay = day; this.mDay = day;

View File

@@ -6,6 +6,7 @@ import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -69,9 +70,9 @@ public class MealFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_expandable_list_view, container, false); View view = inflater.inflate(R.layout.fragment_recycler_view, container, false);
// Set the adapter // Set the adapter
ExpandableListView expandableListView = view.findViewById(R.id.list); RecyclerView expandableListView = view.findViewById(R.id.list);
adapter = new MealAdapter(getContext()); adapter = new MealAdapter(getContext());
expandableListView.setAdapter(adapter); expandableListView.setAdapter(adapter);

View File

@@ -10,7 +10,7 @@ import java.util.ArrayList;
import de.sebse.fuplanner.R; import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.KVV.types.Announcement; import de.sebse.fuplanner.services.KVV.types.Announcement;
import de.sebse.fuplanner.services.KVV.types.Modules; import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
import de.sebse.fuplanner.tools.ui.ItemViewHolder; import de.sebse.fuplanner.tools.ui.ItemViewHolder;
import de.sebse.fuplanner.tools.ui.StringViewHolder; import de.sebse.fuplanner.tools.ui.StringViewHolder;
@@ -89,7 +89,7 @@ class ModDetailAnnounceAdapter extends BaseExpandableListAdapter {
ItemViewHolder itemHolder = new ItemViewHolder(convertView); ItemViewHolder itemHolder = new ItemViewHolder(convertView);
itemHolder.mTitle.setText(announce.getTitle()); itemHolder.mTitle.setText(announce.getTitle());
itemHolder.mSubLeft.setText(announce.getCreatedBy()); itemHolder.mSubLeft.setText(announce.getCreatedBy());
itemHolder.mSubRight.setText(DateUtils.getModifiedDateTime(parent.getContext(), announce.getCreatedOn())); itemHolder.mSubRight.setText(UtilsDate.getModifiedDateTime(parent.getContext(), announce.getCreatedOn()));
return convertView; return convertView;
} }

View File

@@ -8,7 +8,7 @@ import android.widget.BaseExpandableListAdapter;
import de.sebse.fuplanner.R; import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.KVV.types.Assignment; import de.sebse.fuplanner.services.KVV.types.Assignment;
import de.sebse.fuplanner.services.KVV.types.Modules; import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
import de.sebse.fuplanner.tools.ui.ItemViewHolder; import de.sebse.fuplanner.tools.ui.ItemViewHolder;
import de.sebse.fuplanner.tools.ui.StringViewHolder; import de.sebse.fuplanner.tools.ui.StringViewHolder;
@@ -92,7 +92,7 @@ class ModDetailAssignmentAdapter extends BaseExpandableListAdapter {
itemHolder.mSubLeft.setText(itemHolder.mView.getResources().getText(R.string.open)); itemHolder.mSubLeft.setText(itemHolder.mView.getResources().getText(R.string.open));
else else
itemHolder.mSubLeft.setText(itemHolder.mView.getResources().getText(R.string.closed)); itemHolder.mSubLeft.setText(itemHolder.mView.getResources().getText(R.string.closed));
itemHolder.mSubRight.setText(DateUtils.getModifiedDateTime(parent.getContext(), assignment.getDueDate())); itemHolder.mSubRight.setText(UtilsDate.getModifiedDateTime(parent.getContext(), assignment.getDueDate()));
return convertView; return convertView;
} }

View File

@@ -13,7 +13,7 @@ import java.util.ArrayList;
import de.sebse.fuplanner.R; import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.KVV.types.Event; import de.sebse.fuplanner.services.KVV.types.Event;
import de.sebse.fuplanner.services.KVV.types.Modules; import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
import de.sebse.fuplanner.tools.ui.CustomViewHolder; import de.sebse.fuplanner.tools.ui.CustomViewHolder;
import de.sebse.fuplanner.tools.ui.ItemViewHolder; import de.sebse.fuplanner.tools.ui.ItemViewHolder;
@@ -114,14 +114,14 @@ class ModDetailEventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
i.mTitle.setText(event.getTitle()); i.mTitle.setText(event.getTitle());
i.mSubLeft.setText(event.getType()); i.mSubLeft.setText(event.getType());
String start, end; String start, end;
if (DateUtils.dateEquals(event.getStartDate(), System.currentTimeMillis())) if (UtilsDate.dateEquals(event.getStartDate(), System.currentTimeMillis()))
start = DateUtils.getModifiedTime(i.mView.getContext(), event.getStartDate()); start = UtilsDate.getModifiedTime(i.mView.getContext(), event.getStartDate());
else else
start = DateUtils.getModifiedDateTime(i.mView.getContext(), event.getStartDate()); start = UtilsDate.getModifiedDateTime(i.mView.getContext(), event.getStartDate());
if (DateUtils.dateEquals(event.getStartDate(), event.getEndDate())) if (UtilsDate.dateEquals(event.getStartDate(), event.getEndDate()))
end = DateUtils.getModifiedTime(i.mView.getContext(), event.getEndDate()); end = UtilsDate.getModifiedTime(i.mView.getContext(), event.getEndDate());
else else
end = DateUtils.getModifiedDateTime(i.mView.getContext(), event.getEndDate()); end = UtilsDate.getModifiedDateTime(i.mView.getContext(), event.getEndDate());
i.mSubRight.setText(i.mView.getResources().getString(R.string.date_scale, i.mSubRight.setText(i.mView.getResources().getString(R.string.date_scale,
start, end start, end
)); ));

View File

@@ -18,7 +18,7 @@ import de.sebse.fuplanner.services.KVV.types.Announcement;
import de.sebse.fuplanner.services.KVV.types.Assignment; import de.sebse.fuplanner.services.KVV.types.Assignment;
import de.sebse.fuplanner.services.KVV.types.Event; import de.sebse.fuplanner.services.KVV.types.Event;
import de.sebse.fuplanner.services.KVV.types.Modules; import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
import de.sebse.fuplanner.tools.logging.Logger; import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.ui.CustomViewHolder; import de.sebse.fuplanner.tools.ui.CustomViewHolder;
import de.sebse.fuplanner.tools.ui.ItemViewHolder; import de.sebse.fuplanner.tools.ui.ItemViewHolder;
@@ -141,7 +141,7 @@ class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
Announcement announce = mValue.announcements.get(index); Announcement announce = mValue.announcements.get(index);
i.mTitle.setText(announce.getTitle()); i.mTitle.setText(announce.getTitle());
i.mSubLeft.setText(announce.getCreatedBy()); i.mSubLeft.setText(announce.getCreatedBy());
i.mSubRight.setText(DateUtils.getModifiedDateTime(i.mView.getContext(), announce.getCreatedOn())); i.mSubRight.setText(UtilsDate.getModifiedDateTime(i.mView.getContext(), announce.getCreatedOn()));
i.mView.setOnClickListener(view -> { i.mView.setOnClickListener(view -> {
if (mListener != null) mListener.gotoFragmentPart(section, index); if (mListener != null) mListener.gotoFragmentPart(section, index);
}); });
@@ -154,7 +154,7 @@ class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
i.mSubLeft.setText(i.mView.getResources().getText(R.string.open)); i.mSubLeft.setText(i.mView.getResources().getText(R.string.open));
else else
i.mSubLeft.setText(i.mView.getResources().getText(R.string.closed)); i.mSubLeft.setText(i.mView.getResources().getText(R.string.closed));
i.mSubRight.setText(DateUtils.getModifiedDateTime(i.mView.getContext(), assignment.getDueDate())); i.mSubRight.setText(UtilsDate.getModifiedDateTime(i.mView.getContext(), assignment.getDueDate()));
i.mView.setOnClickListener(view -> { i.mView.setOnClickListener(view -> {
if (mListener != null) mListener.gotoFragmentPart(section, index); if (mListener != null) mListener.gotoFragmentPart(section, index);
}); });
@@ -165,14 +165,14 @@ class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
i.mTitle.setText(event.getTitle()); i.mTitle.setText(event.getTitle());
i.mSubLeft.setText(event.getType()); i.mSubLeft.setText(event.getType());
String start, end; String start, end;
if (DateUtils.dateEquals(event.getStartDate(), System.currentTimeMillis())) if (UtilsDate.dateEquals(event.getStartDate(), System.currentTimeMillis()))
start = DateUtils.getModifiedTime(i.mView.getContext(), event.getStartDate()); start = UtilsDate.getModifiedTime(i.mView.getContext(), event.getStartDate());
else else
start = DateUtils.getModifiedDateTime(i.mView.getContext(), event.getStartDate()); start = UtilsDate.getModifiedDateTime(i.mView.getContext(), event.getStartDate());
if (DateUtils.dateEquals(event.getStartDate(), event.getEndDate())) if (UtilsDate.dateEquals(event.getStartDate(), event.getEndDate()))
end = DateUtils.getModifiedTime(i.mView.getContext(), event.getEndDate()); end = UtilsDate.getModifiedTime(i.mView.getContext(), event.getEndDate());
else else
end = DateUtils.getModifiedDateTime(i.mView.getContext(), event.getEndDate()); end = UtilsDate.getModifiedDateTime(i.mView.getContext(), event.getEndDate());
i.mSubRight.setText(i.mView.getResources().getString(R.string.date_scale, i.mSubRight.setText(i.mView.getResources().getString(R.string.date_scale,
start, end start, end
)); ));

View File

@@ -13,7 +13,7 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
public class DateUtils { public class UtilsDate {
@Deprecated @Deprecated
public static String getModifiedDateTime(long modified) { public static String getModifiedDateTime(long modified) {
return getModifiedDateTime(null, modified); return getModifiedDateTime(null, modified);

View File

@@ -0,0 +1,18 @@
package de.sebse.fuplanner.tools;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
public class UtilsUi {
public static float convertPixelsToDp(float px, Context context) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return dp;
}
public static float convertDpToPixels(Context context, float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
}

View File

@@ -0,0 +1,23 @@
package de.sebse.fuplanner.tools.ui;
import android.view.View;
import android.widget.TextView;
import de.sebse.fuplanner.R;
public class MealViewHolder extends CustomViewHolder {
public final TextView mTitle;
public final TextView mSubTitle;
public MealViewHolder(View view) {
super(view);
mTitle = view.findViewById(R.id.title);
mSubTitle = view.findViewById(R.id.sub_title);
}
@Override
public String toString() {
return super.toString() + " '" + mTitle.getText() + "' '" + mSubTitle.getText() + "'";
}
}

View File

@@ -0,0 +1,342 @@
package de.sebse.fuplanner.tools.ui.cardview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.CardView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.view.animation.Transformation;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.UtilsUi;
/**
*
* Copyright (c) 2018 Alessandro Sperotti
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Created by alessandros on 23/02/2018.
* @author Alessandro Sperotti
*/
public class ExpandableCardView extends LinearLayout {
private String title;
private ViewGroup containerView;
private ImageButton arrowBtn;
//private ImageButton headerIcon;
//private TextView textViewTitle;
private int innerViewRes;
private int outerViewRes;
//private Drawable iconDrawable;
private CardView card;
public static final int DEFAULT_ANIM_DURATION = 350;
private long animDuration = DEFAULT_ANIM_DURATION;
private final static int COLLAPSING = 0;
private final static int EXPANDING = 1;
private boolean isExpanded = false;
private boolean isExpanding = false;
private boolean isCollapsing = false;
private boolean expandOnClick = false;
private boolean startExpanded = false;
private int previousHeight = 0;
private OnExpandedListener listener;
private OnClickListener defaultClickListener = v -> {
if(isExpanded()) collapse();
else expand();
};
public ExpandableCardView(Context context) {
super(context);
}
public ExpandableCardView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttributes(context, attrs);
initView(context);
}
public ExpandableCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttributes(context, attrs);
initView(context);
}
private void initView(Context context){
//Inflating View
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater == null) throw new AssertionError();
inflater.inflate(R.layout.expandable_cardview, this);
}
private void initAttributes(Context context, AttributeSet attrs){
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ExpandableCardView);
title = typedArray.getString(R.styleable.ExpandableCardView_title);
//iconDrawable = typedArray.getDrawable(R.styleable.ExpandableCardView_icon);
innerViewRes = typedArray.getResourceId(R.styleable.ExpandableCardView_inner_view, View.NO_ID);
outerViewRes = typedArray.getResourceId(R.styleable.ExpandableCardView_outer_view, View.NO_ID);
expandOnClick = typedArray.getBoolean(R.styleable.ExpandableCardView_expandOnClick, false);
animDuration = typedArray.getInteger(R.styleable.ExpandableCardView_animationDuration, DEFAULT_ANIM_DURATION);
startExpanded = typedArray.getBoolean(R.styleable.ExpandableCardView_startExpanded, false);
typedArray.recycle();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
arrowBtn = findViewById(R.id.arrow);
//textViewTitle = findViewById(R.id.title);
//headerIcon = findViewById(R.id.icon);
//Setting attributes
/*if(!TextUtils.isEmpty(title)) textViewTitle.setText(title);
if(iconDrawable != null){
headerIcon.setVisibility(VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
headerIcon.setBackground(iconDrawable);
}
}*/
card = findViewById(R.id.card);
setInnerView(innerViewRes);
setOuterView(outerViewRes);
containerView = findViewById(R.id.viewContainer);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setElevation(UtilsUi.convertDpToPixels(getContext(), 4));
}
if(startExpanded){
setAnimDuration(0);
expand();
setAnimDuration(animDuration);
}
if(expandOnClick){
card.setOnClickListener(defaultClickListener);
arrowBtn.setOnClickListener(defaultClickListener);
}
}
public void expand() {
final int initialHeight = card.getHeight();
if(!isMoving()) {
previousHeight = initialHeight;
}
card.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
int targetHeight = card.getMeasuredHeight();
if(targetHeight - initialHeight != 0) {
animateViews(initialHeight,
targetHeight - initialHeight,
EXPANDING);
}
}
public void collapse() {
int initialHeight = card.getMeasuredHeight();
if(initialHeight - previousHeight != 0) {
animateViews(initialHeight,
initialHeight - previousHeight,
COLLAPSING);
}
}
public boolean isExpanded() {
return isExpanded;
}
private void animateViews(final int initialHeight, final int distance, final int animationType){
Animation expandAnimation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1){
//Setting isExpanding/isCollapsing to false
isExpanding = false;
isCollapsing = false;
if(listener != null){
if(animationType == EXPANDING){
listener.onExpandChanged(card,true);
}
else{
listener.onExpandChanged(card,false);
}
}
}
card.getLayoutParams().height = animationType == EXPANDING ? (int) (initialHeight + (distance * interpolatedTime)) :
(int) (initialHeight - (distance * interpolatedTime));
card.findViewById(R.id.viewContainer).requestLayout();
containerView.getLayoutParams().height = animationType == EXPANDING ? (int) (initialHeight + (distance * interpolatedTime)) :
(int) (initialHeight - (distance * interpolatedTime));
}
@Override
public boolean willChangeBounds() {
return true;
}
};
RotateAnimation arrowAnimation = animationType == EXPANDING ?
new RotateAnimation(0,180,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f) :
new RotateAnimation(180,0,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
arrowAnimation.setFillAfter(true);
arrowAnimation.setDuration(animDuration);
expandAnimation.setDuration(animDuration);
isExpanding = animationType == EXPANDING;
isCollapsing = animationType == COLLAPSING;
startAnimation(expandAnimation);
//Log.d("SO","Started animation: "+ (animationType == EXPANDING ? "Expanding" : "Collapsing"));
arrowBtn.startAnimation(arrowAnimation);
isExpanded = animationType == EXPANDING;
}
private boolean isExpanding(){
return isExpanding;
}
private boolean isCollapsing(){
return isCollapsing;
}
private boolean isMoving(){
return isExpanding() || isCollapsing();
}
public void setOnExpandedListener(OnExpandedListener listener) {
this.listener = listener;
}
public void removeOnExpandedListener(){
this.listener = null;
}
/*public void setTitle(String title){
if(textViewTitle != null) textViewTitle.setText(title);
}
public void setTitle(int resId){
if(textViewTitle != null) textViewTitle.setText(resId);
}
public void setIcon(Drawable drawable){
if(headerIcon != null){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
headerIcon.setBackground(drawable);
}
iconDrawable = drawable;
}
}
public void setIcon(int resId){
if(headerIcon != null){
iconDrawable = ContextCompat.getDrawable(getContext(), resId);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
headerIcon.setBackground(iconDrawable);
}
}
}*/
private void setInnerView(int resId){
ViewStub stub = findViewById(R.id.viewStub);
stub.setLayoutResource(resId);
stub.inflate();
}
private void setOuterView(int resId){
ViewStub stub = findViewById(R.id.headerStub);
stub.setLayoutResource(resId);
View view = stub.inflate();
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
if(arrowBtn != null) arrowBtn.setOnClickListener(l);
super.setOnClickListener(l);
}
public long getAnimDuration() {
return animDuration;
}
public void setAnimDuration(long animDuration) {
this.animDuration = animDuration;
}
/**
* Interfaces
*/
public interface OnExpandedListener {
void onExpandChanged(View v, boolean isExpanded);
}
}

View File

@@ -9,7 +9,6 @@ import android.graphics.Paint;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@@ -47,7 +46,7 @@ import java.util.Locale;
import de.sebse.fuplanner.R; import de.sebse.fuplanner.R;
import de.sebse.fuplanner.tools.ColorRes; import de.sebse.fuplanner.tools.ColorRes;
import de.sebse.fuplanner.tools.DateUtils; import de.sebse.fuplanner.tools.UtilsDate;
import de.sebse.fuplanner.tools.logging.Logger; import de.sebse.fuplanner.tools.logging.Logger;
import static de.sebse.fuplanner.tools.ui.weekview.WeekViewUtil.daysBetween; import static de.sebse.fuplanner.tools.ui.weekview.WeekViewUtil.daysBetween;
@@ -1653,7 +1652,7 @@ public class WeekView extends View {
@Override @Override
public String interpretDate(Calendar date) { public String interpretDate(Calendar date) {
try { try {
return DateUtils.getModifiedDate(getContext(), date.getTimeInMillis(), "EEE dd.M").toUpperCase(); return UtilsDate.getModifiedDate(getContext(), date.getTimeInMillis(), "EEE dd.M").toUpperCase();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";

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:fillColor="#FF000000"
android:pathData="M7.41,7.84L12,12.42l4.59,-4.58L18,9.25l-6,6 -6,-6z"/>
</vector>

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="@+id/card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/default_vertical_padding"
android:paddingBottom="@dimen/default_vertical_padding"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="@+id/viewContainer"
android:layout_width="match_parent"
android:layout_height="@dimen/default_card_height"
android:gravity="center_vertical"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/default_card_height"
android:id="@+id/header"
android:gravity="center_vertical">
<!--<ImageButton
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/FUTheme.itemTitle"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:maxLines="1"
android:maxLength="39"
android:layout_toEndOf="@+id/icon"
android:layout_toRightOf="@+id/icon" />
<!-
android:textSize="16sp"
android:textColor="@android:color/primary_text_light"
-->
<ViewStub
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/headerStub"
android:inflatedId="@+id/outerView"
android:layout_toLeftOf="@id/arrow"
android:layout_toStartOf="@id/arrow"/>
<ImageButton
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_alignParentRight="true"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/arrow_down"
android:layout_marginEnd="20dp"
android:layout_alignParentEnd="true" />
</RelativeLayout>
<ViewStub
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/viewStub"
android:inflatedId="@+id/innerView"/>
</LinearLayout>
</android.support.v7.widget.CardView>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/FUTheme.itemTitle" />
<TextView
android:id="@+id/sub_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
style="@style/FUTheme.itemValue" />
</RelativeLayout>

View File

@@ -1,51 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <de.sebse.fuplanner.tools.ui.cardview.ExpandableCardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:id="@+id/profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="5dip" app:title="Passengers"
android:layout_margin="5dip"> app:outer_view="@layout/list_canteen_header"
<TextView app:inner_view="@layout/list_all_show_more"
android:id="@+id/title" app:expandOnClick="true"
android:layout_width="wrap_content" app:animationDuration="300"
android:layout_height="wrap_content" app:startExpanded="false" />
android:textStyle="bold" <!--
android:typeface="sans"
tools:text="Test this new stuff!" />
<TextView app:icon="@drawable/ic_event"
android:id="@+id/sub_left" -->
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginTop="5dip"
android:textColor="#343434"
android:textSize="12sp"
tools:text="Peter Bauer" />
<TextView
android:id="@+id/sub_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/sub_left"
android:layout_alignBottom="@id/sub_left"
android:textColor="#343434"
android:textSize="12sp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
tools:text="20.03.18 18:42 Uhr" />
<TextView
android:id="@+id/top_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/title"
android:layout_alignBottom="@id/title"
android:textColor="#343434"
android:textSize="12sp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
tools:text="Raum 105"
tools:ignore="RelativeOverlap" />
</android.support.v7.widget.CardView>

View File

@@ -62,4 +62,13 @@
<attr name="dropListenerEnabled" format="boolean" /> <attr name="dropListenerEnabled" format="boolean" />
<attr name="defaultEventColor" format="color" /> <attr name="defaultEventColor" format="color" />
</declare-styleable> </declare-styleable>
<declare-styleable name="ExpandableCardView">
<attr name="title" format="string"/>
<attr name="icon" format="reference"/>
<attr name="outer_view" format="reference"/>
<attr name="inner_view" format="reference"/>
<attr name="expandOnClick" format="boolean"/>
<attr name="animationDuration" format="integer"/>
<attr name="startExpanded" format="boolean"/>
</declare-styleable>
</resources> </resources>

View File

@@ -5,4 +5,8 @@
<dimen name="nav_header_vertical_spacing">16dp</dimen> <dimen name="nav_header_vertical_spacing">16dp</dimen>
<dimen name="nav_header_height">170dp</dimen> <dimen name="nav_header_height">170dp</dimen>
<dimen name="text_margin">16dp</dimen> <dimen name="text_margin">16dp</dimen>
<dimen name="default_card_height">50dp</dimen>
<dimen name="default_vertical_padding">10dp</dimen>
</resources> </resources>

View File

@@ -20,4 +20,14 @@
<item name="colorAccent">@color/colorFUBlue</item> <item name="colorAccent">@color/colorFUBlue</item>
</style> </style>
<style name="FUTheme.itemTitle">
<item name="android:textStyle">bold</item>
<item name="android:textSize">12sp</item>
<item name="android:textColor">@android:color/primary_text_light</item>
</style>
<style name="FUTheme.itemValue">
<item name="android:textSize">12sp</item>
<item name="android:textColor">#343434</item>
</style>
</resources> </resources>