[android] Added hotels filter to the map activity.

This commit is contained in:
Roman Romanov 2016-12-26 15:06:36 +04:00
parent 2374970318
commit 04eac1d610
12 changed files with 335 additions and 43 deletions

View file

@ -73,4 +73,16 @@
placePage:animationType="left"
placePage:docked="true"
tools:ignore="UnknownIdInLayout"/>
<include
layout="@layout/search_filter_panel"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_alignParentBottom="true"/>
<com.mapswithme.maps.search.HotelsFilterView
android:id="@+id/hotels_filter"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:visibility="gone"/>
</RelativeLayout>

View file

@ -53,6 +53,12 @@
android:visibility="gone"
tools:visibility="visible"/>
<include
layout="@layout/search_filter_panel"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_gravity="bottom"/>
<com.mapswithme.maps.widget.placepage.PlacePageView
android:id="@+id/info_box"
style="@style/MwmWidget.Floating"
@ -86,4 +92,10 @@
android:elevation="@dimen/panel_elevation"
android:visibility="gone"
tools:visibility="visible"/>
<com.mapswithme.maps.search.HotelsFilterView
android:id="@+id/hotels_filter"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:visibility="gone"/>
</RelativeLayout>

View file

@ -66,4 +66,16 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
placePage:animationType="bottom"/>
<include
layout="@layout/search_filter_panel"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_alignParentBottom="true"/>
<com.mapswithme.maps.search.HotelsFilterView
android:id="@+id/hotels_filter"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:visibility="gone"/>
</RelativeLayout>

View file

@ -7,10 +7,10 @@
android:layout_height="@dimen/height_block_base"
android:padding="@dimen/margin_half"
android:background="?cardBackground"
android:clipToPadding="false"
android:visibility="gone"
tools:visibility="visible"
tools:showIn="@layout/fragment_search"
android:clipToPadding="false">
tools:showIn="@layout/fragment_search">
<TextView
android:id="@+id/show_on_map"
style="@style/MwmTextAppearance.Button"

View file

@ -17,6 +17,7 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
@ -60,8 +61,11 @@ import com.mapswithme.maps.routing.RoutingPlanController;
import com.mapswithme.maps.routing.RoutingPlanFragment;
import com.mapswithme.maps.routing.RoutingPlanInplaceController;
import com.mapswithme.maps.search.FloatingSearchToolbarController;
import com.mapswithme.maps.search.HotelsFilter;
import com.mapswithme.maps.search.HotelsFilterView;
import com.mapswithme.maps.search.SearchActivity;
import com.mapswithme.maps.search.SearchEngine;
import com.mapswithme.maps.search.SearchFilterPanelController;
import com.mapswithme.maps.search.SearchFragment;
import com.mapswithme.maps.settings.SettingsActivity;
import com.mapswithme.maps.settings.StoragePathManager;
@ -94,6 +98,8 @@ import com.mapswithme.util.statistics.Statistics;
import java.io.Serializable;
import java.util.Stack;
import static com.mapswithme.maps.search.SearchActivity.EXTRA_HOTELS_FILTER;
public class MwmActivity extends BaseMwmFragmentActivity
implements MapObjectListener,
View.OnTouchListener,
@ -152,6 +158,11 @@ public class MwmActivity extends BaseMwmFragmentActivity
private ViewGroup mRootView;
@Nullable
private SearchFilterPanelController mFilterPanel;
@Nullable
private HotelsFilterView mHotelsFilter;
private boolean mIsFragmentContainer;
private boolean mIsFullscreen;
private boolean mIsFullscreenAnimating;
@ -341,10 +352,12 @@ public class MwmActivity extends BaseMwmFragmentActivity
final Bundle args = new Bundle();
args.putString(SearchActivity.EXTRA_QUERY, query);
if (mFilterPanel != null)
args.putParcelable(EXTRA_HOTELS_FILTER, mFilterPanel.getFilter());
replaceFragment(SearchFragment.class, args, null);
}
else
SearchActivity.start(this, query);
SearchActivity.start(this, query, mFilterPanel != null ? mFilterPanel.getFilter() : null);
}
public void showEditor()
@ -464,6 +477,72 @@ public class MwmActivity extends BaseMwmFragmentActivity
initMainMenu();
initOnmapDownloader();
initPositionChooser();
initFilterPanel();
}
private void initFilterPanel()
{
mHotelsFilter = (HotelsFilterView) findViewById(R.id.hotels_filter);
if (mHotelsFilter != null)
{
mHotelsFilter.setListener(new HotelsFilterView.HotelsFilterListener()
{
@Override
public void onCancel()
{
}
@Override
public void onDone(@Nullable HotelsFilter filter)
{
if (mFilterPanel != null)
mFilterPanel.setFilter(filter);
runSearch();
}
});
}
View frame = findViewById(R.id.filter_frame);
if (frame != null)
{
mFilterPanel = new SearchFilterPanelController(
frame, new SearchFilterPanelController.FilterPanelListener()
{
@Override
public void onViewClick()
{
showSearch(mSearchController.getQuery());
}
@Override
public void onFilterClick()
{
if (mFilterPanel == null)
return;
if (mHotelsFilter != null)
mHotelsFilter.open(mFilterPanel.getFilter());
}
@Override
public void onFilterClear()
{
if (mFilterPanel == null)
return;
mFilterPanel.setFilter(null);
runSearch();
}
}, R.string.search_in_table);
}
}
private void runSearch()
{
SearchEngine.searchInteractive(mSearchController.getQuery(), System.nanoTime(),
false /* isMapAndTable */,
mFilterPanel != null ? mFilterPanel.getFilter() : null);
SearchEngine.showAllResults(mSearchController.getQuery());
}
private void initPositionChooser()
@ -825,6 +904,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
addTask(intent);
else if (intent.hasExtra(EXTRA_UPDATE_COUNTRIES))
showDownloader(true);
HotelsFilter filter = intent.getParcelableExtra(EXTRA_HOTELS_FILTER);
if (mFilterPanel != null)
{
mFilterPanel.show(filter != null || !TextUtils.isEmpty(SearchEngine.getQuery()), true);
mFilterPanel.setFilter(filter);
}
}
private void addTask(Intent intent)
@ -961,6 +1047,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public void onBackPressed()
{
if (mHotelsFilter != null && mHotelsFilter.close())
return;
if (getCurrentMenu().close(true))
{
mFadeView.fadeOut();
@ -1529,8 +1618,13 @@ public class MwmActivity extends BaseMwmFragmentActivity
return;
int toolbarHeight = mSearchController.getToolbar().getHeight();
adjustCompassAndTraffic(visible ? toolbarHeight: UiUtils.getStatusBarHeight(this));
adjustCompassAndTraffic(visible ? toolbarHeight : UiUtils.getStatusBarHeight(this));
setNavButtonsTopLimit(visible ? toolbarHeight : 0);
if (mFilterPanel != null)
{
mFilterPanel.show(visible && !TextUtils.isEmpty(SearchEngine.getQuery()), true);
mFilterPanel.updateFilterButtonVisibility(SearchEngine.getQuery());
}
}
@Override

View file

@ -3,9 +3,8 @@ package com.mapswithme.maps.base;
import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StyleRes;
@ -16,6 +15,7 @@ import android.view.MenuItem;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.util.Config;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
@ -77,13 +77,17 @@ public class BaseMwmFragmentActivity extends AppCompatActivity
attachDefaultFragment();
}
@AttrRes
@ColorRes
protected int getStatusBarColor()
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
return R.attr.colorPrimaryDark;
String theme = Config.getCurrentUiTheme();
if (ThemeUtils.isDefaultTheme(theme))
return R.color.bg_statusbar;
return android.R.attr.colorPrimaryDark;
if (ThemeUtils.isNightTheme(theme))
return R.color.bg_statusbar_night;
throw new IllegalArgumentException("Attempt to apply unsupported theme: " + theme);
}
protected boolean useColorStatusBar()

View file

@ -1,8 +1,12 @@
package com.mapswithme.maps.search;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
public class HotelsFilter
import static com.mapswithme.maps.search.HotelsFilter.Op.FIELD_RATING;
public class HotelsFilter implements Parcelable
{
// *NOTE* keep this in sync with JNI counterpart.
public final static int TYPE_AND = 0;
@ -29,6 +33,21 @@ public class HotelsFilter
mLhs = lhs;
mRhs = rhs;
}
public And(Parcel source)
{
super(TYPE_AND);
mLhs = source.readParcelable(HotelsFilter.class.getClassLoader());
mRhs = source.readParcelable(HotelsFilter.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeParcelable(mLhs, flags);
dest.writeParcelable(mRhs, flags);
}
}
public static class Or extends HotelsFilter
@ -44,6 +63,21 @@ public class HotelsFilter
mLhs = lhs;
mRhs = rhs;
}
public Or(Parcel source)
{
super(TYPE_OR);
mLhs = source.readParcelable(HotelsFilter.class.getClassLoader());
mRhs = source.readParcelable(HotelsFilter.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeParcelable(mLhs, flags);
dest.writeParcelable(mRhs, flags);
}
}
public static class Op extends HotelsFilter
@ -68,6 +102,14 @@ public class HotelsFilter
mField = field;
mOp = op;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeInt(mField);
dest.writeInt(mOp);
}
}
public static class RatingFilter extends Op
@ -79,6 +121,19 @@ public class HotelsFilter
super(FIELD_RATING, op);
mValue = value;
}
public RatingFilter(Parcel source)
{
super(FIELD_RATING, source.readInt());
mValue = source.readFloat();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeFloat(mValue);
}
}
public static class PriceRateFilter extends Op
@ -90,5 +145,66 @@ public class HotelsFilter
super(FIELD_PRICE_RATE, op);
mValue = value;
}
public PriceRateFilter(Parcel source)
{
super(FIELD_PRICE_RATE, source.readInt());
mValue = source.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeInt(mValue);
}
}
protected HotelsFilter(Parcel in)
{
mType = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(mType);
}
@Override
public int describeContents()
{
return 0;
}
private static HotelsFilter readFromParcel(Parcel source)
{
int type = source.readInt();
if (type == TYPE_AND)
return new And(source);
if (type == TYPE_OR)
return new Or(source);
int field = source.readInt();
if (field == FIELD_RATING)
return new RatingFilter(source);
return new PriceRateFilter(source);
}
public static final Creator<HotelsFilter> CREATOR = new Creator<HotelsFilter>()
{
@Override
public HotelsFilter createFromParcel(Parcel in)
{
return readFromParcel(in);
}
@Override
public HotelsFilter[] newArray(int size)
{
return new HotelsFilter[size];
}
};
}

View file

@ -60,7 +60,7 @@ public class HotelsFilterView extends FrameLayout
protected void onFinishInflate()
{
mFrame = findViewById(R.id.frame);
mFrame.setTranslationY(mFrame.getHeight());
mFrame.setTranslationY(mFrame.getResources().getDisplayMetrics().heightPixels);
mFade = findViewById(R.id.fade);
mRating = (RatingFilterView) findViewById(R.id.rating);
mPrice = (PriceFilterView) findViewById(R.id.price);

View file

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StyleRes;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
@ -17,11 +18,14 @@ import com.mapswithme.util.ThemeUtils;
public class SearchActivity extends BaseMwmFragmentActivity implements CustomNavigateUpListener
{
public static final String EXTRA_QUERY = "search_query";
public static final String EXTRA_HOTELS_FILTER = "hotels_filter";
public static void start(@NonNull Activity activity, String query)
public static void start(@NonNull Activity activity, @Nullable String query,
@Nullable HotelsFilter filter)
{
final Intent i = new Intent(activity, SearchActivity.class);
i.putExtra(EXTRA_QUERY, query);
i.putExtra(EXTRA_HOTELS_FILTER, filter);
activity.startActivity(i);
activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
@ -57,6 +61,19 @@ public class SearchActivity extends BaseMwmFragmentActivity implements CustomNav
final FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() == 0)
{
SearchFragment fragment =
(SearchFragment) manager.findFragmentByTag(SearchFragment.class.getName());
if (fragment != null)
{
HotelsFilter filter = fragment.getHotelsFilter();
if (filter != null)
{
Intent intent = NavUtils.getParentActivityIntent(this);
intent.putExtra(EXTRA_HOTELS_FILTER, filter);
NavUtils.navigateUpTo(this, intent);
return;
}
}
NavUtils.navigateUpFromSameTask(this);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
return;

View file

@ -4,7 +4,9 @@ import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@ -17,7 +19,7 @@ public class SearchFilterPanelController
@NonNull
private final View mFrame;
@NonNull
private final View mShowOnMap;
private final TextView mShowOnMap;
@NonNull
private final View mFilterButton;
@NonNull
@ -31,6 +33,8 @@ public class SearchFilterPanelController
private HotelsFilter mFilter;
private final float mElevation;
@NonNull
private final String mCategory;
private View.OnClickListener mClearListener = new View.OnClickListener()
{
@ -44,7 +48,7 @@ public class SearchFilterPanelController
public interface FilterPanelListener
{
void onShowOnMap();
void onViewClick();
void onFilterClick();
void onFilterClear();
}
@ -54,10 +58,18 @@ public class SearchFilterPanelController
public SearchFilterPanelController(@NonNull View frame,
@Nullable FilterPanelListener listener)
{
this(frame, listener, R.string.search_show_on_map);
}
public SearchFilterPanelController(@NonNull View frame,
@Nullable FilterPanelListener listener,
@StringRes int populateButtonText)
{
mFrame = frame;
mFilterPanelListener = listener;
mShowOnMap = mFrame.findViewById(R.id.show_on_map);
mShowOnMap = (TextView) mFrame.findViewById(R.id.show_on_map);
mShowOnMap.setText(populateButtonText);
mFilterButton = mFrame.findViewById(R.id.filter_button);
mFilterIcon = (ImageView) mFilterButton.findViewById(R.id.filter_icon);
mFilterText = (TextView) mFilterButton.findViewById(R.id.filter_text);
@ -65,6 +77,7 @@ public class SearchFilterPanelController
Resources res = mFrame.getResources();
mElevation = res.getDimension(R.dimen.margin_quarter);
mCategory = res.getString(R.string.hotel).toLowerCase();
initListeners();
}
@ -85,9 +98,13 @@ public class SearchFilterPanelController
UiUtils.showIf(show, mDivider);
}
void showFilterButton(boolean show)
public boolean updateFilterButtonVisibility(@Nullable String category)
{
boolean show = !TextUtils.isEmpty(category)
&& category.trim().toLowerCase().equals(mCategory);
UiUtils.showIf(show, mFilterButton);
return show;
}
private void initListeners()
@ -98,7 +115,7 @@ public class SearchFilterPanelController
public void onClick(View v)
{
if (mFilterPanelListener != null)
mFilterPanelListener.onShowOnMap();
mFilterPanelListener.onViewClick();
}
});
mFilterButton.setOnClickListener(new View.OnClickListener()

View file

@ -160,6 +160,7 @@ public class SearchFragment extends BaseMwmFragment
private final LastPosition mLastPosition = new LastPosition();
private boolean mSearchRunning;
private String mInitialQuery;
private @Nullable HotelsFilter mInitialHotelsFilter;
private boolean mFromRoutePlan;
private final LocationListener mLocationListener = new LocationListener.Simple()
@ -192,6 +193,15 @@ public class SearchFragment extends BaseMwmFragment
return (MapManager.nativeGetDownloadedCount() == 0 && !MapManager.nativeIsDownloading());
}
@Nullable
public HotelsFilter getHotelsFilter()
{
if (mFilterPanel == null)
return null;
return mFilterPanel.getFilter();
}
private void showDownloadSuggest()
{
final FragmentManager fm = getChildFragmentManager();
@ -294,7 +304,7 @@ public class SearchFragment extends BaseMwmFragment
new SearchFilterPanelController.FilterPanelListener()
{
@Override
public void onShowOnMap()
public void onViewClick()
{
showAllResultsOnMap();
}
@ -315,7 +325,9 @@ public class SearchFragment extends BaseMwmFragment
runSearch();
}
});
mFilterPanel.showFilterButton(false);
if (mInitialHotelsFilter != null)
mFilterPanel.setFilter(mInitialHotelsFilter);
mFilterPanel.updateFilterButtonVisibility(null);
if (mSearchAdapter == null)
{
@ -337,7 +349,10 @@ public class SearchFragment extends BaseMwmFragment
updateResultsPlaceholder();
if (mInitialQuery != null)
{
setQuery(mInitialQuery);
updateFilterButton(mInitialQuery);
}
mToolbarController.activate();
SearchEngine.INSTANCE.addListener(this);
@ -400,6 +415,7 @@ public class SearchFragment extends BaseMwmFragment
return;
mInitialQuery = arguments.getString(SearchActivity.EXTRA_QUERY);
mInitialHotelsFilter = arguments.getParcelable(SearchActivity.EXTRA_HOTELS_FILTER);
mFromRoutePlan = RoutingController.get().isWaitingPoiPick();
}
@ -467,9 +483,12 @@ public class SearchFragment extends BaseMwmFragment
SearchRecents.add(query);
mLastQueryTimestamp = System.nanoTime();
// TODO (@alexzatsepin): set up hotelsFilter correctly.
HotelsFilter hotelsFilter = null;
if (mFilterPanel != null)
hotelsFilter = mFilterPanel.getFilter();
SearchEngine.searchInteractive(
query, mLastQueryTimestamp, false /* isMapAndTable */, null /* hotelsFilter */);
query, mLastQueryTimestamp, false /* isMapAndTable */, hotelsFilter);
SearchEngine.showAllResults(query);
Utils.navigateToParent(getActivity());
@ -507,7 +526,6 @@ public class SearchFragment extends BaseMwmFragment
}
else
{
// TODO (@alexzatsepin): set up hotelsFilter correctly.
if (!SearchEngine.search(getQuery(), mLastQueryTimestamp, mLastPosition.valid,
mLastPosition.lat, mLastPosition.lon, hotelsFilter))
{
@ -548,14 +566,13 @@ public class SearchFragment extends BaseMwmFragment
updateFilterButton(category);
}
private void updateFilterButton(String category)
private void updateFilterButton(@Nullable String category)
{
if (mFilterPanel != null)
{
String hotel = getString(R.string.hotel);
boolean show = !TextUtils.isEmpty(category)
&& category.trim().toLowerCase().equals(hotel.toLowerCase());
mFilterPanel.showFilterButton(show);
boolean show = mFilterPanel.updateFilterButtonVisibility(category);
if (!show)
mFilterPanel.setFilter(null);
}
}

View file

@ -15,10 +15,12 @@ import android.net.Uri;
import android.os.Build;
import android.support.annotation.AnyRes;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.annotation.StyleRes;
import android.support.design.widget.TextInputLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
@ -431,25 +433,14 @@ public final class UiUtils
decorViewGroup.addView(statusBarTintView);
}
public static void setupColorStatusBar(@NonNull Activity activity, @AttrRes int statusBarColor)
public static void setupColorStatusBar(@NonNull Activity activity, @ColorRes int statusBarColor)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
return;
TypedArray a = null;
try
{
a = activity.obtainStyledAttributes(new int[] {statusBarColor});
int color = a.getColor(0, ContextCompat.getColor(activity, R.color.bg_statusbar));
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(color);
}
finally
{
if (a != null)
a.recycle();
}
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(activity, statusBarColor));
}
public static int getCompassYOffset(@NonNull Context context)