diff options
author | Александр Зацепин <az@mapswithme.com> | 2018-10-17 17:41:40 +0300 |
---|---|---|
committer | Roman Kuznetsov <r.kuznetsow@gmail.com> | 2018-10-18 13:44:48 +0300 |
commit | b51b58fd8ec7a0f645973883c0538ec9f5be1473 (patch) | |
tree | 30250747b78f1a926b5e43bd543b63678b0767e4 /android | |
parent | aa5c95c5ef8306aa80f1c699cb43852c018982a2 (diff) |
[android] Customized the promo category for search to make it reusable for different promo actions and providers
Diffstat (limited to 'android')
9 files changed, 186 insertions, 79 deletions
diff --git a/android/res/drawable-mdpi/ic_category_taxi.png b/android/res/drawable-mdpi/ic_category_taxi.png Binary files differnew file mode 100644 index 0000000000..2a2d86e7d9 --- /dev/null +++ b/android/res/drawable-mdpi/ic_category_taxi.png diff --git a/android/src/com/mapswithme/maps/search/CategoriesAdapter.java b/android/src/com/mapswithme/maps/search/CategoriesAdapter.java index 96713460e1..af0793efdb 100644 --- a/android/src/com/mapswithme/maps/search/CategoriesAdapter.java +++ b/android/src/com/mapswithme/maps/search/CategoriesAdapter.java @@ -2,6 +2,7 @@ package com.mapswithme.maps.search; import android.content.res.Resources; import android.support.annotation.DrawableRes; +import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; @@ -16,8 +17,17 @@ import com.mapswithme.maps.R; import com.mapswithme.util.ThemeUtils; import com.mapswithme.util.statistics.Statistics; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolder> { + @Retention(RetentionPolicy.SOURCE) + @IntDef({ TYPE_CATEGORY, TYPE_PROMO_CATEGORY }) + @interface ViewType {} + private static final int TYPE_CATEGORY = 0; + private static final int TYPE_PROMO_CATEGORY = 1; + @StringRes private final int mCategoryResIds[]; @DrawableRes @@ -28,18 +38,19 @@ class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolde interface OnCategorySelectedListener { - void onCategorySelected(@Nullable String category); + void onSearchCategorySelected(@Nullable String category); + void onPromoCategorySelected(@NonNull PromoCategory promo); } private OnCategorySelectedListener mListener; - CategoriesAdapter(Fragment fragment) + CategoriesAdapter(@NonNull Fragment fragment) { final String packageName = fragment.getActivity().getPackageName(); final boolean isNightTheme = ThemeUtils.isNightTheme(); final Resources resources = fragment.getActivity().getResources(); - final String[] keys = DisplayedCategories.getKeys(); + final String[] keys = getAllCategories(); final int numKeys = keys.length; mCategoryResIds = new int[numKeys]; @@ -47,16 +58,7 @@ class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolde for (int i = 0; i < numKeys; i++) { String key = keys[i]; - mCategoryResIds[i] = resources.getIdentifier(key, "string", packageName); - PromoCategory promo = PromoCategory.findByKey(key); - if (promo != null) - { - Statistics.INSTANCE.trackSponsoredEventForCustomProvider( - Statistics.EventName.SEARCH_SPONSOR_CATEGORY_SHOWN, - promo.getStatisticValue()); - mCategoryResIds[i] = promo.getStringId(); - } if (mCategoryResIds[i] == 0) throw new IllegalStateException("Can't get string resource id for category:" + key); @@ -75,24 +77,58 @@ class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolde mInflater = LayoutInflater.from(fragment.getActivity()); } + @NonNull + private static String[] getAllCategories() + { + String[] searchCategories = DisplayedCategories.getKeys(); + PromoCategory[] promos = PromoCategory.values(); + int amountSize = searchCategories.length + promos.length; + String[] allCategories = new String[amountSize]; + for (PromoCategory promo : promos) + { + if (promo.getPosition() >= amountSize) + throw new AssertionError("Promo position must in range: " + + "[0 - " + amountSize + ")"); + + allCategories[promo.getPosition()] = promo.getKey(); + } + + for (int i = 0, j = 0; i < amountSize; i++) + { + if (allCategories[i] == null) + { + allCategories[i] = searchCategories[j]; + j++; + } + } + + return allCategories; + } + @Override + @ViewType public int getItemViewType(int position) { - return R.layout.item_search_category; + PromoCategory promo = PromoCategory.findByStringId(mCategoryResIds[position]); + if (promo != null) + return TYPE_PROMO_CATEGORY; + return TYPE_CATEGORY; } @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) + public ViewHolder onCreateViewHolder(ViewGroup parent, @ViewType int viewType) { final View view; - if (viewType == R.layout.item_search_category_luggage) + view = mInflater.inflate(R.layout.item_search_category, parent, false); + switch (viewType) { - view = mInflater.inflate(R.layout.item_search_category_luggage, parent, false); - return new ViewHolder(view, (TextView) view.findViewById(R.id.tv__category)); + case TYPE_CATEGORY: + return new ViewHolder(view, (TextView) view); + case TYPE_PROMO_CATEGORY: + return new PromoViewHolder(view, (TextView) view); + default: + throw new AssertionError("Unsupported type detected: " + viewType); } - - view = mInflater.inflate(R.layout.item_search_category, parent, false); - return new ViewHolder(view, (TextView)view); } @Override @@ -107,16 +143,44 @@ class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolde return mCategoryResIds.length; } - @NonNull - private String getSuggestionFromCategory(@StringRes int resId) + private class PromoViewHolder extends ViewHolder { - PromoCategory promoCategory = PromoCategory.findByStringId(resId); - if (promoCategory != null) - return promoCategory.getKey(); - return mResources.getString(resId) + ' '; + PromoViewHolder(@NonNull View v, @NonNull TextView tv) + { + super(v, tv); + } + + @Override + void onItemClicked(int position) + { + @StringRes + int categoryId = mCategoryResIds[position]; + PromoCategory promo = PromoCategory.findByStringId(categoryId); + if (promo != null) + { + String event = Statistics.EventName.SEARCH_SPONSOR_CATEGORY_SELECTED; + Statistics.INSTANCE.trackSearchPromoCategory(event, promo.getProvider()); + if (mListener != null) + mListener.onPromoCategorySelected(promo); + } + } + + @Override + void setTextAndIcon(int textResId, int iconResId) + { + super.setTextAndIcon(textResId, iconResId); + @StringRes + int categoryId = mCategoryResIds[getAdapterPosition()]; + PromoCategory promo = PromoCategory.findByStringId(categoryId); + if (promo != null) + { + String event = Statistics.EventName.SEARCH_SPONSOR_CATEGORY_SHOWN; + Statistics.INSTANCE.trackSearchPromoCategory(event, promo.getProvider()); + } + } } - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener + class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { @NonNull private final TextView mTitle; @@ -129,12 +193,22 @@ class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolde } @Override - public void onClick(View v) + public final void onClick(View v) { final int position = getAdapterPosition(); - Statistics.INSTANCE.trackSearchCategoryClicked(mResources.getResourceEntryName(mCategoryResIds[position])); + onItemClicked(position); + } + + void onItemClicked(int position) + { + String categoryEntryName = mResources.getResourceEntryName(mCategoryResIds[position]); + Statistics.INSTANCE.trackSearchCategoryClicked(categoryEntryName); if (mListener != null) - mListener.onCategorySelected(getSuggestionFromCategory(mCategoryResIds[position])); + { + @StringRes + int categoryId = mCategoryResIds[position]; + mListener.onSearchCategorySelected(mResources.getString(categoryId) + " "); + } } void setTextAndIcon(@StringRes int textResId, @DrawableRes int iconResId) diff --git a/android/src/com/mapswithme/maps/search/DisplayedCategories.java b/android/src/com/mapswithme/maps/search/DisplayedCategories.java index c5629510a2..418947e457 100644 --- a/android/src/com/mapswithme/maps/search/DisplayedCategories.java +++ b/android/src/com/mapswithme/maps/search/DisplayedCategories.java @@ -1,8 +1,15 @@ package com.mapswithme.maps.search; +import android.support.annotation.NonNull; + class DisplayedCategories { - public static String[] getKeys() { return nativeGetKeys(); } + @NonNull + public static String[] getKeys() + { + return nativeGetKeys(); + } + @NonNull private static native String[] nativeGetKeys(); } diff --git a/android/src/com/mapswithme/maps/search/PromoCategory.java b/android/src/com/mapswithme/maps/search/PromoCategory.java index c51cc4eff5..87a65992ce 100644 --- a/android/src/com/mapswithme/maps/search/PromoCategory.java +++ b/android/src/com/mapswithme/maps/search/PromoCategory.java @@ -1,34 +1,47 @@ package com.mapswithme.maps.search; +import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; -import android.text.TextUtils; -import com.mapswithme.util.UiUtils; +import com.mapswithme.maps.R; public enum PromoCategory { - STUB + RUTAXI { @NonNull @Override String getKey() { - return ""; + return "taxi"; } @Override int getStringId() { - return UiUtils.NO_ID; + return R.string.taxi; } @NonNull @Override - String getStatisticValue() + String getProvider() { - return ""; + return "RuTaxi"; + } + + @Override + int getPosition() + { + return 4; + } + + @NonNull + @Override + PromoCategoryProcessor createProcessor(@NonNull Context context) + { + return new RutaxiPromoProcessor(context); } }; @@ -39,7 +52,12 @@ public enum PromoCategory abstract int getStringId(); @NonNull - abstract String getStatisticValue(); + abstract String getProvider(); + + abstract int getPosition(); + + @NonNull + abstract PromoCategoryProcessor createProcessor(@NonNull Context context); @Nullable static PromoCategory findByStringId(@StringRes int nameId) @@ -51,18 +69,4 @@ public enum PromoCategory } return null; } - - @Nullable - static PromoCategory findByKey(@Nullable String key) - { - if (TextUtils.isEmpty(key)) - return null; - - for (PromoCategory cat : values()) - { - if (cat.getKey().equals(key)) - return cat; - } - return null; - } } diff --git a/android/src/com/mapswithme/maps/search/PromoCategoryProcessor.java b/android/src/com/mapswithme/maps/search/PromoCategoryProcessor.java new file mode 100644 index 0000000000..61cdbdfa23 --- /dev/null +++ b/android/src/com/mapswithme/maps/search/PromoCategoryProcessor.java @@ -0,0 +1,6 @@ +package com.mapswithme.maps.search; + +public interface PromoCategoryProcessor +{ + void process(); +} diff --git a/android/src/com/mapswithme/maps/search/RutaxiPromoProcessor.java b/android/src/com/mapswithme/maps/search/RutaxiPromoProcessor.java new file mode 100644 index 0000000000..1c76457eca --- /dev/null +++ b/android/src/com/mapswithme/maps/search/RutaxiPromoProcessor.java @@ -0,0 +1,24 @@ +package com.mapswithme.maps.search; + +import android.content.Context; +import android.support.annotation.NonNull; + +import com.mapswithme.util.Utils; + +public class RutaxiPromoProcessor implements PromoCategoryProcessor +{ + @NonNull + private final Context mContext; + + RutaxiPromoProcessor(@NonNull Context context) + { + mContext = context; + } + + @Override + public void process() + { + // TODO: added app launch when product desicion is ready. + Utils.openUrl(mContext, "https://go.onelink.me/757212956/a81b5d7c"); + } +} diff --git a/android/src/com/mapswithme/maps/search/SearchCategoriesFragment.java b/android/src/com/mapswithme/maps/search/SearchCategoriesFragment.java index 177441bc8a..563deab406 100644 --- a/android/src/com/mapswithme/maps/search/SearchCategoriesFragment.java +++ b/android/src/com/mapswithme/maps/search/SearchCategoriesFragment.java @@ -3,7 +3,6 @@ package com.mapswithme.maps.search; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; import com.mapswithme.maps.R; import com.mapswithme.maps.base.BaseMwmRecyclerFragment; @@ -31,18 +30,25 @@ public class SearchCategoriesFragment extends BaseMwmRecyclerFragment<Categories } @Override - public void onCategorySelected(String category) + public void onSearchCategorySelected(String category) { if (!passCategory(getParentFragment(), category)) passCategory(getActivity(), category); } + @Override + public void onPromoCategorySelected(@NonNull PromoCategory promo) + { + PromoCategoryProcessor processor = promo.createProcessor(getContext().getApplicationContext()); + processor.process(); + } + private static boolean passCategory(Object listener, String category) { if (!(listener instanceof CategoriesAdapter.OnCategorySelectedListener)) return false; - ((CategoriesAdapter.OnCategorySelectedListener)listener).onCategorySelected(category); + ((CategoriesAdapter.OnCategorySelectedListener)listener).onSearchCategorySelected(category); return true; } } diff --git a/android/src/com/mapswithme/maps/search/SearchFragment.java b/android/src/com/mapswithme/maps/search/SearchFragment.java index c0118f9702..2fe57c231b 100644 --- a/android/src/com/mapswithme/maps/search/SearchFragment.java +++ b/android/src/com/mapswithme/maps/search/SearchFragment.java @@ -129,9 +129,6 @@ public class SearchFragment extends BaseMwmFragment return; } - if (mPromoCategorySelected) - return; - if (mAdsLoader != null && !isTabletSearch() && query.length() >= MIN_QUERY_LENGTH_FOR_AD) { mAdsRequested = true; @@ -211,7 +208,6 @@ public class SearchFragment extends BaseMwmFragment private final LastPosition mLastPosition = new LastPosition(); private boolean mSearchRunning; - private boolean mPromoCategorySelected; private String mInitialQuery; @Nullable private String mInitialLocale; @@ -710,24 +706,15 @@ public class SearchFragment extends BaseMwmFragment } @Override - public void onCategorySelected(@Nullable String category) + public void onSearchCategorySelected(@Nullable String category) { - PromoCategory promoCategory = PromoCategory.findByKey(category); - if (promoCategory != null) - { - mPromoCategorySelected = true; - mToolbarController.setQuery(category + " "); + mToolbarController.setQuery(category); + } - Statistics.INSTANCE.trackSponsoredEventForCustomProvider( - Statistics.EventName.SEARCH_SPONSOR_CATEGORY_SELECTED, - promoCategory.getStatisticValue()); - showAllResultsOnMap(); - mPromoCategorySelected = false; - } - else - { - mToolbarController.setQuery(category); - } + @Override + public void onPromoCategorySelected(@NonNull PromoCategory promo) + { + // Do nothing by default. } private void refreshSearchResults() diff --git a/android/src/com/mapswithme/util/statistics/Statistics.java b/android/src/com/mapswithme/util/statistics/Statistics.java index 98cf05bab7..bebb0669b8 100644 --- a/android/src/com/mapswithme/util/statistics/Statistics.java +++ b/android/src/com/mapswithme/util/statistics/Statistics.java @@ -16,12 +16,12 @@ import com.android.billingclient.api.BillingClient; import com.facebook.ads.AdError; import com.facebook.appevents.AppEventsLogger; import com.mapswithme.maps.BuildConfig; -import com.mapswithme.maps.analytics.ExternalLibrariesMediator; import com.mapswithme.maps.Framework; import com.mapswithme.maps.MwmApplication; import com.mapswithme.maps.PrivateVariables; import com.mapswithme.maps.ads.MwmNativeAd; import com.mapswithme.maps.ads.NativeAdError; +import com.mapswithme.maps.analytics.ExternalLibrariesMediator; import com.mapswithme.maps.api.ParsedMwmRequest; import com.mapswithme.maps.bookmarks.data.BookmarkManager; import com.mapswithme.maps.bookmarks.data.MapObject; @@ -955,8 +955,7 @@ public enum Statistics .get()); } - public void trackSponsoredEventForCustomProvider(@NonNull String eventName, - @NonNull String provider) + public void trackSearchPromoCategory(@NonNull String eventName, @NonNull String provider) { trackEvent(eventName, Statistics.params().add(PROVIDER, provider).get()); MyTracker.trackEvent(eventName + "_" + provider); |