[android] Added All pass premium screen

This commit is contained in:
Dmitry Donskoy 2019-10-28 11:25:27 +03:00 committed by Aleksandr Zatsepin
parent c4679f38ab
commit 9fc2a9ff2d
21 changed files with 389 additions and 27 deletions

View file

@ -467,6 +467,10 @@
android:name="com.mapswithme.maps.purchase.BookmarkSubscriptionActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenLayout|screenSize|keyboardHidden"/>
<activity
android:name="com.mapswithme.maps.purchase.AllPassPremiumActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenLayout|screenSize|keyboardHidden"/>
<activity
android:name="com.mapswithme.maps.purchase.SightseeingSubscriptionActivity"
android:screenOrientation="portrait"

View file

@ -153,13 +153,18 @@ configurations.all {
force 'androidx.arch.core:core-common:2.0.0-rc01'
force 'androidx.arch.core:core-runtime:2.0.0-rc01'
force 'androidx.lifecycle:lifecycle-livedata-core:2.0.0-rc01'
force "org.jetbrains.kotlin:kotlin-stdlib:1.3.31"
force "com.google.code.gson:gson:2.8.5"
failOnVersionConflict();
}
}
android {
// All properties are read from gradle.properties file
dataBinding {
enabled = true
}
compileSdkVersion propCompileSdkVersion.toInteger()
defaultConfig {

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="4dp"
android:height="4dp"/>
<solid android:color="@color/white_primary"/>
</shape>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="4dp"
android:height="4dp"/>
<solid android:color="@color/white_lightest"/>
</shape>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="model"
type="com.mapswithme.maps.purchase.AllPassSubscriptionType"/>
</data>
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:ellipsize="end"
android:maxLines="2"
android:fontFamily="@string/robotoMedium"
android:textSize="@dimen/text_size_display_0"
android:text="@{model.titleId}"
android:textColor="@color/white_primary"
android:layout_marginEnd="@dimen/margin_base_plus_quarter"
android:layout_marginRight="@dimen/margin_base_plus_quarter"
android:layout_marginLeft="@dimen/margin_base_plus_quarter"
android:layout_marginStart="@dimen/margin_base_plus_quarter"
tools:ignore="UnusedAttribute"/>
<TextView
android:id="@+id/description"
android:layout_below="@id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLines="2"
android:ellipsize="end"
android:fontFamily="@string/robotoRegular"
android:textColor="@color/white_primary"
android:textSize="@dimen/text_size_body_0"
android:text="@{model.descriptionId}"
android:layout_marginTop="@dimen/margin_half_plus"
android:layout_marginEnd="@dimen/margin_base_plus_quarter"
android:layout_marginRight="@dimen/margin_base_plus_quarter"
android:layout_marginLeft="@dimen/margin_base_plus_quarter"
android:layout_marginStart="@dimen/margin_base_plus_quarter"
tools:ignore="UnusedAttribute"/>
</RelativeLayout>
</layout>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<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_height="match_parent">
<ImageView
android:id="@+id/img1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/img1"/>
<ImageView
android:id="@+id/img2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/img2"/>
<ImageView
android:id="@+id/img3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/img3"/>
<LinearLayout
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/status_bar_placeholder"
android:layout_width="match_parent"
android:background="@android:color/transparent"
android:layout_height="wrap_content"/>
<com.mapswithme.maps.widget.ParallaxBackgroundViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="@dimen/subscription_view_pager_height"
app:autoScroll="true"
app:scrollPeriod="4000"/>
<LinearLayout
android:id="@+id/bottom_container"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:id="@+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/margin_base_plus"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -277,4 +277,5 @@
<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">144dp</dimen>
</resources>

View file

@ -6,6 +6,7 @@
<!-- we use slightly greater font sizes, then in default material styles -->
<dimen name="text_size_display_2">40sp</dimen>
<dimen name="text_size_display_1">36sp</dimen>
<dimen name="text_size_display_0">34sp</dimen>
<dimen name="text_size_headline">28sp</dimen>
<dimen name="text_size_title">24sp</dimen>
<dimen name="text_size_toolbar">20sp</dimen>

View file

@ -0,0 +1,14 @@
package com.mapswithme.maps.purchase;
import android.support.v4.app.Fragment;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
public class AllPassPremiumActivity extends BaseMwmFragmentActivity
{
@Override
protected Class<? extends Fragment> getFragmentClass()
{
return AllPassPremiumPagerFragment.class;
}
}

View file

@ -0,0 +1,49 @@
package com.mapswithme.maps.purchase;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.R;
import com.mapswithme.maps.databinding.FragmentAllPassPremiumBinding;
import java.util.Objects;
public class AllPassPremiumFragment extends Fragment
{
private static final String BUNDLE_INDEX = "index";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
int index = Objects.requireNonNull(getArguments()).getInt(BUNDLE_INDEX);
AllPassSubscriptionType type = AllPassSubscriptionType.values()[index];
FragmentAllPassPremiumBinding binding = makeBinding(inflater, container);
binding.setModel(type);
return binding.getRoot();
}
@NonNull
private static FragmentAllPassPremiumBinding makeBinding(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container)
{
return DataBindingUtil.inflate(inflater, R.layout.fragment_all_pass_premium, container, false);
}
@NonNull
public static AllPassPremiumFragment newInstance(int index)
{
AllPassPremiumFragment fragment = new AllPassPremiumFragment();
Bundle args = new Bundle();
args.putInt(BUNDLE_INDEX, index);
fragment.setArguments(args);
return fragment;
}
}

View file

@ -0,0 +1,106 @@
package com.mapswithme.maps.purchase;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.widget.DotPager;
import com.mapswithme.maps.widget.ParallaxBackgroundPageListener;
import com.mapswithme.maps.widget.ParallaxBackgroundViewPager;
import com.mapswithme.util.UiUtils;
import java.util.ArrayList;
import java.util.List;
public class AllPassPremiumPagerFragment extends BaseMwmFragment
{
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
View root = inflater.inflate(R.layout.pager_fragment_all_pass_premium, container, false);
initStatusBarPlaceholder(root);
initViewPager(root);
return root;
}
private void initStatusBarPlaceholder(@NonNull View root)
{
View statusBarPlaceholder = root.findViewById(R.id.status_bar_placeholder);
ViewGroup.LayoutParams params = statusBarPlaceholder.getLayoutParams();
params.height = UiUtils.getStatusBarHeight(requireContext());
statusBarPlaceholder.setLayoutParams(params);
}
private void initViewPager(@NonNull View root)
{
final List<Integer> items = makeItems();
ParallaxBackgroundViewPager viewPager = root.findViewById(R.id.pager);
PagerAdapter adapter = new ParallaxFragmentPagerAdapter(requireFragmentManager(),
items);
DotPager pager = makeDotPager(root.findViewById(R.id.indicator), viewPager, adapter);
pager.show();
ViewPager.OnPageChangeListener listener = new ParallaxBackgroundPageListener(requireActivity(),
viewPager, items);
viewPager.addOnPageChangeListener(listener);
viewPager.startAutoScroll();
}
@NonNull
private DotPager makeDotPager(@NonNull ViewGroup indicatorContainer, @NonNull ViewPager viewPager,
@NonNull PagerAdapter adapter)
{
return new DotPager.Builder(requireContext(), viewPager, adapter)
.setIndicatorContainer(indicatorContainer)
.setActiveDotDrawable(R.drawable.all_pass_marker_active)
.setInactiveDotDrawable(R.drawable.all_pass_marker_inactive)
.build();
}
@NonNull
private static List<Integer> makeItems()
{
List<Integer> items = new ArrayList<>();
items.add(R.id.img3);
items.add(R.id.img2);
items.add(R.id.img1);
return items;
}
private class ParallaxFragmentPagerAdapter extends FragmentPagerAdapter
{
@NonNull
private final List<Integer> mItems;
ParallaxFragmentPagerAdapter(@NonNull FragmentManager fragmentManager,
@NonNull List<Integer> items)
{
super(fragmentManager);
mItems = items;
}
@Override
public Fragment getItem(int i)
{
return AllPassPremiumFragment.newInstance(i);
}
@Override
public int getCount()
{
return mItems.size();
}
}
}

View file

@ -0,0 +1,32 @@
package com.mapswithme.maps.purchase;
import com.mapswithme.maps.R;
public enum AllPassSubscriptionType
{
FIRST(R.string.all_pass_subscription_message_title,
R.string.all_pass_subscription_message_subtitle),
SECOND(R.string.all_pass_subscription_message_title_2,
R.string.all_pass_subscription_message_subtitle_2),
THIRD(R.string.all_pass_subscription_message_title_3,
R.string.all_pass_subscription_message_subtitle_3);
private final int mTitleId;
private final int mDescriptionId;
AllPassSubscriptionType(int titleId, int descriptionId)
{
mTitleId = titleId;
mDescriptionId = descriptionId;
}
public int getTitleId()
{
return mTitleId;
}
public int getDescriptionId()
{
return mDescriptionId;
}
}

View file

@ -46,6 +46,9 @@ public class DotPager implements ViewPager.OnPageChangeListener
private final Context mContext;
@Nullable
private final OnPageChangedListener mListener;
private final int mActiveDotDrawableResId;
private final int mInactiveDotDrawableResId;
private DotPager(@NonNull Builder builder)
{
@ -55,6 +58,8 @@ public class DotPager implements ViewPager.OnPageChangeListener
mIndicator = builder.mIndicatorContainer;
mListener = builder.mListener;
mDots = new ImageView[mAdapter.getCount()];
mActiveDotDrawableResId = builder.mActiveDotDrawableResId;
mInactiveDotDrawableResId = builder.mInactiveDotDrawableResId;
}
public void show()
@ -72,7 +77,6 @@ public class DotPager implements ViewPager.OnPageChangeListener
private void configurePager()
{
mPager.setAdapter(mAdapter);
mPager.clearOnPageChangeListeners();
mPager.addOnPageChangeListener(this);
}
@ -119,7 +123,7 @@ public class DotPager implements ViewPager.OnPageChangeListener
if (ThemeUtils.isNightTheme())
dotDrawable = isCurPage ? R.drawable.news_marker_active_night : R.drawable.news_marker_inactive_night;
else
dotDrawable = isCurPage ? R.drawable.news_marker_active : R.drawable.news_marker_inactive;
dotDrawable = isCurPage ? mActiveDotDrawableResId : mInactiveDotDrawableResId;
mDots[i].setImageResource(dotDrawable);
}
}
@ -148,6 +152,8 @@ public class DotPager implements ViewPager.OnPageChangeListener
private final Context mContext;
@Nullable
private OnPageChangedListener mListener;
private int mActiveDotDrawableResId = R.drawable.news_marker_active;
private int mInactiveDotDrawableResId = R.drawable.news_marker_inactive;
public Builder(@NonNull Context context, @NonNull ViewPager pager, @NonNull PagerAdapter adapter)
{
@ -168,6 +174,18 @@ public class DotPager implements ViewPager.OnPageChangeListener
return this;
}
public Builder setActiveDotDrawable(int resId)
{
mActiveDotDrawableResId = resId;
return this;
}
public Builder setInactiveDotDrawable(int resId)
{
mInactiveDotDrawableResId = resId;
return this;
}
public DotPager build()
{
return new DotPager(this);

View file

@ -8,7 +8,6 @@ import androidx.viewpager.widget.ViewPager;
import android.view.View;
import java.util.NoSuchElementException;
import java.util.Objects;
public class FragmentPageViewProvider implements PageViewProvider
{
@ -40,7 +39,7 @@ public class FragmentPageViewProvider implements PageViewProvider
}
}
@NonNull
@Nullable
@Override
public View findViewByIndex(int index)
{
@ -49,7 +48,7 @@ public class FragmentPageViewProvider implements PageViewProvider
if (page == null)
throw new NoSuchElementException("No such element for tag : " + tag);
return Objects.requireNonNull(page.getView());
return page.getView();
}
private int getId()

View file

@ -1,10 +1,11 @@
package com.mapswithme.maps.widget;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View;
interface PageViewProvider
{
@NonNull
@Nullable
View findViewByIndex(int index);
}

View file

@ -2,12 +2,12 @@ package com.mapswithme.maps.widget;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.FragmentActivity;
public class PageViewProviderFactory
{
@NonNull
static PageViewProvider defaultProvider(@NonNull AppCompatActivity activity,
static PageViewProvider defaultProvider(@NonNull FragmentActivity activity,
@NonNull ViewPager pager)
{
return new FragmentPageViewProvider(activity.getSupportFragmentManager(), pager);

View file

@ -2,7 +2,8 @@ package com.mapswithme.maps.widget;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.FragmentActivity;
import androidx.app.Activity;
import android.view.View;
import android.widget.ImageView;
@ -23,7 +24,7 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
@NonNull
private final ViewPager mPager;
@NonNull
private final AppCompatActivity mActivity;
private final Activity mActivity;
@NonNull
private final List<Integer> mItems;
@ -34,7 +35,7 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
@NonNull
private final PageViewProvider mPageViewProvider;
public ParallaxBackgroundPageListener(@NonNull AppCompatActivity activity,
public ParallaxBackgroundPageListener(@NonNull Activity activity,
@NonNull ViewPager pager,
@NonNull List<Integer> items,
@NonNull PageViewProvider pageViewProvider)
@ -45,7 +46,7 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
mPageViewProvider = pageViewProvider;
}
public ParallaxBackgroundPageListener(@NonNull AppCompatActivity activity,
public ParallaxBackgroundPageListener(@NonNull FragmentActivity activity,
@NonNull ViewPager pager,
@NonNull List<Integer> items)
{
@ -58,8 +59,8 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
if (state == ViewPager.SCROLL_STATE_IDLE)
setIdlePosition();
boolean isDragging = state == ViewPager.SCROLL_STATE_DRAGGING;
mScrollStarted = isDragging && !mScrollStarted;
boolean isIdle = state == ViewPager.SCROLL_STATE_IDLE;
mScrollStarted = isIdle && !mScrollStarted;
if (mScrollStarted)
mShouldCalculateScrollDirection = true;
@ -68,14 +69,17 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
private void setIdlePosition()
{
mCurrentPagePosition = mPager.getCurrentItem();
mScrollToRight = true;
}
@Override
public void onPageSelected(int position)
{
if (position == 0)
setIdlePosition();
onPageScrollStateChanged(ViewPager.SCROLL_STATE_IDLE);
if (Math.abs(mCurrentPagePosition - position) > 1)
mCurrentPagePosition = mScrollToRight ? Math.max(0, position - 1)
: Math.min(position + 1, mItems.size() - 1);
}
@Override
@ -89,10 +93,8 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
}
int scrollX = mPager.getScrollX();
if (scrollX == 0 && !mScrollToRight || scrollX == mPager.getWidth() * mItems.size())
return;
int animatedItemIndex = mScrollToRight ? mCurrentPagePosition : mCurrentPagePosition - 1;
int animatedItemIndex = mScrollToRight ? Math.min(mCurrentPagePosition, mItems.size() - 1)
: Math.max(0, mCurrentPagePosition - 1);
setAlpha(animatedItemIndex, scrollX);
if (scrollX == 0)
@ -102,6 +104,9 @@ public class ParallaxBackgroundPageListener implements ViewPager.OnPageChangeLis
private void setAlpha(int animatedItemIndex, int scrollX)
{
View view = mPageViewProvider.findViewByIndex(animatedItemIndex);
if (view == null)
return;
ViewPager.LayoutParams lp = (ViewPager.LayoutParams) view.getLayoutParams();
if (lp.isDecor)
return;

View file

@ -33,17 +33,17 @@ public class ParallaxBackgroundViewPager extends ViewPager
public ParallaxBackgroundViewPager(@NonNull Context context, @Nullable AttributeSet attrs)
{
super(context, attrs);
TypedArray a = context.getTheme()
.obtainStyledAttributes(attrs, R.styleable.ParallaxViewPagerBg, 0, 0);
TypedArray array = context.getTheme()
.obtainStyledAttributes(attrs, R.styleable.ParallaxViewPagerBg, 0, 0);
try
{
mAutoScroll = a.getBoolean(R.styleable.ParallaxViewPagerBg_autoScroll, false);
mAutoScrollPeriod = a.getInt(R.styleable.ParallaxViewPagerBg_scrollPeriod,
DEFAULT_AUTO_SCROLL_PERIOD);
mAutoScroll = array.getBoolean(R.styleable.ParallaxViewPagerBg_autoScroll, false);
mAutoScrollPeriod = array.getInt(R.styleable.ParallaxViewPagerBg_scrollPeriod,
DEFAULT_AUTO_SCROLL_PERIOD);
}
finally
{
a.recycle();
array.recycle();
}
mAutoScrollHandler = new Handler();
mAutoScrollMessage = new AutoScrollMessage();