[android] Implemented guides gallery adapter, only default state with stubs

This commit is contained in:
Александр Зацепин 2020-04-27 20:05:37 +03:00 committed by yoksnod
parent 8e923cf300
commit b811e9481e
13 changed files with 216 additions and 68 deletions

View file

@ -2,7 +2,7 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_width="@dimen/guide_gallery_item_width"
android:layout_height="wrap_content"
android:background="?cardBackground"
android:orientation="vertical"
@ -15,6 +15,7 @@
android:id="@+id/image"
android:layout_width="@dimen/nav_street_left"
android:layout_height="@dimen/nav_street_left"
android:layout_centerVertical="true"
app:srcCompat="?guidesPlaceholder" />
<LinearLayout
android:layout_width="match_parent"
@ -29,10 +30,11 @@
android:layout_height="wrap_content"
android:fontFamily="@string/robotoRegular"
android:lines="2"
android:ellipsize="end"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/text_size_body_2"></TextView>
android:textSize="@dimen/text_size_body_2"/>
<TextView
android:id="@+id/description"
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_half"

View file

@ -3,12 +3,19 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/guides_gallery_bottom_sheet"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/red_cross_background"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:orientation="vertical"
android:paddingTop="@dimen/margin_base"
android:paddingBottom="@dimen/margin_quadruple"
app:behavior_defaultState="hidden"
app:behavior_hideable="true"
app:behavior_skipAnchored="true"
app:behavior_skipCollapsed="true"
app:layout_behavior="@string/placepage_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/guides_gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View file

@ -282,19 +282,21 @@
<dimen name="bookmarks_subs_sale_min_width">84dp</dimen>
<dimen name="bookmarks_subs_offer_card_width">164dp</dimen>
<dimen name="bookmarks_subs_card_corner_radius">9dp</dimen>
<!-- Promo-->
<dimen name="promo_after_booking_width">288dp</dimen>
<dimen name="subs_card_min_height">226dp</dimen>
<dimen name="subs_card_min_width">164dp</dimen>
<dimen name="pro_label_margin">52dp</dimen>
<dimen name="promo_single_place_container_height">194dp</dimen>
<dimen name="subscription_view_pager_height">256dp</dimen>
<dimen name="zero">0dp</dimen>
<dimen name="all_pass_top_offset">62dp</dimen>
<dimen name="welcome_btn_min_width">148dp</dimen>
<dimen name="bookmark_all_subscription_content_width">336dp</dimen>
<dimen name="subs_btn_min_width">328dp</dimen>
<dimen name="bookmarks_all_subscription_pager_item_margin">@dimen/margin_base_plus</dimen>
<dimen name="bookmarks_sightseeing_subs_central_content_margin">88dp</dimen>
<dimen name="bookmark_all_subscription_content_width">336dp</dimen>
<dimen name="all_pass_top_offset">62dp</dimen>
<dimen name="subs_card_min_height">226dp</dimen>
<dimen name="subs_card_min_width">164dp</dimen>
<dimen name="subscription_view_pager_height">256dp</dimen>
<!-- Promo-->
<dimen name="promo_after_booking_width">288dp</dimen>
<dimen name="pro_label_margin">52dp</dimen>
<dimen name="promo_single_place_container_height">194dp</dimen>
<dimen name="zero">0dp</dimen>
<dimen name="welcome_btn_min_width">148dp</dimen>
<dimen name="guide_gallery_item_width">328dp</dimen>
</resources>

View file

@ -2665,11 +2665,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
public void onMenuItemClickInternal()
{
Statistics.INSTANCE.trackToolbarClick(getItem());
if (getActivity().closePlacePage())
return;
if (getActivity().closeSidePanel())
return;
getActivity().closePlacePage();
getActivity().closeSidePanel();
getActivity().mMainMenuController.open();
}
}

View file

@ -15,14 +15,15 @@ public class GalleryAdapter<VH extends Holders.BaseViewHolder<I>, I extends Item
mStrategy = strategy;
}
@NonNull
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType)
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
return mStrategy.createViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(VH holder, int position)
public void onBindViewHolder(@NonNull VH holder, int position)
{
mStrategy.onBindViewHolder(holder, position);
}

View file

@ -6,12 +6,6 @@ import android.graphics.Bitmap;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.net.Uri;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import androidx.recyclerview.widget.RecyclerView;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.view.View;
@ -19,10 +13,17 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.BitmapImageViewTarget;
import com.mapswithme.HotelUtils;
import com.mapswithme.maps.R;
import com.mapswithme.maps.guides.GuidesGallery;
import com.mapswithme.maps.promo.PromoCityGallery;
import com.mapswithme.maps.promo.PromoEntity;
import com.mapswithme.maps.search.Popularity;
@ -31,6 +32,7 @@ import com.mapswithme.maps.ugc.UGC;
import com.mapswithme.maps.widget.RatingView;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.NetworkPolicy;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
@ -424,6 +426,7 @@ public class Holders
}
}
public static class CatalogPromoHolder extends BaseViewHolder<PromoEntity>
{
@NonNull
@ -547,4 +550,37 @@ public class Holders
listener.onItemSelected(item, position);
}
}
public static class GuideHodler extends BaseViewHolder<GuidesGallery.Item>
{
@NonNull
private final ImageView mImage;
@NonNull
private final TextView mSubtitle;
// TODO: handle city and outdoor content properly.
/* @NonNull
private final View mCityContent;
@NonNull
private final View mOutdoorContent;*/
public GuideHodler(@NonNull View itemView, @NonNull List<GuidesGallery.Item> items, @Nullable ItemSelectedListener<GuidesGallery.Item> listener)
{
super(itemView, items, listener);
mImage = itemView.findViewById(R.id.image);
mSubtitle = itemView.findViewById(R.id.subtitle);
}
@Override
public void bind(@NonNull GuidesGallery.Item item)
{
super.bind(item);
Glide.with(mImage.getContext())
.load(item.getImageUrl())
.asBitmap()
.placeholder(ThemeUtils.getResource(mImage.getContext(), R.attr.guidesPlaceholder))
.centerCrop()
.into(mImage);
mSubtitle.setText(item.getSubtitle());
// TODO: another fields comming soon;
}
}
}

View file

@ -1,5 +1,8 @@
package com.mapswithme.maps.gallery;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -160,7 +163,7 @@ public class Items
}
}
public static class Item
public static class Item implements Parcelable
{
@NonNull
private final String mTitle;
@ -177,6 +180,28 @@ public class Items
mSubtitle = subtitle;
}
protected Item(Parcel in)
{
mTitle = in.readString();
mUrl = in.readString();
mSubtitle = in.readString();
}
public static final Creator<Item> CREATOR = new Creator<Item>()
{
@Override
public Item createFromParcel(Parcel in)
{
return new Item(in);
}
@Override
public Item[] newArray(int size)
{
return new Item[size];
}
};
@NonNull
public String getTitle()
{
@ -194,5 +219,19 @@ public class Items
{
return mUrl;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(mTitle);
dest.writeString(mUrl);
dest.writeString(mSubtitle);
}
}
}

View file

@ -2,6 +2,9 @@ package com.mapswithme.maps.gallery;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.ViewGroup;
import java.util.List;
@ -82,6 +85,19 @@ public abstract class RegularAdapterStrategy<T extends RegularAdapterStrategy.It
mType = type;
}
protected Item(Parcel in)
{
super(in);
mType = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeInt(mType);
}
public int getType()
{
return mType;

View file

@ -10,6 +10,7 @@ import com.mapswithme.maps.gallery.Constants;
import com.mapswithme.maps.gallery.GalleryAdapter;
import com.mapswithme.maps.gallery.ItemSelectedListener;
import com.mapswithme.maps.gallery.Items;
import com.mapswithme.maps.guides.GuidesGallery;
import com.mapswithme.maps.promo.PromoCityGallery;
import com.mapswithme.maps.promo.PromoEntity;
import com.mapswithme.maps.search.SearchResult;
@ -104,6 +105,17 @@ public class Factory
return new GalleryAdapter<>(strategy);
}
@NonNull
public static GalleryAdapter createGuidesAdapter(
@NonNull List<GuidesGallery.Item> items, @Nullable ItemSelectedListener<GuidesGallery.Item> listener,
@NonNull GalleryPlacement placement)
{
GuidesAdapterStrategy strategy = new GuidesAdapterStrategy(items, listener);
//noinspection ConstantConditions
trackProductGalleryShownOrError(items.toArray(), GalleryType.PROMO, ONLINE, placement);
return new GalleryAdapter<>(strategy);
}
@NonNull
public static GalleryAdapter createCatalogPromoLoadingAdapter()
{

View file

@ -0,0 +1,42 @@
package com.mapswithme.maps.gallery.impl;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mapswithme.maps.R;
import com.mapswithme.maps.gallery.Holders;
import com.mapswithme.maps.gallery.ItemSelectedListener;
import com.mapswithme.maps.gallery.RegularAdapterStrategy;
import com.mapswithme.maps.guides.GuidesGallery;
import java.util.List;
public class GuidesAdapterStrategy extends RegularAdapterStrategy<GuidesGallery.Item>
{
GuidesAdapterStrategy(@NonNull List<GuidesGallery.Item> items,
@Nullable ItemSelectedListener<GuidesGallery.Item> listener)
{
super(items, null, listener, Integer.MAX_VALUE);
}
@NonNull
@Override
protected Holders.BaseViewHolder<GuidesGallery.Item> createProductViewHolder(
@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.guides_discovery_item, parent, false);
return new Holders.GuideHodler(view, mItems, getListener());
}
@NonNull
@Override
protected Holders.BaseViewHolder<GuidesGallery.Item> createMoreProductsViewHolder(
@NonNull ViewGroup parent, int viewType)
{
throw new UnsupportedOperationException("Guides adapter doesn't support more item!");
}
}

View file

@ -5,6 +5,8 @@ import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mapswithme.maps.gallery.Constants;
import com.mapswithme.maps.gallery.RegularAdapterStrategy;
import com.mapswithme.maps.widget.placepage.PlacePageData;
import java.util.ArrayList;
@ -64,19 +66,13 @@ public class GuidesGallery implements PlacePageData
}
};
public static class Item implements Parcelable
public static class Item extends RegularAdapterStrategy.Item
{
@NonNull
private final String mGuideId;
@NonNull
private final String mUrl;
@NonNull
private final String mImageUrl;
@NonNull
private final String mTitle;
@NonNull
private final String mSubTitle;
@NonNull
private final Type mType;
private final boolean mDownloaded;
@Nullable
@ -89,11 +85,9 @@ public class GuidesGallery implements PlacePageData
boolean downloaded, @Nullable CityParams cityParams,
@Nullable OutdoorParams outdoorParams)
{
super(Constants.TYPE_PRODUCT, title, subTitle, url);
mGuideId = guideId;
mUrl = url;
mImageUrl = imageUrl;
mTitle = title;
mSubTitle = subTitle;
mType = Type.values()[type];
mDownloaded = downloaded;
mCityParams = cityParams;
@ -102,11 +96,9 @@ public class GuidesGallery implements PlacePageData
protected Item(Parcel in)
{
super(in);
mGuideId = in.readString();
mUrl = in.readString();
mImageUrl = in.readString();
mTitle = in.readString();
mSubTitle = in.readString();
mType = Type.values()[in.readInt()];
mDownloaded = in.readByte() != 0;
mCityParams = in.readParcelable(CityParams.class.getClassLoader());
@ -134,11 +126,6 @@ public class GuidesGallery implements PlacePageData
return mGuideId;
}
@NonNull
public String getUrl()
{
return mUrl;
}
@NonNull
public String getImageUrl()
@ -147,19 +134,7 @@ public class GuidesGallery implements PlacePageData
}
@NonNull
public String getTitle()
{
return mTitle;
}
@NonNull
public String getSubTitle()
{
return mSubTitle;
}
@NonNull
public Type getType()
public Type getGuideType()
{
return mType;
}
@ -190,11 +165,9 @@ public class GuidesGallery implements PlacePageData
@Override
public void writeToParcel(Parcel dest, int flags)
{
super.writeToParcel(dest, flags);
dest.writeString(mGuideId);
dest.writeString(mUrl);
dest.writeString(mImageUrl);
dest.writeString(mTitle);
dest.writeString(mSubTitle);
dest.writeInt(mType.ordinal());
dest.writeByte((byte) (mDownloaded ? 1 : 0));
dest.writeParcelable(mCityParams, flags);

View file

@ -5,18 +5,31 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.gallery.impl.Factory;
import com.mapswithme.maps.guides.GuidesGallery;
import com.mapswithme.maps.widget.recycler.ItemDecoratorFactory;
import com.mapswithme.util.statistics.GalleryPlacement;
import java.util.Objects;
public class GuidesGalleryViewRenderer implements PlacePageViewRenderer<PlacePageData>,
PlacePageStateObserver
{
@Nullable
private GuidesGallery mGallery;
@SuppressWarnings("NullableProblems")
@NonNull
private RecyclerView mRecyclerView;
@Override
public void render(@NonNull PlacePageData data)
{
mGallery = (GuidesGallery) data;
mRecyclerView.setAdapter(Factory.createGuidesAdapter(mGallery.getItems(), null,
GalleryPlacement.MAP));
}
@Override
@ -28,7 +41,14 @@ public class GuidesGalleryViewRenderer implements PlacePageViewRenderer<PlacePag
@Override
public void initialize(@Nullable View view)
{
Objects.requireNonNull(view);
mRecyclerView = view.findViewById(R.id.guides_gallery);
mRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext(),
LinearLayoutManager.HORIZONTAL, false));
// TODO: implement new item decoration.
mRecyclerView.addItemDecoration(
ItemDecoratorFactory.createSponsoredGalleryDecorator(view.getContext(),
LinearLayoutManager.HORIZONTAL));
}
@Override

View file

@ -6,5 +6,6 @@ public enum GalleryPlacement
DISCOVERY,
PLACEPAGE_LARGE_TOPONYMS,
PLACEPAGE_SIGHTSEEINGS,
PLACEPAGE_OUTDOOR
PLACEPAGE_OUTDOOR,
MAP
}