[android] Implemented checkin/chekout selection in toolbasr via material date picker on search screen and map

This commit is contained in:
alexzatsepin 2020-08-04 20:55:23 +03:00 committed by Arsentiy Milchakov
parent ea7e1f5374
commit e860d11ebd
9 changed files with 163 additions and 61 deletions

View file

@ -10,7 +10,7 @@
android:paddingTop="@dimen/margin_quarter_plus"
android:paddingEnd="@dimen/margin_base_plus_quarter"
android:paddingBottom="@dimen/margin_half_plus"
android:visibility="visible">
android:visibility="gone">
<com.google.android.material.chip.ChipGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -4,11 +4,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
style="@style/MwmWidget.ToolbarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/MwmWidget.ToolbarTheme"
app:contentInsetLeft="@dimen/dp_0"
app:contentInsetStart="@dimen/dp_0"
android:layout_width="match_parent"
android:layout_height="wrap_content">
app:contentInsetStart="@dimen/dp_0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -4,11 +4,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
style="@style/MwmWidget.ToolbarStyle.NoElevation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/MwmWidget.ToolbarTheme"
app:contentInsetLeft="@dimen/dp_0"
app:contentInsetStart="@dimen/dp_0"
android:layout_width="match_parent"
android:layout_height="wrap_content">
app:contentInsetStart="@dimen/dp_0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -98,5 +98,5 @@
<string name="auto_enum_value" translatable="false">AUTO</string>
<string name="placepage_toolbar_behavior" translatable="false">com.mapswithme.maps.widget.placepage.ToolbarBehavior</string>
<string name="placepage_behavior" translatable="false">com.trafi.anchorbottomsheetbehavior.AnchorBottomSheetBehavior</string>
<string name="booking_filter_date_range" translatable="false">%s - %s</string>
</resources>

View file

@ -32,7 +32,6 @@ import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.Framework.PlacePageActivationListener;
import com.mapswithme.maps.base.CustomNavigateUpListener;
import com.mapswithme.maps.ads.LikesManager;
import com.mapswithme.maps.api.ParsedMwmRequest;
import com.mapswithme.maps.auth.PassportAuthDialogFragment;
@ -40,6 +39,7 @@ import com.mapswithme.maps.background.AppBackgroundTracker;
import com.mapswithme.maps.background.NotificationCandidate;
import com.mapswithme.maps.background.Notifier;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.maps.base.CustomNavigateUpListener;
import com.mapswithme.maps.base.NoConnectionListener;
import com.mapswithme.maps.base.OnBackPressListener;
import com.mapswithme.maps.bookmarks.AuthBundleFactory;
@ -434,9 +434,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (mFilterController == null || data == null)
return;
// TODO: data.getParcelableExtra(FilterActivity.EXTRA_FILTER_PARAMS) is obsolete. Get filter
// filter params from toolbar.
BookingFilterParams params = null;
BookingFilterParams params = data.getParcelableExtra(FilterActivity.EXTRA_FILTER_PARAMS);
HotelsFilter filter = data.getParcelableExtra(FilterActivity.EXTRA_FILTER);
mFilterController.setFilterAndParams(filter, params);
@ -558,14 +556,15 @@ public class MwmActivity extends BaseMwmFragmentActivity
this);
mMainMenuController.initialize(findViewById(R.id.coordinator));
mSearchController = new FloatingSearchToolbarController(this, this);
mSearchController.getToolbar().getViewTreeObserver().addOnGlobalLayoutListener(new ToolbarLayoutChangeListener());
mSearchController.setVisibilityListener(this);
boolean isLaunchByDeepLink = getIntent().getBooleanExtra(EXTRA_LAUNCH_BY_DEEP_LINK, false);
initViews(isLaunchByDeepLink);
Statistics.INSTANCE.trackConnectionState();
mSearchController = new FloatingSearchToolbarController(this, this);
mSearchController.getToolbar().getViewTreeObserver().addOnGlobalLayoutListener(new ToolbarLayoutChangeListener());
mSearchController.setVisibilityListener(this);
SearchEngine.INSTANCE.addListener(this);
SharingHelper.INSTANCE.initialize(null);
@ -677,7 +676,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
runSearch();
}
}, R.string.search_in_table);
@Override
public void onFilterParamsChanged()
{
runSearch();
}
}, R.string.search_in_table, mSearchController);
}
}
@ -1154,12 +1159,10 @@ public class MwmActivity extends BaseMwmFragmentActivity
setupSearchQuery(data);
// TODO: data.getParcelableExtra(FilterActivity.EXTRA_FILTER_PARAMS) is obsolete. Get filter
// filter params from toolbar.
BookingFilterParams params = null;
BookingFilterParams params = data.getParcelableExtra(FilterActivity.EXTRA_FILTER_PARAMS);
mFilterController.setFilterAndParams(data.getParcelableExtra(FilterActivity.EXTRA_FILTER),
params);
mFilterController.updateFilterButtonVisibility(params != null);
mFilterController.updateFilterButtonsVisibility(mFilterController.isSatisfiedForSearch());
runSearch();
}
@ -1181,7 +1184,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
runSearch();
mSearchController.refreshToolbar();
mFilterController.updateFilterButtonVisibility(true);
mFilterController.updateFilterButtonsVisibility(true);
mFilterController.show(true, true);
}
@ -1366,7 +1369,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
BookingFilterParams params = intent.getParcelableExtra(FilterActivity.EXTRA_FILTER_PARAMS);
if (mFilterController != null && (filter != null || params != null))
{
mFilterController.updateFilterButtonVisibility(true);
mFilterController.updateFilterButtonsVisibility(true);
mFilterController.show(!TextUtils.isEmpty(SearchEngine.INSTANCE.getQuery()), true);
mFilterController.setFilterAndParams(filter, params);
return true;
@ -2156,7 +2159,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void onResultsUpdate(SearchResult[] results, long timestamp, boolean isHotel)
{
if (mFilterController != null)
mFilterController.updateFilterButtonVisibility(isHotel);
mFilterController.updateFilterButtonsVisibility(isHotel);
}
@Override

View file

@ -121,14 +121,9 @@ public class BookingFilterParams implements Parcelable
return mRooms;
}
public static class Factory
public static BookingFilterParams createParams(long checkIn, long checkOut)
{
@Nullable
public BookingFilterParams createParams(long checkIn, long checkOut, @NonNull Room... rooms)
{
return ConnectionState.isConnected() ? new BookingFilterParams(checkIn, checkOut, rooms)
: null;
}
return ConnectionState.isConnected() ? new BookingFilterParams(checkIn, checkOut, Room.DEFAULT)
: null;
}
}

View file

@ -1,18 +1,19 @@
package com.mapswithme.maps.search;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import com.mapswithme.maps.R;
import com.mapswithme.maps.widget.SearchToolbarController;
import com.mapswithme.util.UiUtils;
public class SearchFilterController
public class SearchFilterController implements SearchToolbarController.FilterParamsChangedListener
{
private static final String STATE_HOTEL_FILTER = "state_hotel_filter";
private static final String STATE_FILTER_PARAMS = "state_filter_params";
@ -36,6 +37,8 @@ public class SearchFilterController
@Nullable
private BookingFilterParams mBookingFilterParams;
private boolean mHotelMode;
@NonNull
private final SearchToolbarController mToolbarController;
@NonNull
private final View.OnClickListener mClearListener = new View.OnClickListener()
@ -44,6 +47,7 @@ public class SearchFilterController
public void onClick(View v)
{
setFilterAndParams(null, null);
mToolbarController.setFilterParams(null);
if (mFilterListener != null)
mFilterListener.onFilterClear();
}
@ -52,23 +56,41 @@ public class SearchFilterController
@Nullable
private final FilterListener mFilterListener;
@Override
public void onBookingParamsChanged()
{
mBookingFilterParams = mToolbarController.getFilterParams();
if (mFilterListener != null)
mFilterListener.onFilterParamsChanged();
}
public boolean isSatisfiedForSearch()
{
return mFilter != null || mBookingFilterParams != null;
}
interface FilterListener
{
void onShowOnMapClick();
void onFilterClick();
void onFilterClear();
void onFilterParamsChanged();
}
SearchFilterController(@NonNull View frame, @Nullable FilterListener listener)
SearchFilterController(@NonNull View frame, @Nullable FilterListener listener,
@NonNull SearchToolbarController toolbarController)
{
this(frame, listener, R.string.search_show_on_map);
this(frame, listener, R.string.search_show_on_map, toolbarController);
}
public SearchFilterController(@NonNull View frame,
@Nullable FilterListener listener, @StringRes int populateButtonText)
public SearchFilterController(@NonNull View frame, @Nullable FilterListener listener,
@StringRes int populateButtonText,
@NonNull SearchToolbarController toolbarController)
{
mFrame = frame;
mFilterListener = listener;
mToolbarController = toolbarController;
mToolbarController.addBookingParamsChangedListener(this);
mShowOnMap = mFrame.findViewById(R.id.show_on_map);
mShowOnMap.setText(populateButtonText);
mFilterButton = mFrame.findViewById(R.id.filter_button);
@ -95,10 +117,11 @@ public class SearchFilterController
UiUtils.showIf(show, mDivider);
}
public void updateFilterButtonVisibility(boolean isHotel)
public void updateFilterButtonsVisibility(boolean isHotel)
{
mHotelMode = isHotel;
UiUtils.showIf(isHotel, mFilterButton);
mToolbarController.showFilterControls(isHotel);
}
private void initListeners()
@ -124,8 +147,9 @@ public class SearchFilterController
public void setFilterAndParams(@Nullable HotelsFilter filter, @Nullable BookingFilterParams params)
{
mFilter = filter;
mBookingFilterParams = params;
if (mFilter != null || mBookingFilterParams != null)
if (params != null)
mToolbarController.setFilterParams(params);
if (mFilter != null)
{
mFilterIcon.setOnClickListener(mClearListener);
mFilterIcon.setImageResource(R.drawable.ic_cancel);
@ -150,7 +174,8 @@ public class SearchFilterController
public void resetFilter()
{
setFilterAndParams(null, null);
updateFilterButtonVisibility(false);
mToolbarController.setFilterParams(null);
updateFilterButtonsVisibility(false);
}
@Nullable
@ -170,7 +195,7 @@ public class SearchFilterController
public void onRestoreState(@NonNull Bundle state)
{
setFilterAndParams(state.getParcelable(STATE_HOTEL_FILTER), state.getParcelable(STATE_FILTER_PARAMS));
updateFilterButtonVisibility(state.getBoolean(STATE_HOTEL_FILTER_VISIBILITY, false));
updateFilterButtonsVisibility(state.getBoolean(STATE_HOTEL_FILTER_VISIBILITY, false));
}
public static class DefaultFilterListener implements FilterListener
@ -190,5 +215,11 @@ public class SearchFilterController
{
}
@Override
public void onFilterParamsChanged()
{
}
}
}

View file

@ -355,12 +355,18 @@ public class SearchFragment extends BaseMwmFragment
{
runSearch();
}
});
@Override
public void onFilterParamsChanged()
{
runSearch();
}
}, mToolbarController);
if (savedInstanceState != null)
mFilterController.onRestoreState(savedInstanceState);
if (mInitialHotelsFilter != null || mInitialFilterParams != null)
mFilterController.setFilterAndParams(mInitialHotelsFilter, mInitialFilterParams);
mFilterController.updateFilterButtonVisibility(mInitialFilterParams != null);
mFilterController.updateFilterButtonsVisibility(mFilterController.isSatisfiedForSearch());
mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
{
@ -665,9 +671,12 @@ public class SearchFragment extends BaseMwmFragment
{
if (mFilterController != null)
{
mFilterController.updateFilterButtonVisibility(isHotel);
mFilterController.updateFilterButtonsVisibility(isHotel);
if (!isHotel)
{
mFilterController.setFilterAndParams(null, null);
mToolbarController.setFilterParams(null);
}
}
}

View file

@ -3,34 +3,39 @@ package com.mapswithme.maps.widget;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.util.Pair;
import com.google.android.material.chip.Chip;
import com.google.android.material.datepicker.CalendarConstraints;
import com.google.android.material.datepicker.MaterialDatePicker;
import com.google.android.material.datepicker.MaterialPickerOnPositiveButtonClickListener;
import com.mapswithme.maps.R;
import com.mapswithme.maps.search.BookingFilterParams;
import com.mapswithme.util.InputUtils;
import com.mapswithme.util.StringUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.statistics.AlohaHelper;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class SearchToolbarController extends ToolbarController
implements View.OnClickListener
{
private static final int REQUEST_VOICE_RECOGNITION = 0xCA11;
public static final String DAY_OF_MONTH_PATTERN = "MMM d";
@NonNull
private final View mSearchContainer;
@ -45,7 +50,7 @@ public class SearchToolbarController extends ToolbarController
@Nullable
private final View mFilterContainer;
@Nullable
private Chip mChooseDates;
private Chip mChooseDatesChip;
@Nullable
private Chip mRooms;
private final boolean mVoiceInputSupported = InputUtils.isVoiceInputSupported(getActivity());
@ -59,21 +64,31 @@ public class SearchToolbarController extends ToolbarController
SearchToolbarController.this.onTextChanged(s.toString());
}
};
@Nullable
private Pair<Long, Long> mChosenDates;
@NonNull
private final View.OnClickListener mChooseDatesClickListener = v -> {
MaterialDatePicker.Builder<Pair<Long, Long>> builder
= MaterialDatePicker.Builder.dateRangePicker();
if (mChosenDates != null)
builder.setSelection(mChosenDates);
final MaterialDatePicker<?> picker = builder.build();
picker.addOnPositiveButtonClickListener(new MaterialPickerOnPositiveButtonClickListener<Object>()
{
@Override
public void onPositiveButtonClick(Object selection)
{
mChooseDates.setText(picker.getHeaderText());
//noinspection unchecked
mChosenDates = (Pair<Long, Long>) selection;
mChooseDatesChip.setText(picker.getHeaderText());
for (FilterParamsChangedListener listener : mFilterParamsChangedListeners)
listener.onBookingParamsChanged();
}
});
picker.show(((AppCompatActivity) getActivity()).getSupportFragmentManager(), picker.toString());
};
@NonNull
private List<FilterParamsChangedListener> mFilterParamsChangedListeners = new ArrayList<>();
public interface Container
{
@ -83,7 +98,6 @@ public class SearchToolbarController extends ToolbarController
public SearchToolbarController(View root, Activity activity)
{
super(root, activity);
mSearchContainer = getToolbar().findViewById(R.id.search_container);
mQuery = mSearchContainer.findViewById(R.id.query);
mQuery.setOnClickListener(this);
@ -104,20 +118,43 @@ public class SearchToolbarController extends ToolbarController
mVoiceInput.setOnClickListener(this);
mClear = mSearchContainer.findViewById(R.id.clear);
mClear.setOnClickListener(this);
mFilterContainer = getToolbar().findViewById(R.id.filter_container);
if (mFilterContainer != null)
{
mChooseDates = mFilterContainer.findViewById(R.id.choose_dates);
mChooseDatesChip = mFilterContainer.findViewById(R.id.choose_dates);
mRooms = mFilterContainer.findViewById(R.id.rooms);
mChooseDates.setOnClickListener(mChooseDatesClickListener);
mChooseDates.setOnCloseIconClickListener(mChooseDatesClickListener);
//noinspection ConstantConditions
mChooseDatesChip.setOnClickListener(mChooseDatesClickListener);
mChooseDatesChip.setOnCloseIconClickListener(mChooseDatesClickListener);
}
showProgress(false);
updateButtons(true);
}
public void setFilterParams(@Nullable BookingFilterParams params)
{
if (mChooseDatesChip == null)
return;
if (params == null)
{
mChooseDatesChip.setText(R.string.date_picker_сhoose_dates_cta);
mChosenDates = null;
return;
}
mChosenDates = new Pair<>(params.getCheckinMillisec(), params.getCheckoutMillisec());
SimpleDateFormat dateFormater = new SimpleDateFormat(DAY_OF_MONTH_PATTERN,
Locale.getDefault());
@SuppressWarnings("ConstantConditions")
String start = dateFormater.format(new Date(mChosenDates.first));
@SuppressWarnings("ConstantConditions")
String end = dateFormater.format(new Date(mChosenDates.second));
mChooseDatesChip.setText(getActivity().getString(R.string.booking_filter_date_range,
start, end));
}
private void updateButtons(boolean queryEmpty)
{
UiUtils.showIf(supportsVoiceSearch() && queryEmpty && mVoiceInputSupported, mVoiceInput);
@ -237,6 +274,9 @@ public class SearchToolbarController extends ToolbarController
public void showFilterControls(boolean show)
{
if (mFilterContainer == null)
return;
UiUtils.showIf(show, mFilterContainer);
}
@ -254,4 +294,28 @@ public class SearchToolbarController extends ToolbarController
{
mQuery.setHint(hint);
}
public void addBookingParamsChangedListener(@NonNull FilterParamsChangedListener listener)
{
mFilterParamsChangedListeners.add(listener);
}
public void removeBookingParamsChangedListener(@NonNull FilterParamsChangedListener listener)
{
mFilterParamsChangedListeners.remove(listener);
}
@Nullable
public BookingFilterParams getFilterParams()
{
if (mChosenDates == null)
return null;
return BookingFilterParams.createParams(mChosenDates.first, mChosenDates.second);
}
public interface FilterParamsChangedListener
{
void onBookingParamsChanged();
}
}