Added Google Ads

This commit is contained in:
Кузнецова Ксения 2017-08-22 11:49:12 +03:00 committed by Roman Kuznetsov
parent a1859a6f48
commit cf324e4bbb
11 changed files with 507 additions and 86 deletions

View file

@ -45,6 +45,7 @@ dependencies {
compile 'com.google.android.gms:play-services-analytics:10.0.1'
compile 'com.google.android.gms:play-services-plus:10.0.1'
compile 'com.google.android.gms:play-services-gcm:10.0.1'
compile 'com.google.android.gms:play-services-ads:10.0.1'
// statistics
compile 'com.flurry.android:analytics:6.7.0'
// crash reporting

View file

@ -39,6 +39,31 @@
<attr name="drawSmile" format="boolean"/>
</declare-styleable>
<declare-styleable name="GoogleAds" >
<attr name="colorLocation" format="string"/>
<attr name="fontSizeLocation" format="string"/>
<attr name="clickToCall" format="string"/>
<attr name="location" format="string"/>
<attr name="sellerRatings" format="string"/>
<attr name="siteLinks" format="string"/>
<attr name="number" format="string"/>
<attr name="fontSizeAnnotation" format="string"/>
<attr name="fontSizeAttribution" format="string"/>
<attr name="fontSizeDescription" format="string"/>
<attr name="fontSizeDomainLink" format="string"/>
<attr name="fontSizeTitle" format="string"/>
<attr name="colorAdBorder" format="string"/>
<attr name="colorAnnotation" format="string"/>
<attr name="colorAttribution" format="string"/>
<attr name="colorBackground" format="string"/>
<attr name="colorDomainLink" format="string"/>
<attr name="colorText" format="string"/>
<attr name="colorTitleLink" format="string"/>
<attr name="attributionSpacingBelow" format="string"/>
<attr name="noTitleUnderline" format="string"/>
<attr name="titleBold" format="string"/>
</declare-styleable>
<bool name="isTablet">false</bool>
<bool name="tabletLayout">false</bool>
</resources>

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="GoogleAdsLight">
<item name="colorLocation">#FFF9EF</item>
<item name="fontSizeLocation">12</item>
<item name="clickToCall">true</item>
<item name="location">true</item>
<item name="sellerRatings">false</item>
<item name="siteLinks">false</item>
<item name="number">1</item>;
<item name="fontSizeAnnotation">12</item>
<item name="fontSizeAttribution">12</item>
<item name="fontSizeDescription">12</item>
<item name="fontSizeDomainLink">12</item>
<item name="fontSizeTitle">12</item>
<item name="colorAdBorder">#E0DAD1</item>
<item name="colorAnnotation">#75726D</item>
<item name="colorAttribution">#75726D</item>
<item name="colorBackground">#FFF9EF</item>
<item name="colorDomainLink">#1E96F0</item>
<item name="colorText">#75726D</item>
<item name="colorTitleLink">#21201E</item>
<item name="attributionSpacingBelow">4</item>
<item name="noTitleUnderline">true</item>
<item name="titleBold">true</item>
</style>
<style name="GoogleAdsDark">
<item name="colorLocation">#484B50</item>
<item name="fontSizeLocation">12</item>
<item name="clickToCall">true</item>
<item name="location">true</item>
<item name="sellerRatings">false</item>
<item name="siteLinks">false</item>
<item name="number">1</item>;
<item name="fontSizeAnnotation">12</item>
<item name="fontSizeAttribution">12</item>
<item name="fontSizeDescription">12</item>
<item name="fontSizeDomainLink">12</item>
<item name="fontSizeTitle">12</item>
<item name="colorAdBorder">#56595D</item>
<item name="colorAnnotation">#C8C9CA</item>
<item name="colorAttribution">#C8C9CA</item>
<item name="colorBackground">#484B50</item>
<item name="colorDomainLink">#51B5E6</item>
<item name="colorText">#C8C9CA</item>
<item name="colorTitleLink">#FFFFFF</item>
<item name="attributionSpacingBelow">4</item>
<item name="noTitleUnderline">true</item>
<item name="titleBold">true</item>
</style>
</resources>

View file

@ -1,9 +1,12 @@
package com.mapswithme.maps.ads;
import android.support.annotation.NonNull;
import com.mapswithme.maps.Framework;
public class GoogleSearchAd
{
@NonNull
private String mAdUnitId = "";
public GoogleSearchAd()
@ -22,5 +25,6 @@ public class GoogleSearchAd
}
}
String getAdUnitId() { return mAdUnitId; }
@NonNull
public String getAdUnitId() { return mAdUnitId; }
}

View file

@ -0,0 +1,28 @@
package com.mapswithme.maps.search;
import android.support.annotation.NonNull;
import com.google.android.gms.ads.search.SearchAdView;
class GoogleAdsBanner implements SearchData
{
@NonNull
private SearchAdView mAdView;
GoogleAdsBanner(@NonNull SearchAdView adView)
{
this.mAdView = adView;
}
@NonNull
SearchAdView getAdView()
{
return mAdView;
}
@Override
public int getItemViewType()
{
return SearchResultTypes.TYPE_GOOGLE_ADS;
}
}

View file

@ -0,0 +1,151 @@
package com.mapswithme.maps.search;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.ads.mediation.admob.AdMobAdapter;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.search.SearchAdRequest;
import com.google.android.gms.ads.search.SearchAdView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.ads.GoogleSearchAd;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.concurrency.UiThread;
class GoogleAdsLoader
{
private long mLoadingDelay;
@NonNull
private final Bundle mStyleParams = new Bundle();
@Nullable
private GoogleSearchAd mGoogleSearchAd;
@Nullable
private Runnable mLoadingTask;
@NonNull
private String mQuery = "";
@Nullable
private AdvertLoadingListener mLoadingListener;
GoogleAdsLoader(@NonNull Context context, long loadingDelay)
{
this.mLoadingDelay = loadingDelay;
initStyle(context);
}
void scheduleAdsLoading(@NonNull final Context context, @NonNull final String query)
{
cancelAdsLoading();
mQuery = query;
mGoogleSearchAd = new GoogleSearchAd();
if (mGoogleSearchAd.getAdUnitId().isEmpty())
return;
mLoadingTask = new Runnable()
{
@Override
public void run()
{
performLoading(context);
}
};
UiThread.runLater(mLoadingTask, mLoadingDelay);
}
void cancelAdsLoading()
{
if (mLoadingTask != null)
{
UiThread.cancelDelayedTasks(mLoadingTask);
mLoadingTask = null;
}
}
private void updateAdView(SearchAdView searchAdView)
{
SearchAdRequest.Builder builder = new SearchAdRequest.Builder()
.setQuery(mQuery)
.addNetworkExtrasBundle(AdMobAdapter.class, mStyleParams);
searchAdView.loadAd(builder.build());
}
void attach(@NonNull AdvertLoadingListener listener)
{
mLoadingListener = listener;
}
void detach()
{
mLoadingListener = null;
}
private void initStyle(@NonNull Context context)
{
TypedArray attrs = context.obtainStyledAttributes(ThemeUtils.isNightTheme() ?
R.style.GoogleAdsDark : R.style.GoogleAdsLight, R.styleable.GoogleAds);
mStyleParams.putString("csa_width", "auto");
mStyleParams.putString("csa_colorLocation", attrs.getString(R.styleable.GoogleAds_colorLocation));
mStyleParams.putString("csa_fontSizeLocation", attrs.getString(R.styleable.GoogleAds_fontSizeLocation));
mStyleParams.putString("csa_clickToCall", attrs.getString(R.styleable.GoogleAds_clickToCall));
mStyleParams.putString("csa_location", attrs.getString(R.styleable.GoogleAds_location));
mStyleParams.putString("csa_sellerRatings", attrs.getString(R.styleable.GoogleAds_sellerRatings));
mStyleParams.putString("csa_siteLinks", attrs.getString(R.styleable.GoogleAds_siteLinks));
mStyleParams.putString("csa_number", attrs.getString(R.styleable.GoogleAds_number));
mStyleParams.putString("csa_fontSizeAnnotation", attrs.getString(R.styleable.GoogleAds_fontSizeAnnotation));
mStyleParams.putString("csa_fontSizeAttribution", attrs.getString(R.styleable.GoogleAds_fontSizeAttribution));
mStyleParams.putString("csa_fontSizeDescription", attrs.getString(R.styleable.GoogleAds_fontSizeDescription));
mStyleParams.putString("csa_fontSizeDomainLink", attrs.getString(R.styleable.GoogleAds_fontSizeDomainLink));
mStyleParams.putString("csa_fontSizeTitle", attrs.getString(R.styleable.GoogleAds_fontSizeTitle));
mStyleParams.putString("csa_colorAdBorder", attrs.getString(R.styleable.GoogleAds_colorAdBorder));
mStyleParams.putString("csa_colorAnnotation", attrs.getString(R.styleable.GoogleAds_colorAnnotation));
mStyleParams.putString("csa_colorAttribution", attrs.getString(R.styleable.GoogleAds_colorAttribution));
mStyleParams.putString("csa_colorBackground", attrs.getString(R.styleable.GoogleAds_colorBackground));
mStyleParams.putString("csa_colorDomainLink", attrs.getString(R.styleable.GoogleAds_colorDomainLink));
mStyleParams.putString("csa_colorText", attrs.getString(R.styleable.GoogleAds_colorText));
mStyleParams.putString("csa_colorTitleLink", attrs.getString(R.styleable.GoogleAds_colorTitleLink));
mStyleParams.putString("csa_attributionSpacingBelow", attrs.getString(R.styleable.GoogleAds_attributionSpacingBelow));
mStyleParams.putString("csa_noTitleUnderline", attrs.getString(R.styleable.GoogleAds_noTitleUnderline));
mStyleParams.putString("csa_titleBold", attrs.getString(R.styleable.GoogleAds_titleBold));
attrs.recycle();
}
private void performLoading(@NonNull Context context)
{
if (mGoogleSearchAd == null)
throw new AssertionError("mGoogleSearchAd can't be null here");
final SearchAdView view = new SearchAdView(context);
view.setAdSize(AdSize.SEARCH);
view.setAdUnitId(mGoogleSearchAd.getAdUnitId());
updateAdView(view);
view.setAdListener(new AdListener()
{
@Override
public void onAdLoaded()
{
mLoadingTask = null;
if (mLoadingListener != null)
{
mLoadingListener.onLoadingFinished(view);
}
}
@Override
public void onAdFailedToLoad(int i)
{
mLoadingTask = null;
}
});
}
interface AdvertLoadingListener
{
void onLoadingFinished(@NonNull SearchAdView searchAdView);
}
}

View file

@ -13,6 +13,7 @@ import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.mapswithme.maps.R;
@ -21,23 +22,29 @@ import com.mapswithme.util.Graphics;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder>
{
private static final int TYPE_SUGGEST = 0;
private static final int TYPE_RESULT = 1;
private static final int TYPE_LOCAL_ADS_CUSTOMER = 2;
private final SearchFragment mSearchFragment;
private SearchResult[] mResults;
private SearchData[] mResults;
private final Drawable mClosedMarkerBackground;
static abstract class BaseViewHolder extends RecyclerView.ViewHolder
static abstract class SearchDataViewHolder extends RecyclerView.ViewHolder
{
SearchDataViewHolder(@NonNull View itemView)
{
super(itemView);
}
abstract void bind(@NonNull SearchData searchData, int position);
}
private static abstract class BaseResultViewHolder extends SearchDataViewHolder
{
SearchResult mResult;
// Position within search results
int mOrder;
BaseViewHolder(View view)
BaseResultViewHolder(@NonNull View view)
{
super(view);
if (view instanceof TextView)
@ -46,25 +53,6 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
if (tintAttr != 0)
Graphics.tint((TextView)view, tintAttr);
}
}
@AttrRes int getTintAttr()
{
return R.attr.colorAccent;
}
void bind(@NonNull SearchResult result, int order)
{
mResult = result;
mOrder = order;
}
}
private static abstract class BaseResultViewHolder extends BaseViewHolder
{
BaseResultViewHolder(View view)
{
super(view);
view.setOnClickListener(new View.OnClickListener()
{
@Override
@ -76,26 +64,33 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
}
@Override
void bind(@NonNull SearchResult result, int order)
void bind(@NonNull SearchData result, int order)
{
super.bind(result, order);
SpannableStringBuilder builder = new SpannableStringBuilder(result.name);
if (result.highlightRanges != null)
mResult = (SearchResult)result;
mOrder = order;
SpannableStringBuilder builder = new SpannableStringBuilder(mResult.name);
if (mResult.highlightRanges != null)
{
final int size = result.highlightRanges.length / 2;
final int size = mResult.highlightRanges.length / 2;
int index = 0;
for (int i = 0; i < size; i++)
{
final int start = result.highlightRanges[index++];
final int len = result.highlightRanges[index++];
final int start = mResult.highlightRanges[index++];
final int len = mResult.highlightRanges[index++];
builder.setSpan(new StyleSpan(Typeface.BOLD), start, start + len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
getTitleView().setText(builder);
TextView titleView = getTitleView();
if (titleView != null)
titleView.setText(builder);
}
@AttrRes int getTintAttr()
{
return R.attr.colorAccent;
}
abstract TextView getTitleView();
@ -123,6 +118,25 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
}
}
private static class GoogleAdsViewHolder extends SearchDataViewHolder
{
@NonNull
private ViewGroup container;
GoogleAdsViewHolder(@NonNull View view)
{
super(view);
container = (FrameLayout)view;
}
@Override
void bind(@NonNull SearchData searchData, int position)
{
container.removeAllViews();
container.addView(((GoogleAdsBanner)searchData).getAdView());
}
}
private class ResultViewHolder extends BaseResultViewHolder
{
final TextView mName;
@ -205,16 +219,16 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
}
@Override
void bind(@NonNull SearchResult result, int order)
void bind(@NonNull SearchData result, int order)
{
super.bind(result, order);
// TODO: Support also "Open Now" mark.
UiUtils.showIf(result.description.openNow == SearchResult.OPEN_NOW_NO, mClosedMarker);
UiUtils.setTextAndHideIfEmpty(mDescription, formatDescription(result));
UiUtils.setTextAndHideIfEmpty(mRegion, result.description.region);
UiUtils.setTextAndHideIfEmpty(mDistance, result.description.distance);
UiUtils.setTextAndHideIfEmpty(mPriceCategory, result.description.pricing);
UiUtils.showIf(mResult.description.openNow == SearchResult.OPEN_NOW_NO, mClosedMarker);
UiUtils.setTextAndHideIfEmpty(mDescription, formatDescription(mResult));
UiUtils.setTextAndHideIfEmpty(mRegion, mResult.description.region);
UiUtils.setTextAndHideIfEmpty(mDistance, mResult.description.distance);
UiUtils.setTextAndHideIfEmpty(mPriceCategory, mResult.description.pricing);
}
@Override
@ -245,29 +259,31 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
public SearchDataViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType)
{
case TYPE_SUGGEST:
return new SuggestViewHolder(inflater.inflate(R.layout.item_search_suggest, parent, false));
case SearchResultTypes.TYPE_SUGGEST:
return new SuggestViewHolder(inflater.inflate(R.layout.item_search_suggest, parent, false));
case TYPE_RESULT:
return new ResultViewHolder(inflater.inflate(R.layout.item_search_result, parent, false));
case SearchResultTypes.TYPE_RESULT:
return new ResultViewHolder(inflater.inflate(R.layout.item_search_result, parent, false));
case TYPE_LOCAL_ADS_CUSTOMER:
return new LocalAdsCustomerViewHolder(inflater.inflate(R.layout.item_search_result, parent,
false));
case SearchResultTypes.TYPE_LOCAL_ADS_CUSTOMER:
return new LocalAdsCustomerViewHolder(inflater.inflate(R.layout.item_search_result, parent, false));
default:
throw new IllegalArgumentException("Unhandled view type given");
case SearchResultTypes.TYPE_GOOGLE_ADS:
return new GoogleAdsViewHolder(new FrameLayout(parent.getContext()));
default:
throw new IllegalArgumentException("Unhandled view type given");
}
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position)
public void onBindViewHolder(@NonNull SearchDataViewHolder holder, int position)
{
holder.bind(mResults[position], position);
}
@ -275,20 +291,7 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
@Override
public int getItemViewType(int position)
{
switch (mResults[position].type)
{
case SearchResult.TYPE_SUGGEST:
return TYPE_SUGGEST;
case SearchResult.TYPE_RESULT:
return TYPE_RESULT;
case SearchResult.TYPE_LOCAL_ADS_CUSTOMER:
return TYPE_LOCAL_ADS_CUSTOMER;
default:
throw new IllegalArgumentException("Unhandled SearchResult type");
}
return mResults[position].getItemViewType();
}
boolean showPopulateButton()
@ -296,7 +299,8 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
return (!RoutingController.get().isWaitingPoiPick() &&
mResults != null &&
mResults.length > 0 &&
mResults[0].type != SearchResult.TYPE_SUGGEST);
SearchResult.class.isInstance(mResults[0]) &&
((SearchResult) mResults[0]).type != SearchResultTypes.TYPE_SUGGEST);
}
@Override
@ -321,7 +325,7 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.BaseViewHolder>
refreshData(null);
}
void refreshData(SearchResult[] results)
void refreshData(SearchData[] results)
{
mResults = results;
notifyDataSetChanged();

View file

@ -0,0 +1,6 @@
package com.mapswithme.maps.search;
interface SearchData
{
int getItemViewType();
}

View file

@ -20,6 +20,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.ads.search.SearchAdView;
import com.mapswithme.maps.MwmActivity;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
@ -35,12 +36,16 @@ import com.mapswithme.maps.routing.RoutingController;
import com.mapswithme.maps.widget.PlaceholderView;
import com.mapswithme.maps.widget.SearchToolbarController;
import com.mapswithme.maps.widget.placepage.Sponsored;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.SharedPropertiesUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.concurrency.UiThread;
import com.mapswithme.util.log.LoggerFactory;
import com.mapswithme.util.statistics.Statistics;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class SearchFragment extends BaseMwmFragment
@ -51,9 +56,38 @@ public class SearchFragment extends BaseMwmFragment
HotelsFilterHolder
{
public static final String PREFS_SHOW_ENABLE_LOGGING_SETTING = "ShowEnableLoggingSetting";
private static final int MIN_QUERY_LENGTH_FOR_AD = 3;
private static final long ADS_DELAY_MS = 200;
private static final long RESULTS_DELAY_MS = 400;
private static final int AD_POSITION = 3;
private long mLastQueryTimestamp;
@Nullable
private GoogleAdsLoader mAdsLoader;
private boolean mAdsRequested = false;
private int mAdsOrientation = -1;
@Nullable
private SearchAdView mGoogleAdView;
@NonNull
private final Runnable mResultsShowingTask = new Runnable()
{
@Override
public void run()
{
refreshSearchResults();
}
};
@NonNull
private final Runnable mSearchEndTask = new Runnable()
{
@Override
public void run()
{
onSearchEnd();
}
};
private static class LastPosition
{
double lat;
@ -87,6 +121,11 @@ public class SearchFragment extends BaseMwmFragment
if (!isAdded())
return;
UiThread.cancelDelayedTasks(mSearchEndTask);
UiThread.cancelDelayedTasks(mResultsShowingTask);
mGoogleAdView = null;
stopAdsLoading();
if (TextUtils.isEmpty(query))
{
mSearchAdapter.clear();
@ -105,6 +144,12 @@ public class SearchFragment extends BaseMwmFragment
if (mCianCategorySelected)
return;
if (mAdsLoader != null && !isInteractiveSearch() && query.length() >= MIN_QUERY_LENGTH_FOR_AD)
{
mAdsRequested = true;
mAdsLoader.scheduleAdsLoading(getActivity().getApplicationContext(), query);
}
runSearch();
}
@ -188,6 +233,10 @@ public class SearchFragment extends BaseMwmFragment
@Nullable
private HotelsFilter mInitialHotelsFilter;
private boolean mIsHotel;
@NonNull
private SearchResult[] mSearchResults = new SearchResult[0];
private final LocationListener mLocationListener = new LocationListener.Simple()
{
@Override
@ -299,6 +348,20 @@ public class SearchFragment extends BaseMwmFragment
super.onViewCreated(view, savedInstanceState);
readArguments();
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;
}
});
}
ViewGroup root = (ViewGroup) view;
mAppBarLayout = (AppBarLayout) root.findViewById(R.id.app_bar);
mToolbarLayout = (CollapsingToolbarLayout) mAppBarLayout.findViewById(R.id.collapsing_toolbar);
@ -398,7 +461,6 @@ public class SearchFragment extends BaseMwmFragment
mFilterController.onSaveState(outState);
}
public void onResume()
{
super.onResume();
@ -425,6 +487,14 @@ public class SearchFragment extends BaseMwmFragment
super.onDestroy();
}
@Override
public void onDestroyView()
{
if (mAdsLoader != null)
mAdsLoader.detach();
super.onDestroyView();
}
private String getQuery()
{
return mToolbarController.getQuery();
@ -524,6 +594,12 @@ public class SearchFragment extends BaseMwmFragment
}
private void onSearchEnd()
{
if (mSearchRunning && isAdded())
updateSearchView();
}
private void updateSearchView()
{
mSearchRunning = false;
mToolbarController.showProgress(false);
@ -535,7 +611,13 @@ public class SearchFragment extends BaseMwmFragment
{
SearchEngine.cancelApiCall();
SearchEngine.cancelAllSearches();
onSearchEnd();
updateSearchView();
}
private boolean isInteractiveSearch()
{
// TODO @yunitsky Implement more elegant solution.
return getActivity() instanceof MwmActivity;
}
private void runSearch()
@ -545,8 +627,7 @@ public class SearchFragment extends BaseMwmFragment
hotelsFilter = mFilterController.getFilter();
mLastQueryTimestamp = System.nanoTime();
// TODO @yunitsky Implement more elegant solution.
if (getActivity() instanceof MwmActivity)
if (isInteractiveSearch())
{
SearchEngine.searchInteractive(
getQuery(), mLastQueryTimestamp, true /* isMapAndTable */, hotelsFilter);
@ -572,19 +653,32 @@ public class SearchFragment extends BaseMwmFragment
if (!isAdded() || !mToolbarController.hasQuery())
return;
// Search is running hence results updated.
mSearchRunning = true;
updateFrames();
mSearchAdapter.refreshData(results);
mToolbarController.showProgress(true);
updateFilterButton(isHotel);
mSearchResults = results;
mIsHotel = isHotel;
if (mAdsRequested)
{
UiThread.cancelDelayedTasks(mResultsShowingTask);
UiThread.runLater(mResultsShowingTask, RESULTS_DELAY_MS);
}
else
{
refreshSearchResults();
}
}
@Override
public void onResultsEnd(long timestamp)
{
if (mSearchRunning && isAdded())
if (mAdsRequested)
{
UiThread.cancelDelayedTasks(mSearchEndTask);
UiThread.runLater(mSearchEndTask, RESULTS_DELAY_MS);
}
else
{
onSearchEnd();
}
}
@Override
@ -606,6 +700,38 @@ public class SearchFragment extends BaseMwmFragment
}
}
private void refreshSearchResults()
{
// Search is running hence results updated.
stopAdsLoading();
mSearchRunning = true;
updateFrames();
mSearchAdapter.refreshData(combineResultsWithAds());
mToolbarController.showProgress(true);
updateFilterButton(mIsHotel);
}
@NonNull
private SearchData[] combineResultsWithAds()
{
if (mSearchResults.length < AD_POSITION || mGoogleAdView == null)
return mSearchResults;
List<SearchData> result = new LinkedList<>();
int counter = 0;
for (SearchResult r : mSearchResults)
{
if (r.type != SearchResultTypes.TYPE_SUGGEST && counter++ == AD_POSITION)
result.add(new GoogleAdsBanner(mGoogleAdView));
else
result.add(r);
}
SearchData[] resultArray = new SearchData[result.size()];
result.toArray(resultArray);
return resultArray;
}
private void updateFilterButton(boolean isHotel)
{
if (mFilterController != null)
@ -666,4 +792,13 @@ public class SearchFragment extends BaseMwmFragment
{
return mToolbarController;
}
private void stopAdsLoading()
{
if (mAdsLoader == null)
return;
mAdsLoader.cancelAdsLoading();
mAdsRequested = false;
}
}

View file

@ -1,15 +1,15 @@
package com.mapswithme.maps.search;
import static com.mapswithme.maps.search.SearchResultTypes.TYPE_LOCAL_ADS_CUSTOMER;
import static com.mapswithme.maps.search.SearchResultTypes.TYPE_RESULT;
import static com.mapswithme.maps.search.SearchResultTypes.TYPE_SUGGEST;
/**
* Class instances are created from native code.
*/
@SuppressWarnings("unused")
public class SearchResult
public class SearchResult implements SearchData
{
public static final int TYPE_SUGGEST = 0;
public static final int TYPE_RESULT = 1;
public static final int TYPE_LOCAL_ADS_CUSTOMER = 2;
// Values should match osm::YesNoUnknown enum.
public static final int OPEN_NOW_UNKNOWN = 0;
public static final int OPEN_NOW_YES = 1;
@ -78,4 +78,10 @@ public class SearchResult
this.description = description;
this.highlightRanges = highlightRanges;
}
@Override
public int getItemViewType()
{
return type;
}
}

View file

@ -0,0 +1,9 @@
package com.mapswithme.maps.search;
class SearchResultTypes
{
static final int TYPE_SUGGEST = 0;
static final int TYPE_RESULT = 1;
static final int TYPE_LOCAL_ADS_CUSTOMER = 2;
static final int TYPE_GOOGLE_ADS = 3;
}