Merge pull request #693 from trashkalmar/whats-new
[android] add: What's new.
BIN
android/res/drawable-hdpi/img_news_p2p.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
android/res/drawable-hdpi/img_news_tts.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
android/res/drawable-mdpi/img_news_p2p.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
android/res/drawable-mdpi/img_news_tts.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
android/res/drawable-xhdpi/img_news_p2p.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
android/res/drawable-xhdpi/img_news_tts.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
android/res/drawable-xxhdpi/img_news_p2p.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
android/res/drawable-xxhdpi/img_news_tts.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
android/res/drawable-xxxhdpi/img_news_p2p.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
android/res/drawable-xxxhdpi/img_news_tts.png
Normal file
After Width: | Height: | Size: 37 KiB |
8
android/res/drawable/news_marker_active.xml
Normal 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="7dp"
|
||||
android:height="7dp"/>
|
||||
|
||||
<solid android:color="@color/news_marker_active"/>
|
||||
</shape>
|
8
android/res/drawable/news_marker_inactive.xml
Normal 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="7dp"
|
||||
android:height="7dp"/>
|
||||
|
||||
<solid android:color="@color/news_marker_inactive"/>
|
||||
</shape>
|
47
android/res/layout/fragment_news.xml
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/margin_half">
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
tools:background="#200000FF"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout
|
||||
android:id="@+id/dots"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="9dp"
|
||||
tools:src="@drawable/news_marker_active"/>
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:src="@drawable/news_marker_inactive"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/next"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
android:textColor="@color/base_blue_light"
|
||||
android:textAllCaps="true"
|
||||
android:padding="@dimen/margin_base"
|
||||
android:background="?clickableBackground"
|
||||
tools:text="Next"/>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
40
android/res/layout/news_page.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mapswithme.maps.widget.HeightLimitedFrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/margin_base"
|
||||
android:paddingRight="@dimen/margin_base">
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center">
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_double_and_half"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:tag="@string/tag_height_limited"
|
||||
tools:src="@drawable/img_news_p2p"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/MwmTextAppearance.Title"
|
||||
android:fontFamily="@string/robotoMedium"
|
||||
tools:text="@string/whats_new_where_to_turn"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_base_plus"
|
||||
android:layout_marginBottom="@dimen/margin_half"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body2"
|
||||
tools:text="@string/whats_new_voice_instructions"/>
|
||||
</LinearLayout>
|
||||
</com.mapswithme.maps.widget.HeightLimitedFrameLayout>
|
|
@ -40,4 +40,19 @@
|
|||
<item>@string/post</item>
|
||||
</array>
|
||||
|
||||
<!-- What's new -->
|
||||
<integer-array name="news_images">
|
||||
<item>@drawable/img_news_tts</item>
|
||||
<item>@drawable/img_news_p2p</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="news_titles">
|
||||
<item>@string/whats_new_where_to_turn</item>
|
||||
<item>@string/whats_new_between_any_points</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="news_subtitles">
|
||||
<item>@string/whats_new_voice_instructions</item>
|
||||
<item>@string/whats_new_happy_day</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -70,4 +70,7 @@
|
|||
<!-- search -->
|
||||
<color name="search_star_dimmed">#1F000000</color>
|
||||
|
||||
<!-- What's new -->
|
||||
<color name="news_marker_active">#8A000000</color>
|
||||
<color name="news_marker_inactive">#1F000000</color>
|
||||
</resources>
|
||||
|
|
|
@ -82,4 +82,7 @@
|
|||
<dimen name="appbar_elevation">4dp</dimen>
|
||||
|
||||
<dimen name="tabs_height">64dp</dimen>
|
||||
|
||||
<dimen name="news_max_width">560dp</dimen>
|
||||
<dimen name="news_max_height">500dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
</style>
|
||||
|
||||
<style name="MwmTextAppearance.Body3.Light">
|
||||
<item name="android:textSize">@dimen/text_size_body_3</item>
|
||||
<item name="android:textColor">@color/text_light</item>
|
||||
</style>
|
||||
|
||||
|
|
|
@ -758,7 +758,10 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
|
||||
mSearchController.refreshToolbar();
|
||||
mPlacePage.onResume();
|
||||
LikesManager.INSTANCE.showDialogs(this);
|
||||
|
||||
if (!NewsFragment.showOn(this))
|
||||
LikesManager.INSTANCE.showDialogs(this);
|
||||
|
||||
mMainMenu.onResume();
|
||||
}
|
||||
|
||||
|
|
191
android/src/com/mapswithme/maps/NewsFragment.java
Normal file
|
@ -0,0 +1,191 @@
|
|||
package com.mapswithme.maps;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.*;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import com.mapswithme.maps.base.BaseMwmDialogFragment;
|
||||
import com.mapswithme.util.Config;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
|
||||
public class NewsFragment extends BaseMwmDialogFragment
|
||||
{
|
||||
private ViewPager mPager;
|
||||
private TextView mNext;
|
||||
private ImageView[] mDots;
|
||||
|
||||
private class Adapter extends PagerAdapter
|
||||
{
|
||||
private final int[] mImages;
|
||||
private final String[] mTitles = MwmApplication.get().getResources().getStringArray(R.array.news_titles);
|
||||
private final String[] mSubtitles = MwmApplication.get().getResources().getStringArray(R.array.news_subtitles);
|
||||
|
||||
Adapter()
|
||||
{
|
||||
TypedArray images = MwmApplication.get().getResources().obtainTypedArray(R.array.news_images);
|
||||
mImages = new int[images.length()];
|
||||
for (int i = 0; i < mImages.length; i++)
|
||||
mImages[i] = images.getResourceId(i, 0);
|
||||
|
||||
images.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return mImages.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object)
|
||||
{
|
||||
return (view == object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position)
|
||||
{
|
||||
View res = LayoutInflater.from(getActivity()).inflate(R.layout.news_page, container, false);
|
||||
|
||||
((ImageView)res.findViewById(R.id.image))
|
||||
.setImageResource(mImages[position]);
|
||||
|
||||
((TextView)res.findViewById(R.id.title))
|
||||
.setText(mTitles[position]);
|
||||
|
||||
((TextView)res.findViewById(R.id.subtitle))
|
||||
.setText(mSubtitles[position]);
|
||||
|
||||
container.addView(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object)
|
||||
{
|
||||
container.removeView((View)object);
|
||||
}
|
||||
}
|
||||
|
||||
private void update()
|
||||
{
|
||||
int cur = mPager.getCurrentItem();
|
||||
for (int i = 0; i < mDots.length; i++)
|
||||
{
|
||||
mDots[i].setImageResource(i == cur ? R.drawable.news_marker_active
|
||||
: R.drawable.news_marker_inactive);
|
||||
}
|
||||
|
||||
mNext.setText(cur + 1 == mDots.length ? R.string.done
|
||||
: R.string.whats_new_next);
|
||||
}
|
||||
|
||||
private void fixPagerSize()
|
||||
{
|
||||
if (!UiUtils.isTablet())
|
||||
return;
|
||||
|
||||
UiUtils.waitLayout(mPager, new ViewTreeObserver.OnGlobalLayoutListener()
|
||||
{
|
||||
@Override
|
||||
public void onGlobalLayout()
|
||||
{
|
||||
int maxWidth = UiUtils.dimen(R.dimen.news_max_width);
|
||||
int maxHeight = UiUtils.dimen(R.dimen.news_max_height);
|
||||
|
||||
if (mPager.getWidth() > maxWidth || mPager.getHeight() > maxHeight)
|
||||
{
|
||||
mPager.setLayoutParams(new LinearLayout.LayoutParams(Math.min(maxWidth, mPager.getWidth()),
|
||||
Math.min(maxHeight, mPager.getHeight())));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setStyle(STYLE_NORMAL, UiUtils.isTablet() ? R.style.MwmMain_DialogFragment
|
||||
: R.style.MwmMain_DialogFragment_Fullscreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Dialog onCreateDialog(Bundle savedInstanceState)
|
||||
{
|
||||
Dialog res = super.onCreateDialog(savedInstanceState);
|
||||
res.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
View content = View.inflate(getActivity(), R.layout.fragment_news, null);
|
||||
res.setContentView(content);
|
||||
|
||||
mPager = (ViewPager)content.findViewById(R.id.pager);
|
||||
fixPagerSize();
|
||||
mPager.setAdapter(new Adapter());
|
||||
mPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onPageSelected(int position)
|
||||
{
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
ViewGroup dots = (ViewGroup)content.findViewById(R.id.dots);
|
||||
mDots = new ImageView[dots.getChildCount()];
|
||||
for (int i = 0; i < mDots.length; i++)
|
||||
mDots[i] = (ImageView)dots.getChildAt(i);
|
||||
|
||||
mNext = (TextView)content.findViewById(R.id.next);
|
||||
mNext.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mPager.getCurrentItem() == mDots.length - 1)
|
||||
dismiss();
|
||||
else
|
||||
mPager.setCurrentItem(mPager.getCurrentItem() + 1, true);
|
||||
}
|
||||
});
|
||||
|
||||
update();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays "What's new" dialog on given {@code activity}. Or not.
|
||||
* @return whether "What's new" dialog should be shown.
|
||||
*/
|
||||
@SuppressWarnings("TryWithIdenticalCatches")
|
||||
public static boolean showOn(FragmentActivity activity)
|
||||
{
|
||||
if (Config.getFirstInstallVersion() >= BuildConfig.VERSION_CODE)
|
||||
return false;
|
||||
|
||||
String tag = NewsFragment.class.getName();
|
||||
if (Config.getLastWhatsNewVersion() >= BuildConfig.VERSION_CODE)
|
||||
return (activity.getSupportFragmentManager().findFragmentByTag(tag) != null);
|
||||
|
||||
Config.setWhatsNewShown();
|
||||
|
||||
try
|
||||
{
|
||||
final NewsFragment fragment = NewsFragment.class.newInstance();
|
||||
fragment.show(activity.getSupportFragmentManager(), tag);
|
||||
} catch (java.lang.InstantiationException ignored)
|
||||
{}
|
||||
catch (IllegalAccessException ignored)
|
||||
{}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ public final class Config
|
|||
private static final String KEY_MISC_DISCLAIMER_ACCEPTED = "IsDisclaimerApproved";
|
||||
private static final String KEY_MISC_KML_MOVED = "KmlBeenMoved";
|
||||
private static final String KEY_MISC_KITKAT_MIGRATED = "KitKatMigrationCompleted";
|
||||
private static final String KEY_MISC_NEWS_LAST_VERSION = "WhatsNewShownVersion";
|
||||
|
||||
private Config() {}
|
||||
|
||||
|
@ -260,6 +261,16 @@ public final class Config
|
|||
setBool(KEY_MISC_KITKAT_MIGRATED);
|
||||
}
|
||||
|
||||
public static int getLastWhatsNewVersion()
|
||||
{
|
||||
return getInt(KEY_MISC_NEWS_LAST_VERSION);
|
||||
}
|
||||
|
||||
public static void setWhatsNewShown()
|
||||
{
|
||||
setInt(KEY_MISC_NEWS_LAST_VERSION, BuildConfig.VERSION_CODE);
|
||||
}
|
||||
|
||||
private static native boolean nativeGetBoolean(String name, boolean defaultValue);
|
||||
private static native void nativeSetBoolean(String name, boolean value);
|
||||
private static native int nativeGetInt(String name, int defaultValue);
|
||||
|
|