[Android] Refactored booking filter, extracted it onto separate screen/activity

This commit is contained in:
Александр Зацепин 2018-01-22 21:29:55 +03:00 committed by Arsentiy Milchakov
parent 01e406e298
commit 0ccec9cde7
19 changed files with 605 additions and 747 deletions

View file

@ -398,8 +398,11 @@
<data android:scheme="@string/fb_login_protocol_scheme"/>
</intent-filter>
</activity>
<activity android:name="com.mopub.common.MoPubBrowser" android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity
android:name=".search.FilterActivity"
android:configChanges="orientation|screenLayout|screenSize"
android:label="@string/booking_filters"/>
<receiver
android:name="com.mapswithme.maps.background.ConnectivityChangedReceiver"

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

View file

@ -79,11 +79,4 @@
placePage:animationType="left"
placePage:docked="true"
tools:ignore="UnknownIdInLayout"/>
<com.mapswithme.maps.search.HotelsFilterView
android:id="@+id/hotels_filter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
tools:visibility="gone"/>
</RelativeLayout>

View file

@ -92,10 +92,4 @@
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

@ -72,11 +72,4 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
placePage:animationType="bottom"/>
<com.mapswithme.maps.search.HotelsFilterView
android:id="@+id/hotels_filter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
tools:visibility="gone"/>
</RelativeLayout>

View file

@ -96,9 +96,5 @@
android:layout_height="match_parent"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
<com.mapswithme.maps.search.HotelsFilterView
android:id="@+id/filter"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="@dimen/margin_half_plus"
tools:targetApi="lollipop">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleEnabled="false"
app:layout_scrollFlags="enterAlways">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/MwmWidget.ToolbarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="@style/MwmWidget.ToolbarTheme">
<ImageView
android:id="@+id/reset"
android:layout_width="?actionBarSize"
android:layout_height="?actionBarSize"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end|center_vertical"
android:background="?selectableItemBackgroundBorderless"
android:scaleType="centerInside"
android:src="@drawable/ic_24px_clear"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/scroll"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/hotels_filter_padding"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/booking_filters_check_in"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/booking_filters_rating"/>
<include layout="@layout/divider_horizontal"/>
<com.mapswithme.maps.search.RatingFilterView
android:id="@+id/rating"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include layout="@layout/divider_horizontal"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/booking_filters_price_category"/>
<include layout="@layout/divider_horizontal"/>
<com.mapswithme.maps.search.PriceFilterView
android:id="@+id/price"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include layout="@layout/divider_horizontal"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/search_hotel_filters_type"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/item_tag"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<LinearLayout
android:id="@+id/buttons_frame"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:orientation="vertical"
android:layout_gravity="bottom"
android:background="?cardBackground">
<include layout="@layout/divider_horizontal"/>
<TextView
android:id="@+id/done"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textAppearance="@style/MwmTextAppearance.Button"
android:fontFamily="@string/robotoMedium"
android:text="@string/done"
android:background="?clickableBackground"
tools:targetApi="jelly_bean"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>

View file

@ -1,167 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:parentTag="FrameLayout">
<FrameLayout
android:id="@+id/fade"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_dialog_translucent"
android:alpha="0"
tools:alpha="1"/>
<RelativeLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?cardBackground"
android:layout_gravity="bottom"
android:visibility="gone"
tools:visibility="visible">
<RelativeLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?cardBackground"
tools:targetApi="lollipop">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_base"
android:layout_marginLeft="@dimen/margin_base"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/reset"
android:layout_toLeftOf="@id/reset"
android:textAppearance="@style/MwmTextAppearance.Toolbar.Title"
android:fontFamily="@string/robotoMedium"
android:textColor="?android:textColorPrimary"
android:text="@string/booking_filters"/>
<TextView
android:id="@+id/reset"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingRight="@dimen/margin_base"
android:paddingLeft="@dimen/margin_base"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:gravity="center"
android:textAppearance="@style/MwmTextAppearance.Button"
android:fontFamily="@string/robotoMedium"
android:text="@string/booking_filters_reset"
android:background="?clickableBackground"
tools:targetApi="jelly_bean"/>
</RelativeLayout>
<FrameLayout
android:id="@+id/elevation"
style="@style/MwmWidget.FrameLayout.Elevation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header"/>
<android.support.v4.widget.NestedScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/elevation">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/hotels_filter_padding"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/booking_filters_check_in"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/booking_filters_rating"/>
<include layout="@layout/divider_horizontal"/>
<com.mapswithme.maps.search.RatingFilterView
android:id="@+id/rating"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include layout="@layout/divider_horizontal"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/booking_filters_price_category"/>
<include layout="@layout/divider_horizontal"/>
<com.mapswithme.maps.search.PriceFilterView
android:id="@+id/price"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include layout="@layout/divider_horizontal"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Title"
android:text="@string/search_hotel_filters_type"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/item_tag"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<RelativeLayout
android:id="@+id/buttons_frame"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_alignParentBottom="true"
android:background="?cardBackground">
<include layout="@layout/divider_horizontal"/>
<View
android:id="@+id/center_divider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:background="?dividerHorizontal"/>
<TextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@id/center_divider"
android:layout_toStartOf="@id/center_divider"
android:gravity="center"
android:textAppearance="@style/MwmTextAppearance.Button"
android:fontFamily="@string/robotoMedium"
android:text="@string/cancel"
android:background="?clickableBackground"
tools:targetApi="jelly_bean"/>
<TextView
android:id="@+id/done"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/center_divider"
android:layout_toEndOf="@id/center_divider"
android:gravity="center"
android:textAppearance="@style/MwmTextAppearance.Button"
android:fontFamily="@string/robotoMedium"
android:text="@string/done"
android:background="?clickableBackground"
tools:targetApi="jelly_bean"/>
</RelativeLayout>
</RelativeLayout>
</merge>

View file

@ -65,9 +65,9 @@ import com.mapswithme.maps.routing.RoutingBottomMenuListener;
import com.mapswithme.maps.routing.RoutingController;
import com.mapswithme.maps.routing.RoutingPlanFragment;
import com.mapswithme.maps.routing.RoutingPlanInplaceController;
import com.mapswithme.maps.search.FilterActivity;
import com.mapswithme.maps.search.FloatingSearchToolbarController;
import com.mapswithme.maps.search.HotelsFilter;
import com.mapswithme.maps.search.HotelsFilterView;
import com.mapswithme.maps.search.NativeSearchListener;
import com.mapswithme.maps.search.SearchActivity;
import com.mapswithme.maps.search.SearchEngine;
@ -560,27 +560,28 @@ public class MwmActivity extends BaseMwmFragmentActivity
private void initFilterViews()
{
HotelsFilterView hotelsFilterView = (HotelsFilterView) findViewById(R.id.hotels_filter);
View frame = findViewById(R.id.filter_frame);
if (frame != null && hotelsFilterView != null)
if (frame != null)
{
mFilterController = new SearchFilterController(
frame, hotelsFilterView, new SearchFilterController.DefaultFilterListener()
mFilterController = new SearchFilterController(frame, new SearchFilterController
.DefaultFilterListener()
{
@Override
public void onViewClick()
public void onShowOnMapClick()
{
showSearch(mSearchController.getQuery());
}
@Override
public void onFilterClear()
public void onFilterClick()
{
runSearch();
HotelsFilter filter = mFilterController != null ? mFilterController.getFilter() : null;
FilterActivity.startForResult(MwmActivity.this, filter,
FilterActivity.REQ_CODE_FILTER);
}
@Override
public void onFilterDone()
public void onFilterClear()
{
runSearch();
}
@ -606,27 +607,17 @@ public class MwmActivity extends BaseMwmFragmentActivity
final Toolbar toolbar = (Toolbar) mPositionChooser.findViewById(R.id.toolbar_position_chooser);
UiUtils.extendViewWithStatusBar(toolbar);
UiUtils.showHomeUpButton(toolbar);
toolbar.setNavigationOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
hidePositionChooser();
}
});
mPositionChooser.findViewById(R.id.done).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Statistics.INSTANCE.trackEditorLaunch(true);
hidePositionChooser();
if (Framework.nativeIsDownloadedMapAtScreenCenter())
startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class));
else
UiUtils.showAlertDialog(MwmActivity.this, R.string.message_invalid_feature_position);
}
});
toolbar.setNavigationOnClickListener(v -> hidePositionChooser());
mPositionChooser.findViewById(R.id.done).setOnClickListener(
v ->
{
Statistics.INSTANCE.trackEditorLaunch(true);
hidePositionChooser();
if (Framework.nativeIsDownloadedMapAtScreenCenter())
startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class));
else
UiUtils.showAlertDialog(MwmActivity.this, R.string.message_invalid_feature_position);
});
UiUtils.hide(mPositionChooser);
}
@ -1060,6 +1051,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
case REQ_CODE_DISCOVERY:
handleDiscoveryResult(data);
break;
case FilterActivity.REQ_CODE_FILTER:
handleFilterResult(data);
break;
}
}
@ -1080,6 +1074,15 @@ public class MwmActivity extends BaseMwmFragmentActivity
onShowDiscoveredObject(destination);
}
private void handleFilterResult(@Nullable Intent data)
{
if (data == null || mFilterController == null)
return;
mFilterController.setFilter(data.getParcelableExtra(FilterActivity.EXTRA_FILTER));
runSearch();
}
@Override
public void onRouteToDiscoveredObject(@NonNull final MapObject object)
{
@ -1293,9 +1296,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public void onBackPressed()
{
if (mFilterController != null && mFilterController.onBackPressed())
return;
if (getCurrentMenu().close(true))
{
mFadeView.fadeOut();

View file

@ -0,0 +1,82 @@
package com.mapswithme.maps.search;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import com.mapswithme.maps.activity.CustomNavigateUpListener;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.util.ThemeUtils;
public class FilterActivity extends BaseMwmFragmentActivity
implements FilterFragment.Listener, CustomNavigateUpListener
{
public static final int REQ_CODE_FILTER = 101;
public static final String EXTRA_FILTER = "extra_filter";
public static final String ACTION_FILTER_APPLY = "action_filter_apply";
public static void startForResult(@NonNull Activity activity, @Nullable HotelsFilter filter,
int requestCode)
{
Intent i = buildFilterIntent(activity, filter);
activity.startActivityForResult(i, requestCode);
}
public static void startForResult(@NonNull Fragment fragment, @Nullable HotelsFilter filter,
int requestCode)
{
Intent i = buildFilterIntent(fragment.getActivity(), filter);
fragment.startActivityForResult(i, requestCode);
}
@NonNull
private static Intent buildFilterIntent(@NonNull Activity activity, @Nullable HotelsFilter filter)
{
Intent i = new Intent(activity, FilterActivity.class);
Bundle args = new Bundle();
args.putParcelable(FilterFragment.ARG_FILTER, filter);
i.putExtras(args);
return i;
}
@Override
protected boolean useColorStatusBar()
{
return true;
}
@Override
public int getThemeResourceId(@NonNull String theme)
{
return ThemeUtils.getCardBgThemeResourceId(theme);
}
@Override
protected Class<? extends Fragment> getFragmentClass()
{
return FilterFragment.class;
}
@Override
public void onFilterApply(@Nullable HotelsFilter filter)
{
setResult(filter, ACTION_FILTER_APPLY);
}
private void setResult(@Nullable HotelsFilter filter, @NonNull String action)
{
Intent i = new Intent(action);
i.putExtra(EXTRA_FILTER, filter);
setResult(Activity.RESULT_OK, i);
finish();
}
@Override
public void customOnNavigateUp()
{
finish();
}
}

View file

@ -0,0 +1,283 @@
package com.mapswithme.maps.search;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.activity.CustomNavigateUpListener;
import com.mapswithme.maps.base.BaseMwmToolbarFragment;
import com.mapswithme.maps.widget.ToolbarController;
import com.mapswithme.maps.widget.recycler.TagItemDecoration;
import com.mapswithme.maps.widget.recycler.TagLayoutManager;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class FilterFragment extends BaseMwmToolbarFragment
implements HotelsTypeAdapter.OnTypeSelectedListener
{
static final String ARG_FILTER = "arg_filter";
@Nullable
private CustomNavigateUpListener mNavigateUpListener;
@Nullable
private Listener mListener;
@SuppressWarnings("NullableProblems")
@NonNull
private RatingFilterView mRating;
@SuppressWarnings("NullableProblems")
@NonNull
private PriceFilterView mPrice;
@SuppressWarnings("NullableProblems")
@NonNull
private final Drawable mTagsDecorator
= ContextCompat.getDrawable(MwmApplication.get(), R.drawable.divider_transparent_half);
@NonNull
private final Set<HotelsFilter.HotelType> mHotelTypes = new HashSet<>();
@Nullable
private HotelsTypeAdapter mTypeAdapter;
@Override
public void onAttach(Context context)
{
super.onAttach(context);
if (context instanceof CustomNavigateUpListener)
mNavigateUpListener = (CustomNavigateUpListener) context;
if (context instanceof Listener)
mListener = (Listener) context;
}
@Override
public void onDetach()
{
super.onDetach();
mNavigateUpListener = null;
mListener = null;
}
@Override
protected ToolbarController onCreateToolbarController(@NonNull View root)
{
return new ToolbarController(root, getActivity())
{
@Override
public void onUpClick()
{
if (mNavigateUpListener == null)
return;
mNavigateUpListener.customOnNavigateUp();
}
};
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
View root = inflater.inflate(R.layout.fragment_search_filter, container, false);
mRating = root.findViewById(R.id.rating);
mPrice = root.findViewById(R.id.price);
View content = root.findViewById(R.id.content);
RecyclerView type = content.findViewById(R.id.type);
type.setLayoutManager(new TagLayoutManager());
type.setNestedScrollingEnabled(false);
type.addItemDecoration(new TagItemDecoration(mTagsDecorator));
mTypeAdapter = new HotelsTypeAdapter(this);
type.setAdapter(mTypeAdapter);
root.findViewById(R.id.done).setOnClickListener(
v ->
{
if (mListener == null)
return;
HotelsFilter filter = populateFilter();
mListener.onFilterApply(filter);
});
Bundle args = getArguments();
HotelsFilter filter = null;
if (args != null)
filter = args.getParcelable(ARG_FILTER);
updateViews(filter);
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
mToolbarController.setTitle(R.string.booking_filters);
mToolbarController.findViewById(R.id.reset).setOnClickListener(v -> updateViews(null));
}
@Nullable
private HotelsFilter populateFilter()
{
mPrice.updateFilter();
final HotelsFilter.RatingFilter rating = mRating.getFilter();
final HotelsFilter price = mPrice.getFilter();
final HotelsFilter.OneOf oneOf = makeOneOf(mHotelTypes.iterator());
return combineFilters(rating, price, oneOf);
}
@Nullable
private HotelsFilter.OneOf makeOneOf(@NonNull Iterator<HotelsFilter.HotelType> iterator)
{
if (!iterator.hasNext())
return null;
HotelsFilter.HotelType type = iterator.next();
return new HotelsFilter.OneOf(type, makeOneOf(iterator));
}
@Nullable
private HotelsFilter combineFilters(@NonNull HotelsFilter... filters)
{
HotelsFilter result = null;
for (HotelsFilter filter : filters)
{
if (result == null)
{
result = filter;
continue;
}
if (filter != null)
result = new HotelsFilter.And(filter, result);
}
return result;
}
private void updateViews(@Nullable HotelsFilter filter)
{
if (filter == null)
{
mRating.update(null);
mPrice.update(null);
if (mTypeAdapter != null)
updateTypeAdapter(mTypeAdapter, null);
}
else
{
mRating.update(findRatingFilter(filter));
mPrice.update(findPriceFilter(filter));
if (mTypeAdapter != null)
updateTypeAdapter(mTypeAdapter, findTypeFilter(filter));
}
}
@Nullable
private HotelsFilter.RatingFilter findRatingFilter(@NonNull HotelsFilter filter)
{
if (filter instanceof HotelsFilter.RatingFilter)
return (HotelsFilter.RatingFilter) filter;
HotelsFilter.RatingFilter result;
if (filter instanceof HotelsFilter.And)
{
HotelsFilter.And and = (HotelsFilter.And) filter;
result = findRatingFilter(and.mLhs);
if (result == null)
result = findRatingFilter(and.mRhs);
return result;
}
return null;
}
@Nullable
private HotelsFilter findPriceFilter(@NonNull HotelsFilter filter)
{
if (filter instanceof HotelsFilter.PriceRateFilter)
return filter;
if (filter instanceof HotelsFilter.Or)
{
HotelsFilter.Or or = (HotelsFilter.Or) filter;
if (or.mLhs instanceof HotelsFilter.PriceRateFilter
&& or.mRhs instanceof HotelsFilter.PriceRateFilter )
{
return filter;
}
}
HotelsFilter result;
if (filter instanceof HotelsFilter.And)
{
HotelsFilter.And and = (HotelsFilter.And) filter;
result = findPriceFilter(and.mLhs);
if (result == null)
result = findPriceFilter(and.mRhs);
return result;
}
return null;
}
@Nullable
private HotelsFilter.OneOf findTypeFilter(@NonNull HotelsFilter filter)
{
if (filter instanceof HotelsFilter.OneOf)
return (HotelsFilter.OneOf) filter;
HotelsFilter.OneOf result;
if (filter instanceof HotelsFilter.And)
{
HotelsFilter.And and = (HotelsFilter.And) filter;
result = findTypeFilter(and.mLhs);
if (result == null)
result = findTypeFilter(and.mRhs);
return result;
}
return null;
}
private void updateTypeAdapter(@NonNull HotelsTypeAdapter typeAdapter,
@Nullable HotelsFilter.OneOf types)
{
mHotelTypes.clear();
if (types != null)
populateHotelTypes(mHotelTypes, types);
typeAdapter.updateItems(mHotelTypes);
}
private void populateHotelTypes(@NonNull Set<HotelsFilter.HotelType> hotelTypes,
@NonNull HotelsFilter.OneOf types)
{
hotelTypes.add(types.mType);
if (types.mTile != null)
populateHotelTypes(hotelTypes, types.mTile);
}
@Override
public void onTypeSelected(boolean selected, @NonNull HotelsFilter.HotelType type)
{
if (selected)
mHotelTypes.add(type);
else
mHotelTypes.remove(type);
}
interface Listener
{
void onFilterApply(@Nullable HotelsFilter filter);
}
}

View file

@ -1,378 +0,0 @@
package com.mapswithme.maps.search;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.mapswithme.maps.R;
import com.mapswithme.maps.widget.recycler.TagItemDecoration;
import com.mapswithme.maps.widget.recycler.TagLayoutManager;
import com.mapswithme.util.Animations;
import com.mapswithme.util.InputUtils;
import com.mapswithme.util.UiUtils;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HotelsFilterView extends FrameLayout
implements HotelsTypeAdapter.OnTypeSelectedListener
{
private static final String STATE_OPENED = "state_opened";
interface HotelsFilterListener
{
void onCancel();
void onDone(@Nullable HotelsFilter filter);
}
private View mFrame;
private View mFade;
private RatingFilterView mRating;
private PriceFilterView mPrice;
private View mContent;
private View mElevation;
private int mHeaderHeight;
private int mButtonsHeight;
private Drawable mTagsDecorator;
@NonNull
private final Set<HotelsFilter.HotelType> mHotelTypes = new HashSet<>();
@Nullable
private HotelsTypeAdapter mTypeAdapter;
@Nullable
private HotelsFilterListener mListener;
@Nullable
private HotelsFilter mFilter;
private boolean mOpened = false;
public HotelsFilterView(Context context)
{
this(context, null, 0);
}
public HotelsFilterView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public HotelsFilterView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public HotelsFilterView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context)
{
Resources res = context.getResources();
mHeaderHeight = (int) res.getDimension(
UiUtils.getStyledResourceId(context, android.R.attr.actionBarSize));
mButtonsHeight = (int) res.getDimension(R.dimen.height_block_base);
LayoutInflater.from(context).inflate(R.layout.hotels_filter, this, true);
mTagsDecorator = ContextCompat.getDrawable(context, R.drawable.divider_transparent_half);
}
@CallSuper
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
if (isInEditMode())
return;
mFrame = findViewById(R.id.frame);
mFrame.setTranslationY(mFrame.getResources().getDisplayMetrics().heightPixels);
mFade = findViewById(R.id.fade);
mRating = findViewById(R.id.rating);
mPrice = findViewById(R.id.price);
mContent = mFrame.findViewById(R.id.content);
mElevation = mFrame.findViewById(R.id.elevation);
RecyclerView type = mContent.findViewById(R.id.type);
type.setLayoutManager(new TagLayoutManager());
type.setNestedScrollingEnabled(false);
type.addItemDecoration(new TagItemDecoration(mTagsDecorator));
mTypeAdapter = new HotelsTypeAdapter(this);
type.setAdapter(mTypeAdapter);
findViewById(R.id.cancel).setOnClickListener(v -> cancel());
findViewById(R.id.done).setOnClickListener(v ->
{
populateFilter();
if (mListener != null)
mListener.onDone(mFilter);
close();
});
findViewById(R.id.reset).setOnClickListener(v ->
{
mFilter = null;
mHotelTypes.clear();
if (mListener != null)
mListener.onDone(null);
updateViews();
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (isInEditMode())
return;
mContent.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mElevation.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int height = mContent.getMeasuredHeight() + mHeaderHeight + mButtonsHeight
+ mElevation.getMeasuredHeight();
if (height >= getMeasuredHeight())
height = LayoutParams.WRAP_CONTENT;
ViewGroup.LayoutParams lp = mFrame.getLayoutParams();
lp.height = height;
mFrame.setLayoutParams(lp);
}
private void cancel()
{
updateViews();
if (mListener != null)
mListener.onCancel();
close();
}
private void populateFilter()
{
mPrice.updateFilter();
final HotelsFilter.RatingFilter rating = mRating.getFilter();
final HotelsFilter price = mPrice.getFilter();
final HotelsFilter.OneOf oneOf = makeOneOf(mHotelTypes.iterator());
mFilter = combineFilters(rating, price, oneOf);
}
@Nullable
private HotelsFilter.OneOf makeOneOf(@NonNull Iterator<HotelsFilter.HotelType> iterator)
{
if (!iterator.hasNext())
return null;
HotelsFilter.HotelType type = iterator.next();
return new HotelsFilter.OneOf(type, makeOneOf(iterator));
}
@Nullable
private HotelsFilter combineFilters(@NonNull HotelsFilter... filters)
{
HotelsFilter result = null;
for (HotelsFilter filter : filters)
{
if (result == null)
{
result = filter;
continue;
}
if (filter != null)
result = new HotelsFilter.And(filter, result);
}
return result;
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (mOpened && !UiUtils.isViewTouched(event, mFrame))
{
cancel();
return true;
}
super.onTouchEvent(event);
return mOpened;
}
public boolean close()
{
if (!mOpened)
return false;
mOpened = false;
Animations.fadeOutView(mFade, null);
Animations.disappearSliding(mFrame, Animations.BOTTOM, null);
return true;
}
public void open(@Nullable HotelsFilter filter)
{
if (mOpened)
return;
mOpened = true;
mFilter = filter;
Animations.fadeInView(mFade, null);
Animations.appearSliding(mFrame, Animations.BOTTOM, new Runnable()
{
@Override
public void run()
{
updateViews();
}
});
InputUtils.hideKeyboard(this);
}
private void updateViews()
{
if (mFilter == null)
{
mRating.update(null);
mPrice.update(null);
if (mTypeAdapter != null)
updateTypeAdapter(mTypeAdapter, null);
}
else
{
mRating.update(findRatingFilter(mFilter));
mPrice.update(findPriceFilter(mFilter));
if (mTypeAdapter != null)
updateTypeAdapter(mTypeAdapter, findTypeFilter(mFilter));
}
}
@Nullable
private HotelsFilter.RatingFilter findRatingFilter(@NonNull HotelsFilter filter)
{
if (filter instanceof HotelsFilter.RatingFilter)
return (HotelsFilter.RatingFilter) filter;
HotelsFilter.RatingFilter result;
if (filter instanceof HotelsFilter.And)
{
HotelsFilter.And and = (HotelsFilter.And) filter;
result = findRatingFilter(and.mLhs);
if (result == null)
result = findRatingFilter(and.mRhs);
return result;
}
return null;
}
@Nullable
private HotelsFilter findPriceFilter(@NonNull HotelsFilter filter)
{
if (filter instanceof HotelsFilter.PriceRateFilter)
return filter;
if (filter instanceof HotelsFilter.Or)
{
HotelsFilter.Or or = (HotelsFilter.Or) filter;
if (or.mLhs instanceof HotelsFilter.PriceRateFilter
&& or.mRhs instanceof HotelsFilter.PriceRateFilter )
{
return filter;
}
}
HotelsFilter result;
if (filter instanceof HotelsFilter.And)
{
HotelsFilter.And and = (HotelsFilter.And) filter;
result = findPriceFilter(and.mLhs);
if (result == null)
result = findPriceFilter(and.mRhs);
return result;
}
return null;
}
@Nullable
private HotelsFilter.OneOf findTypeFilter(@NonNull HotelsFilter filter)
{
if (filter instanceof HotelsFilter.OneOf)
return (HotelsFilter.OneOf) filter;
HotelsFilter.OneOf result;
if (filter instanceof HotelsFilter.And)
{
HotelsFilter.And and = (HotelsFilter.And) filter;
result = findTypeFilter(and.mLhs);
if (result == null)
result = findTypeFilter(and.mRhs);
return result;
}
return null;
}
private void updateTypeAdapter(@NonNull HotelsTypeAdapter typeAdapter,
@Nullable HotelsFilter.OneOf types)
{
mHotelTypes.clear();
if (types != null)
populateHotelTypes(mHotelTypes, types);
typeAdapter.updateItems(mHotelTypes);
}
private void populateHotelTypes(@NonNull Set<HotelsFilter.HotelType> hotelTypes,
@NonNull HotelsFilter.OneOf types)
{
hotelTypes.add(types.mType);
if (types.mTile != null)
populateHotelTypes(hotelTypes, types.mTile);
}
public void setListener(@Nullable HotelsFilterListener listener)
{
mListener = listener;
}
public void onSaveState(@NonNull Bundle outState)
{
outState.putBoolean(STATE_OPENED, mOpened);
}
public void onRestoreState(@NonNull Bundle state, @Nullable HotelsFilter filter)
{
if (state.getBoolean(STATE_OPENED, false))
open(filter);
}
@Override
public void onTypeSelected(boolean selected, @NonNull HotelsFilter.HotelType type)
{
if (selected)
mHotelTypes.add(type);
else
mHotelTypes.remove(type);
}
}

View file

@ -1,6 +1,5 @@
package com.mapswithme.maps.search;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -30,16 +29,11 @@ public class SearchFilterController
private final TextView mFilterText;
@NonNull
private final View mDivider;
@NonNull
private final HotelsFilterView mFilterView;
@Nullable
private HotelsFilter mFilter;
@Nullable
private BookingFilterParams mBookingFilterParams;
private final float mElevation;
private boolean mHotelMode;
@NonNull
@ -59,36 +53,28 @@ public class SearchFilterController
interface FilterListener
{
void onViewClick();
void onShowOnMapClick();
void onFilterClick();
void onFilterClear();
void onFilterCancel();
void onFilterDone();
}
SearchFilterController(@NonNull View frame, @NonNull HotelsFilterView filter,
@Nullable FilterListener listener)
SearchFilterController(@NonNull View frame, @Nullable FilterListener listener)
{
this(frame, filter, listener, R.string.search_show_on_map);
this(frame, listener, R.string.search_show_on_map);
}
public SearchFilterController(@NonNull View frame, @NonNull HotelsFilterView filter,
@Nullable FilterListener listener,
@StringRes int populateButtonText)
public SearchFilterController(@NonNull View frame,
@Nullable FilterListener listener, @StringRes int populateButtonText)
{
mFrame = frame;
mFilterView = filter;
mFilterListener = listener;
mShowOnMap = (TextView) mFrame.findViewById(R.id.show_on_map);
mShowOnMap = 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);
mFilterIcon = mFilterButton.findViewById(R.id.filter_icon);
mFilterText = mFilterButton.findViewById(R.id.filter_text);
mDivider = mFrame.findViewById(R.id.divider);
Resources res = mFrame.getResources();
mElevation = res.getDimension(R.dimen.margin_quarter);
initListeners();
}
@ -116,43 +102,16 @@ public class SearchFilterController
private void initListeners()
{
mShowOnMap.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (mFilterListener != null)
mFilterListener.onViewClick();
}
});
mFilterButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mFilterView.open(getFilter());
if (mFilterListener != null)
mFilterListener.onFilterClick();
}
});
mFilterView.setListener(new HotelsFilterView.HotelsFilterListener()
{
@Override
public void onCancel()
{
if (mFilterListener != null)
mFilterListener.onFilterCancel();
}
@Override
public void onDone(@Nullable HotelsFilter filter)
{
setFilter(filter);
if (mFilterListener != null)
mFilterListener.onFilterDone();
}
});
mShowOnMap.setOnClickListener(v ->
{
if (mFilterListener != null)
mFilterListener.onShowOnMapClick();
});
mFilterButton.setOnClickListener(v ->
{
if (mFilterListener != null)
mFilterListener.onFilterClick();
});
}
@Nullable
@ -186,7 +145,7 @@ public class SearchFilterController
}
}
public void resetFilter()
void resetFilter()
{
setFilter(null);
updateFilterButtonVisibility(false);
@ -203,31 +162,23 @@ public class SearchFilterController
mBookingFilterParams = params;
}
public boolean onBackPressed()
{
mHotelMode = false;
return mFilterView.close();
}
public void onSaveState(@NonNull Bundle outState)
{
outState.putParcelable(STATE_HOTEL_FILTER, mFilter);
outState.putBoolean(STATE_HOTEL_FILTER_VISIBILITY,
mFilterButton.getVisibility() == View.VISIBLE);
mFilterView.onSaveState(outState);
}
public void onRestoreState(@NonNull Bundle state)
{
setFilter((HotelsFilter) state.getParcelable(STATE_HOTEL_FILTER));
setFilter(state.getParcelable(STATE_HOTEL_FILTER));
updateFilterButtonVisibility(state.getBoolean(STATE_HOTEL_FILTER_VISIBILITY, false));
mFilterView.onRestoreState(state, mFilter);
}
public static class DefaultFilterListener implements FilterListener
{
@Override
public void onViewClick()
public void onShowOnMapClick()
{
}
@ -239,16 +190,7 @@ public class SearchFilterController
@Override
public void onFilterClear()
{
}
@Override
public void onFilterCancel()
{
}
@Override
public void onFilterDone()
{
}
}
}

View file

@ -1,5 +1,6 @@
package com.mapswithme.maps.search;
import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
@ -70,23 +71,9 @@ public class SearchFragment extends BaseMwmFragment
@Nullable
private SearchAdView mGoogleAdView;
@NonNull
private final Runnable mResultsShowingTask = new Runnable()
{
@Override
public void run()
{
refreshSearchResults();
}
};
private final Runnable mResultsShowingTask = this::refreshSearchResults;
@NonNull
private final Runnable mSearchEndTask = new Runnable()
{
@Override
public void run()
{
onSearchEnd();
}
};
private final Runnable mSearchEndTask = this::onSearchEnd;
private static class LastPosition
{
@ -348,55 +335,52 @@ public class SearchFragment extends BaseMwmFragment
if (ConnectionState.isWifiConnected() && SharedPropertiesUtils.isShowcaseSwitchedOnLocal())
{
mAdsLoader = new GoogleAdsLoader(getContext(), ADS_DELAY_MS);
mAdsLoader.attach(new GoogleAdsLoader.AdvertLoadingListener()
{
@Override
public void onLoadingFinished(@NonNull SearchAdView searchAdView)
{
mGoogleAdView = searchAdView;
mAdsRequested = false;
}
});
mAdsLoader.attach(searchAdView ->
{
mGoogleAdView = searchAdView;
mAdsRequested = false;
});
}
ViewGroup root = (ViewGroup) view;
mAppBarLayout = (AppBarLayout) root.findViewById(R.id.app_bar);
mToolbarLayout = (CollapsingToolbarLayout) mAppBarLayout.findViewById(R.id.collapsing_toolbar);
mAppBarLayout = root.findViewById(R.id.app_bar);
mToolbarLayout = mAppBarLayout.findViewById(R.id.collapsing_toolbar);
mTabFrame = root.findViewById(R.id.tab_frame);
ViewPager pager = (ViewPager) mTabFrame.findViewById(R.id.pages);
ViewPager pager = mTabFrame.findViewById(R.id.pages);
mToolbarController = new ToolbarController(view);
TabLayout tabLayout = (TabLayout) root.findViewById(R.id.tabs);
TabLayout tabLayout = root.findViewById(R.id.tabs);
final TabAdapter tabAdapter = new TabAdapter(getChildFragmentManager(), pager, tabLayout);
mResultsFrame = root.findViewById(R.id.results_frame);
mResults = (RecyclerView) mResultsFrame.findViewById(R.id.recycler);
mResults = mResultsFrame.findViewById(R.id.recycler);
setRecyclerScrollListener(mResults);
mResultsPlaceholder = (PlaceholderView) mResultsFrame.findViewById(R.id.placeholder);
mResultsPlaceholder = mResultsFrame.findViewById(R.id.placeholder);
mResultsPlaceholder.setContent(R.drawable.img_mappyny,
R.string.search_not_found, R.string.search_not_found_query);
mFilterElevation = view.findViewById(R.id.filter_elevation);
mFilterController = new SearchFilterController(root.findViewById(R.id.filter_frame),
(HotelsFilterView) view.findViewById(R.id.filter),
new SearchFilterController.DefaultFilterListener()
{
@Override
public void onViewClick()
public void onShowOnMapClick()
{
showAllResultsOnMap();
}
@Override
public void onFilterClear()
public void onFilterClick()
{
runSearch();
HotelsFilter filter = mFilterController != null ? mFilterController.getFilter() : null;
FilterActivity.startForResult(SearchFragment.this, filter,
FilterActivity.REQ_CODE_FILTER);
}
@Override
public void onFilterDone()
public void onFilterClear()
{
runSearch();
}
@ -437,15 +421,11 @@ public class SearchFragment extends BaseMwmFragment
if (SearchRecents.getSize() == 0)
pager.setCurrentItem(TabAdapter.Tab.CATEGORIES.ordinal());
tabAdapter.setTabSelectedListener(new TabAdapter.OnTabSelectedListener()
{
@Override
public void onTabSelected(@NonNull TabAdapter.Tab tab)
{
Statistics.INSTANCE.trackSearchTabSelected(tab.name());
mToolbarController.deactivate();
}
});
tabAdapter.setTabSelectedListener(tab ->
{
Statistics.INSTANCE.trackSearchTabSelected(tab.name());
mToolbarController.deactivate();
});
if (mInitialSearchOnMap)
showAllResultsOnMap();
@ -756,13 +736,28 @@ public class SearchFragment extends BaseMwmFragment
{
super.onActivityResult(requestCode, resultCode, data);
mToolbarController.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK)
return;
switch (requestCode)
{
case FilterActivity.REQ_CODE_FILTER:
if (data == null)
break;
if (mFilterController == null)
return;
mFilterController.setFilter(data.getParcelableExtra(FilterActivity.EXTRA_FILTER));
runSearch();
break;
}
}
@Override
public boolean onBackPressed()
{
if (mFilterController != null && mFilterController.onBackPressed())
return true;
if (mToolbarController.hasQuery())
{
mToolbarController.clear();

View file

@ -10,7 +10,6 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import com.mapswithme.maps.R;
import com.mapswithme.util.InputUtils;
@ -23,11 +22,11 @@ public class SearchToolbarController extends ToolbarController
{
private static final int REQUEST_VOICE_RECOGNITION = 0xCA11;
protected final View mContainer;
protected final EditText mQuery;
private final View mContainer;
private final EditText mQuery;
protected final View mProgress;
protected final View mClear;
protected final View mVoiceInput;
private final View mClear;
private final View mVoiceInput;
private final boolean mVoiceInputSupported = InputUtils.isVoiceInputSupported(mActivity);
@ -52,23 +51,20 @@ public class SearchToolbarController extends ToolbarController
mContainer = mToolbar.findViewById(R.id.frame);
mQuery = (EditText) mContainer.findViewById(R.id.query);
mQuery = mContainer.findViewById(R.id.query);
mQuery.setOnClickListener(this);
mQuery.addTextChangedListener(mTextWatcher);
mQuery.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
boolean isSearchDown = (event != null &&
event.getAction() == KeyEvent.ACTION_DOWN &&
event.getKeyCode() == KeyEvent.KEYCODE_SEARCH);
mQuery.setOnEditorActionListener(
(v, actionId, event) ->
{
boolean isSearchDown = (event != null &&
event.getAction() == KeyEvent.ACTION_DOWN &&
event.getKeyCode() == KeyEvent.KEYCODE_SEARCH);
boolean isSearchAction = (actionId == EditorInfo.IME_ACTION_SEARCH);
boolean isSearchAction = (actionId == EditorInfo.IME_ACTION_SEARCH);
return (isSearchDown || isSearchAction) && onStartSearchClick();
}
});
return (isSearchDown || isSearchAction) && onStartSearchClick();
});
mProgress = mContainer.findViewById(R.id.progress);