[android] Editor UI

This commit is contained in:
Dmitry Yunitsky 2016-01-11 13:01:40 +03:00 committed by Sergey Yershov
parent dfefd19efe
commit 24eb7eddb4
8 changed files with 982 additions and 7 deletions

View file

@ -15,6 +15,7 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
@ -42,6 +43,7 @@ import com.mapswithme.maps.bookmarks.ChooseBookmarkCategoryFragment;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.bookmarks.data.MapObject.ApiPoint;
import com.mapswithme.maps.bookmarks.data.Metadata;
import com.mapswithme.maps.editor.EditorActivity;
import com.mapswithme.maps.editor.EditorFragment;
import com.mapswithme.maps.location.LocationHelper;
@ -64,6 +66,7 @@ import com.mapswithme.maps.widget.menu.MainMenu;
import com.mapswithme.maps.widget.placepage.BasePlacePageAnimationController;
import com.mapswithme.maps.widget.placepage.PlacePageView;
import com.mapswithme.maps.widget.placepage.PlacePageView.State;
import com.mapswithme.maps.widget.placepage.TimetableFragment;
import com.mapswithme.util.Animations;
import com.mapswithme.util.BottomSheetHelper;
import com.mapswithme.util.Config;
@ -99,7 +102,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
private static final String[] DOCKED_FRAGMENTS = { SearchFragment.class.getName(),
DownloadFragment.class.getName(),
RoutingPlanFragment.class.getName(),
EditorFragment.class.getName() };
TimetableFragment.class.getName() };
// Instance state
private static final String STATE_PP_OPENED = "PpOpened";
private static final String STATE_MAP_OBJECT = "MapObject";
@ -252,11 +255,14 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void showEditor(MapObject point)
{
final String openingTime = point.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS);
// TODO use EditorFragment after is will be finished
if (mIsFragmentContainer)
{
final Bundle args = new Bundle();
args.putParcelable(EditorFragment.EXTRA_POINT, point);
replaceFragment(EditorFragment.class, args, null);
if (!TextUtils.isEmpty(openingTime))
args.putString(TimetableFragment.EXTRA_TIME, openingTime);
replaceFragment(TimetableFragment.class, args, null);
}
else
EditorActivity.start(this, point);

View file

@ -0,0 +1,25 @@
package com.mapswithme.maps.base;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.mapswithme.maps.widget.ToolbarController;
public class BaseMwmToolbarFragment extends BaseMwmFragment
{
protected ToolbarController mToolbarController;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
mToolbarController = onCreateToolbarController(view);
}
protected ToolbarController onCreateToolbarController(@NonNull View root)
{
return new ToolbarController(root, getActivity());
}
}

View file

@ -3,29 +3,37 @@ package com.mapswithme.maps.editor;
import android.app.Activity;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.maps.bookmarks.data.MapObject;
import com.mapswithme.maps.bookmarks.data.Metadata;
import com.mapswithme.maps.widget.placepage.TimetableFragment;
public class EditorActivity extends BaseMwmFragmentActivity
{
@Override
protected Class<? extends Fragment> getFragmentClass()
{
return EditorFragment.class;
// TODO use EditorFragment after is will be finished
return TimetableFragment.class;
}
@Override
public void onBackPressed()
{
final EditorFragment fragment = (EditorFragment)getSupportFragmentManager().findFragmentByTag(getFragmentClass().getName());
final TimetableFragment fragment = (TimetableFragment) getSupportFragmentManager().findFragmentByTag(getFragmentClass().getName());
if ((fragment == null) || !fragment.isAdded() || !fragment.onBackPressed())
super.onBackPressed();
}
public static void start(Activity activity, MapObject point)
{
activity.startActivity(new Intent(activity, EditorActivity.class)
.putExtra(EditorFragment.EXTRA_POINT, point));
final Intent intent = new Intent(activity, EditorActivity.class);
final String openHours = point.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS);
if (!TextUtils.isEmpty(openHours))
intent.putExtra(TimetableFragment.EXTRA_TIME, openHours);
activity.startActivity(intent);
}
}

View file

@ -0,0 +1,103 @@
package com.mapswithme.maps.widget.placepage;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.editor.OpeningHours;
import com.mapswithme.maps.editor.data.Timetable;
import com.mapswithme.util.UiUtils;
public class AdvancedTimetableFragment extends BaseMwmFragment
implements View.OnClickListener,
TimetableFragment.TimetableProvider
{
private boolean mIsExampleShown;
private EditText mInput;
private View mExample;
private ImageView mIndicator;
private Timetable[] mInitTimetables;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_timetable_advanced, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
initViews(view);
refreshTimetables();
showExample(false);
}
@Override
public void onResume()
{
super.onResume();
refreshTimetables();
}
private void initViews(View view)
{
view.findViewById(R.id.examples).setOnClickListener(this);
mInput = (EditText) view.findViewById(R.id.et__timetable);
mExample = view.findViewById(R.id.tv__examples);
mIndicator = (ImageView) view.findViewById(R.id.iv__indicator);
}
private void showExample(boolean show)
{
mIsExampleShown = show;
if (mIsExampleShown)
{
UiUtils.show(mExample);
// TODO yunikkk animate indicator
mIndicator.setImageResource(R.drawable.ic_expand_less);
}
else
{
UiUtils.hide(mExample);
mIndicator.setImageResource(R.drawable.ic_expand_more);
}
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.examples:
showExample(!mIsExampleShown);
}
}
@Override
public Timetable[] getTimetables()
{
if (mInput.length() == 0)
return OpeningHours.nativeGetDefaultTimetables();
return OpeningHours.nativeTimetablesFromString(mInput.getText().toString());
}
public void setTimetables(Timetable[] timetables)
{
mInitTimetables = timetables;
refreshTimetables();
}
private void refreshTimetables()
{
if (mInput != null && mInitTimetables != null)
mInput.setText(OpeningHours.nativeTimetablesToString(mInitTimetables));
}
}

View file

@ -0,0 +1,157 @@
package com.mapswithme.maps.widget.placepage;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.TimePicker;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmDialogFragment;
import com.mapswithme.maps.editor.data.HoursMinutes;
public class HoursMinutesPickerFragment extends BaseMwmDialogFragment
{
private static final String EXTRA_FROM = "HoursMinutesFrom";
private static final String EXTRA_TO = "HoursMinutesTo";
private static final String EXTRA_SELECT_FIRST = "SelectedTab";
private static final String EXTRA_ID = "Id";
public static final int TAB_FROM = 0;
public static final int TAB_TO = 1;
private HoursMinutes mFrom;
private HoursMinutes mTo;
private TimePicker mPicker;
@IntRange(from = 0, to = 1) private int mSelectedTab;
private TabLayout mTabs;
private int mId;
public interface OnPickListener
{
void onHoursMinutesPicked(HoursMinutes from, HoursMinutes to, int id);
}
public static void pick(Context context, FragmentManager manager, @NonNull HoursMinutes from, @NonNull HoursMinutes to,
@IntRange(from = 0, to = 1) int selectedPosition, int id)
{
final Bundle args = new Bundle();
args.putParcelable(EXTRA_FROM, from);
args.putParcelable(EXTRA_TO, to);
args.putInt(EXTRA_SELECT_FIRST, selectedPosition);
args.putInt(EXTRA_ID, id);
final HoursMinutesPickerFragment fragment = (HoursMinutesPickerFragment) Fragment.instantiate(context, HoursMinutesPickerFragment.class.getName(), args);
fragment.show(manager, null);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
readArgs();
final View root = createView();
refreshPicker();
//noinspection ConstantConditions
mTabs.getTabAt(mSelectedTab).select();
return new AlertDialog.Builder(getActivity(), R.style.MwmMain_DialogFragment_TimePicker)
.setView(root)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
saveHoursMinutes(mPicker.getCurrentHour(), mPicker.getCurrentMinute());
if (getParentFragment() instanceof OnPickListener)
((OnPickListener) getParentFragment()).onHoursMinutesPicked(mFrom, mTo, mId);
}
})
.setCancelable(true)
.create();
}
private void readArgs()
{
final Bundle args = getArguments();
mFrom = args.getParcelable(EXTRA_FROM);
mTo = args.getParcelable(EXTRA_TO);
mSelectedTab = args.getInt(EXTRA_SELECT_FIRST);
mId = args.getInt(EXTRA_ID);
}
private View createView()
{
final LayoutInflater inflater = LayoutInflater.from(getActivity());
@SuppressLint("InflateParams")
final View root = inflater.inflate(R.layout.fragment_timetable_picker, null);
mTabs = (TabLayout) root.findViewById(R.id.tabs);
TextView tabView = (TextView) inflater.inflate(R.layout.tab_timepicker, mTabs, false);
// TODO @yunik add translations
tabView.setText("From");
mTabs.addTab(mTabs.newTab().setCustomView(tabView), true);
tabView = (TextView) inflater.inflate(R.layout.tab_timepicker, mTabs, false);
tabView.setText("To");
mTabs.addTab(mTabs.newTab().setCustomView(tabView), true);
mTabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
@Override
public void onTabSelected(TabLayout.Tab tab)
{
mSelectedTab = tab.getPosition();
refreshPicker();
}
@Override
public void onTabUnselected(TabLayout.Tab tab)
{
saveHoursMinutes(mPicker.getCurrentHour(), mPicker.getCurrentMinute());
}
@Override
public void onTabReselected(TabLayout.Tab tab) {}
});
mPicker = (TimePicker) root.findViewById(R.id.picker);
mPicker.setIs24HourView(DateFormat.is24HourFormat(getActivity()));
mPicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener()
{
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
saveHoursMinutes(hourOfDay, minute);
}
});
return root;
}
private void saveHoursMinutes(int hourOfDay, int minute)
{
if (mSelectedTab == TAB_FROM)
mFrom = new HoursMinutes(hourOfDay, minute);
else
mTo = new HoursMinutes(hourOfDay, minute);
}
private void refreshPicker()
{
final HoursMinutes hoursMinutes = mSelectedTab == TAB_FROM ? mFrom : mTo;
mPicker.setCurrentMinute((int) hoursMinutes.minutes);
mPicker.setCurrentHour((int) hoursMinutes.hours);
}
}

View file

@ -0,0 +1,456 @@
package com.mapswithme.maps.widget.placepage;
import android.support.annotation.IdRes;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SwitchCompat;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.mapswithme.maps.R;
import com.mapswithme.maps.editor.OpeningHours;
import com.mapswithme.maps.editor.data.HoursMinutes;
import com.mapswithme.maps.editor.data.Timespan;
import com.mapswithme.maps.editor.data.Timetable;
import com.mapswithme.util.UiUtils;
public class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter.BaseTimetableViewHolder>
implements HoursMinutesPickerFragment.OnPickListener,
TimetableFragment.TimetableProvider
{
private static final int TYPE_TIMETABLE = 0;
private static final int TYPE_ADD_TIMETABLE = 1;
private static final int ID_OPENING = 0;
private static final int ID_CLOSED = 1;
private final Fragment mFragment;
private List<Timetable> mItems = new ArrayList<>();
private Timetable mComplementItem;
private int mPickingPosition;
SimpleTimetableAdapter(Fragment fragment)
{
mFragment = fragment;
mItems = new ArrayList<>(Arrays.asList(OpeningHours.nativeGetDefaultTimetables()));
}
public void setTimetables(Timetable[] tts)
{
mItems = new ArrayList<>(Arrays.asList(tts));
notifyDataSetChanged();
}
@Override
public Timetable[] getTimetables()
{
return mItems.toArray(new Timetable[mItems.size()]);
}
@Override
public BaseTimetableViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return viewType == TYPE_TIMETABLE ? new TimetableViewHolder(inflater.inflate(R.layout.item_timetable, parent, false))
: new AddTimetableViewHolder(inflater.inflate(R.layout.item_timetable_add, parent, false));
}
@Override
public void onBindViewHolder(BaseTimetableViewHolder holder, int position)
{
holder.onBind();
}
@Override
public int getItemCount()
{
return mItems.size() + 1;
}
@Override
public int getItemViewType(int position)
{
return position == getItemCount() - 1 ? TYPE_ADD_TIMETABLE
: TYPE_TIMETABLE;
}
protected void addTimetable()
{
mItems.add(OpeningHours.nativeGetComplementTimetable(mItems.toArray(new Timetable[mItems.size()])));
printItems();
notifyItemInserted(mItems.size() - 1);
refreshComplement();
}
protected void removeTimetable(int position)
{
mItems.remove(position);
printItems();
notifyItemRemoved(position);
refreshComplement();
}
protected void refreshComplement()
{
mComplementItem = OpeningHours.nativeGetComplementTimetable(mItems.toArray(new Timetable[mItems.size()]));
notifyItemChanged(getItemCount() - 1);
}
protected void pickOpeningTime(int position, int tab)
{
final Timetable data = mItems.get(position);
mPickingPosition = position;
HoursMinutesPickerFragment.pick(mFragment.getActivity(), mFragment.getChildFragmentManager(),
data.workingTimespan.start, data.workingTimespan.end,
tab, ID_OPENING);
}
protected void pickClosedHours(int position)
{
final Timetable data = mItems.get(position);
mPickingPosition = position;
HoursMinutesPickerFragment.pick(mFragment.getActivity(), mFragment.getChildFragmentManager(),
data.workingTimespan.start, data.workingTimespan.end,
0, ID_CLOSED);
}
@Override
public void onHoursMinutesPicked(HoursMinutes from, HoursMinutes to, int id)
{
final Timetable item = mItems.get(mPickingPosition);
if (id == ID_OPENING)
mItems.set(mPickingPosition, OpeningHours.nativeSetOpeningTime(item, new Timespan(from, to)));
else
mItems.set(mPickingPosition, OpeningHours.nativeAddClosedSpan(item, new Timespan(from, to)));
notifyItemChanged(mPickingPosition);
}
private void removeClosedHours(int position, int closedPosition)
{
mItems.set(position, OpeningHours.nativeRemoveClosedSpan(mItems.get(position), closedPosition));
notifyItemChanged(position);
}
protected void addWorkingDay(int day, int position)
{
final Timetable tts[] = mItems.toArray(new Timetable[mItems.size()]);
mItems = new ArrayList<>(Arrays.asList(OpeningHours.nativeAddWorkingDay(tts, position, day)));
refreshComplement();
notifyDataSetChanged();
}
protected void removeWorkingDay(int day, int position)
{
final Timetable tts[] = mItems.toArray(new Timetable[mItems.size()]);
mItems = new ArrayList<>(Arrays.asList(OpeningHours.nativeRemoveWorkingDay(tts, position, day)));
refreshComplement();
printItems();
notifyDataSetChanged();
}
// FIXME remove
private void printItems()
{
Log.d("TEST", "Items : \n");
for (Timetable tt : mItems)
Log.d("TEST", tt.toString() + "\n");
}
private void setFullday(int position, boolean fullday)
{
mItems.set(position, OpeningHours.nativeSetIsFullday(mItems.get(position), fullday));
notifyItemChanged(position);
}
public abstract class BaseTimetableViewHolder extends RecyclerView.ViewHolder
{
public BaseTimetableViewHolder(View itemView)
{
super(itemView);
}
abstract void onBind();
}
public class TimetableViewHolder extends BaseTimetableViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener
{
// Limit closed spans to avoid dynamic inflation of views in recycler's children. Yeah, its a hack.
static final int MAX_CLOSED_SPANS = 10;
TextView day1Text;
TextView day2Text;
TextView day3Text;
TextView day4Text;
TextView day5Text;
TextView day6Text;
TextView day7Text;
SparseArray<CheckBox> days = new SparseArray<>(7);
View allday;
SwitchCompat swAllday;
View schedule;
View openClose;
View open;
View close;
TextView tvOpen;
TextView tvClose;
View closedHours[] = new View[MAX_CLOSED_SPANS];
View addClosed;
View deleteTimetable;
public TimetableViewHolder(View itemView)
{
super(itemView);
addDay(R.id.chb__day_1, 1);
addDay(R.id.chb__day_2, 2);
addDay(R.id.chb__day_3, 3);
addDay(R.id.chb__day_4, 4);
addDay(R.id.chb__day_5, 5);
addDay(R.id.chb__day_6, 6);
addDay(R.id.chb__day_7, 7);
fillDaysTexts();
final int[] daysIds = new int[]{R.id.day1, R.id.day2, R.id.day3, R.id.day4, R.id.day5, R.id.day6, R.id.day7};
for (int i = 0; i < 7; i++)
{
final int finalI = i;
itemView.findViewById(daysIds[i]).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
days.get(finalI + 1).toggle();
}
});
}
allday = itemView.findViewById(R.id.allday);
allday.setOnClickListener(this);
swAllday = (SwitchCompat) allday.findViewById(R.id.sw__allday);
schedule = itemView.findViewById(R.id.schedule);
openClose = schedule.findViewById(R.id.time_open_close);
open = openClose.findViewById(R.id.time_open);
open.setOnClickListener(this);
close = openClose.findViewById(R.id.time_close);
close.setOnClickListener(this);
tvOpen = (TextView) open.findViewById(R.id.tv__time_open);
tvClose = (TextView) close.findViewById(R.id.tv__time_close);
addClosed = schedule.findViewById(R.id.tv__add_closed);
addClosed.setOnClickListener(this);
deleteTimetable = itemView.findViewById(R.id.tv__remove_timetable);
deleteTimetable.setOnClickListener(this);
final ViewGroup closedHost = (ViewGroup) itemView.findViewById(R.id.closed_host);
for (int i = 0; i < MAX_CLOSED_SPANS; i++)
{
final View span = LayoutInflater.from(itemView.getContext()).inflate(R.layout.item_timetable_closed_hours, closedHost, false);
closedHost.addView(span, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, UiUtils.dimen(R.dimen.editor_height_closed)));
closedHours[i] = span;
final int finalI = i;
span.findViewById(R.id.iv__remove_closed).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
removeClosedHours(getAdapterPosition(), finalI);
}
});
}
}
@Override
void onBind()
{
final int position = getAdapterPosition();
final Timetable data = mItems.get(position);
UiUtils.showIf(position > 0, deleteTimetable);
tvOpen.setText(formatHoursMinutes(data.workingTimespan.start));
tvClose.setText(formatHoursMinutes(data.workingTimespan.end));
showDays(data.weekdays);
showSchedule(!data.isFullday);
showClosedHours(data.closedTimespans);
}
private String formatHoursMinutes(HoursMinutes hoursMinutes)
{
// TODO @yunik add proper translated strings
return String.format("%02d", Long.valueOf(hoursMinutes.hours))
+ ":"
+ String.format("%02d", Long.valueOf(hoursMinutes.minutes));
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.time_open:
pickOpeningTime(getAdapterPosition(), HoursMinutesPickerFragment.TAB_FROM);
break;
case R.id.time_close:
pickOpeningTime(getAdapterPosition(), HoursMinutesPickerFragment.TAB_TO);
break;
case R.id.tv__remove_timetable:
removeTimetable(getAdapterPosition());
break;
case R.id.tv__add_closed:
pickClosedHours(getAdapterPosition());
break;
case R.id.allday:
swAllday.toggle();
break;
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
switch (buttonView.getId())
{
case R.id.sw__allday:
setFullday(getAdapterPosition(), isChecked);
break;
case R.id.chb__day_1:
switchWorkingDay(1);
break;
case R.id.chb__day_2:
switchWorkingDay(2);
break;
case R.id.chb__day_3:
switchWorkingDay(3);
break;
case R.id.chb__day_4:
switchWorkingDay(4);
break;
case R.id.chb__day_5:
switchWorkingDay(5);
break;
case R.id.chb__day_6:
switchWorkingDay(6);
break;
case R.id.chb__day_7:
switchWorkingDay(7);
break;
}
}
void showDays(int[] weekdays)
{
for (int i = 1; i <= 7; i++)
checkWithoutCallback(days.get(i), false);
for (int checked : weekdays)
checkWithoutCallback(days.get(checked), true);
}
void showSchedule(boolean show)
{
UiUtils.showIf(show, schedule);
checkWithoutCallback(swAllday, !show);
}
private void showClosedHours(Timespan[] closedSpans)
{
int i = 0;
for (Timespan timespan : closedSpans)
{
if (i == MAX_CLOSED_SPANS)
return;
if (timespan == null)
UiUtils.hide(closedHours[i]);
else
{
UiUtils.show(closedHours[i]);
// TODO add localization
((TextView) closedHours[i].findViewById(R.id.tv__closed)).setText(formatHoursMinutes(timespan.start)
+ "-"
+ formatHoursMinutes(timespan.end));
}
i++;
}
while (i < MAX_CLOSED_SPANS)
UiUtils.hide(closedHours[i++]);
}
private void addDay(@IdRes int res, final int dayIndex)
{
days.put(dayIndex, (CheckBox) itemView.findViewById(res));
}
private void switchWorkingDay(int day)
{
final CheckBox checkBox = days.get(day);
if (checkBox.isChecked())
addWorkingDay(day, getAdapterPosition());
else
removeWorkingDay(day, getAdapterPosition());
}
private void fillDaysTexts()
{
day1Text = (TextView) itemView.findViewById(R.id.tv__day_1);
day2Text = (TextView) itemView.findViewById(R.id.tv__day_2);
day3Text = (TextView) itemView.findViewById(R.id.tv__day_3);
day4Text = (TextView) itemView.findViewById(R.id.tv__day_4);
day5Text = (TextView) itemView.findViewById(R.id.tv__day_5);
day6Text = (TextView) itemView.findViewById(R.id.tv__day_6);
day7Text = (TextView) itemView.findViewById(R.id.tv__day_7);
// FIXME @yunik localize texts
day1Text.setText("Su");
day2Text.setText("Mo");
day3Text.setText("Tu");
day4Text.setText("We");
day5Text.setText("Th");
day6Text.setText("Fr");
day7Text.setText("Sa");
}
private void checkWithoutCallback(CompoundButton button, boolean check)
{
button.setOnCheckedChangeListener(null);
button.setChecked(check);
button.setOnCheckedChangeListener(this);
}
}
private class AddTimetableViewHolder extends BaseTimetableViewHolder
{
private TextView add;
public AddTimetableViewHolder(View itemView)
{
super(itemView);
add = (TextView) itemView.findViewById(R.id.btn__add_time);
add.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
addTimetable();
}
});
}
@Override
void onBind()
{
// TODO @yunik add text with complement days
add.setEnabled(mComplementItem != null && mComplementItem.weekdays.length != 0);
}
}
}

View file

@ -0,0 +1,67 @@
package com.mapswithme.maps.widget.placepage;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmRecyclerFragment;
import com.mapswithme.maps.editor.data.HoursMinutes;
import com.mapswithme.maps.editor.data.Timetable;
public class SimpleTimetableFragment extends BaseMwmRecyclerFragment
implements TimetableFragment.TimetableProvider,
HoursMinutesPickerFragment.OnPickListener
{
private SimpleTimetableAdapter mAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
protected RecyclerView.Adapter createAdapter()
{
mAdapter = new SimpleTimetableAdapter(this);
return mAdapter;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_timetable_simple, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
@Override
public Timetable[] getTimetables()
{
return mAdapter.getTimetables();
}
@Override
public void onHoursMinutesPicked(HoursMinutes from, HoursMinutes to, int id)
{
mAdapter.onHoursMinutesPicked(from, to, id);
}
public void setTimetables(Timetable[] tts)
{
if (tts == null)
return;
createAdapter();
mAdapter.setTimetables(tts);
}
}

View file

@ -0,0 +1,153 @@
package com.mapswithme.maps.widget.placepage;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmToolbarFragment;
import com.mapswithme.maps.base.OnBackPressListener;
import com.mapswithme.maps.editor.OpeningHours;
import com.mapswithme.maps.editor.data.Timetable;
import com.mapswithme.util.Utils;
public class TimetableFragment extends BaseMwmToolbarFragment
implements View.OnClickListener,
OnBackPressListener
{
interface TimetableProvider
{
Timetable[] getTimetables();
}
public static final String EXTRA_TIME = "Time";
private boolean mIsAdvancedMode;
private TextView mSwitchMode;
private SimpleTimetableFragment mSimpleModeFragment;
private AdvancedTimetableFragment mAdvancedModeFragment;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_timetable, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
initViews(view);
simpleMode();
final Bundle args = getArguments();
if (args != null && args.containsKey(EXTRA_TIME))
mSimpleModeFragment.setTimetables(OpeningHours.nativeTimetablesFromString(args.getString(EXTRA_TIME)));
}
private void initViews(View root)
{
mToolbarController.setTitle(R.string.editor_time_title);
mToolbarController.findViewById(R.id.iv__submit).setOnClickListener(this);
mSwitchMode = (TextView) root.findViewById(R.id.tv__mode_switch);
mSwitchMode.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.tv__mode_switch:
switchMode();
break;
case R.id.iv__submit:
saveTimetable();
}
}
@Override
public boolean onBackPressed()
{
return false;
}
private void switchMode()
{
if (mIsAdvancedMode)
simpleMode();
else
advancedMode();
}
private void simpleMode()
{
mIsAdvancedMode = false;
mSwitchMode.setText(R.string.editor_time_advanced);
final Timetable[] filledTimetables = getFilledTimetables(mAdvancedModeFragment, mAdvancedModeFragment);
mSimpleModeFragment = (SimpleTimetableFragment) attachFragment(mSimpleModeFragment, SimpleTimetableFragment.class.getName());
mSimpleModeFragment.setTimetables(filledTimetables);
}
private void advancedMode()
{
mIsAdvancedMode = true;
mSwitchMode.setText(R.string.editor_time_simple);
final Timetable[] filledTimetables = getFilledTimetables(mSimpleModeFragment, mSimpleModeFragment);
mAdvancedModeFragment = (AdvancedTimetableFragment) attachFragment(mAdvancedModeFragment, AdvancedTimetableFragment.class.getName());
mAdvancedModeFragment.setTimetables(filledTimetables);
}
private boolean hasFilledTimetables(Fragment fragment)
{
return fragment != null && fragment.isAdded();
}
private Timetable[] getFilledTimetables(Fragment fragment, TimetableProvider provider)
{
if (!hasFilledTimetables(fragment))
return null;
final Timetable[] timetables = provider.getTimetables();
if (timetables == null)
{
// FIXME @yunikkk add correct text
new AlertDialog.Builder(getActivity())
.setMessage("Invalid formatted timetable!")
.create();
return null;
}
return timetables;
}
private Fragment attachFragment(Fragment current, String className)
{
Fragment fragment = current == null ? Fragment.instantiate(getActivity(), className)
: current;
getChildFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
return fragment;
}
private void saveTimetable()
{
if (mIsAdvancedMode)
mAdvancedModeFragment.getTimetables();
else
mSimpleModeFragment.getTimetables();
final Timetable[] timetables = mIsAdvancedMode ? mAdvancedModeFragment.getTimetables() : mSimpleModeFragment.getTimetables();
// TODO @yunikkk or @deathbaba save timetables to the core
Utils.navigateToParent(getActivity());
}
}