2017年5月28日日曜日

What's New in Android Design Tools (Google I/O '17)



# What's new ではない復習的な内容は一部省略しています。

ConstraintLayout

  • Unified and expressive way to create Layouts
  • Flat Layouts
  • Deep INtegration with Android Studio & the Layout Editor
  • Unbundled Library
  • Compatible with 99% of Android Devices
1.0
  • Google I/O 2016 から17回リリース
  • 2017年2月に 1.0 リリース
  • パフォーマンス改善
  • Relative positioning
  • Center positioning & bias
  • Guidelines
  • Chains
  • Ratio
  • ConstraintSet
Android Studio でプロジェクトを作った時のデフォルトが ConstraintLayout に

コミュニティベースのサイトがオープン https://constraintlayout.com/

1.1.0 beta1 maven { url "https://maven.google.com" } dependencies { compile "com.android.support.constraint:constraint-layout:1.1.0-beta1" }
  • Barriers
    • widget の集まりに対して、最小 or 最大の端を取るもの
  • Group
    • widget の集まりを定義できる
    • group に対して setVisibility() すると、それに含まれるすべての widget に setVisibility() される
  • Placeholder

Placeholder

virtual view を作成し、ConstraintLayout の別の view を contents としてセットできる TransitionManager.beginDelayedTransition(container); placeholder.setContentId(view.getId()); 縦横のレイアウトを Placeholder を使った template として用意し、メインのレイアウトを1つにできる layout/header_template.xml <merge ... android:layout_width="match_parent" android:layout_height="match_parent" tools:parentTag="android.support.constraint.ConstraintLayout"> <android.support.constraint.Placeholder android:id="@+id/template_main_image" app:content="@+id/top_image" app:layout_constraintDimensionRatio="16:9" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" /> <android.support.constraint.Placeholder android:id="@+id/template_action" android:layout_width="48dp" android:layout_height="48dp" app:content="@+id/action_button" app:layout_constraintBottom_toBottomOf="@id/template_main_image" app:layout_constraintHorizontal_bias="0.80" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/template_main_image" /> </merge> layout-land/header_template.xml <merge ... android:layout_width="match_parent" android:layout_height="match_parent" tools:parentTag="android.support.constraint.ConstraintLayout"> <android.support.constraint.Placeholder android:id="@+id/template_main_image" app:content="@+id/top_image" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="1:1" app:layout_constraintTop_toTopOf="parent" /> <android.support.constraint.Placeholder android:id="@+id/template_action" android:layout_width="48dp" android:layout_height="48dp" app:content="@+id/action_button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@id/template_main_image" app:layout_constraintRight_toRightOf="@id/template_main_image" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.80" /> </merge> layout/activity_main.xml <android.support.constraint.ConstraintLayout ... android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.sample.myapplication.MainActivity"> <ImageView android:id="@+id/top_image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageButton android:id="@+id/action_button" android:layout_width="48dp" android:layout_height="48dp" /> <include layout="@layout/header_template" /> </android.support.constraint.ConstraintLayout> template に割り当てる部分は ViewGroup や include でも問題ない <android.support.constraint.ConstraintLayout ... android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.sample.myapplication.MainActivity"> <ImageView android:id="@+id/top_image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <include android:id="@+id/action_button" layout="@layout/action_button_content" /> <include layout="@layout/header_template" /> </android.support.constraint.ConstraintLayout>

ConstraintSet

  • View 自体と、それをどのようにレイアウトするかを分離
  • すべての制約を一つのオブジェクトにカプセル化
  • 既存の ConstraintLayout に ConstraintSet を適用できる
  • 複数の ConstraintSet 間を切り替え
    • layout を切り替えるわけではないので、view は reload されない
ConstraintSet mConstraintSet1 = new ConstraintSet(); ConstraintSet mConstraintSet2 = new ConstraintSet(); // get constraints from layout mConstraintSet2.clone(context, R.layout.state2); setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewByid(R.id.activity_main); // get constraints from ConstraintLayout mConstraintSet1.clone(mConstraintLayout); // switch with animation TransitionManager.beginDelayedTransition(mConstraintLayout); // switch to state2 mConstraintSet2.apply(mConstraintLayout);
その他の利用例) 縦横それぞれのレイアウトとその ConstraintSet を用意し、画面回転を自分でハンドリングして、そのときに ConstraintSet を切り替えることで自分でレイアウトを切り替えることが可能


ConstraintLayout & Motion
  • Flat Hierarchy == No clipping issues
  • Scene Graph
  • ConstraintSet == Keyframe


Android Studio 3.0

Tools がいろいろある
  • alignment tools
  • arrengement tools
  • guideline tools
  • right click menu
Inference
  • 接続の確率モデルに基づく
  • 制約されていない view を制約する(すでに制約されているものは何もしない)
  • view は動かさない(alignment tools ではない)
Advanced Inspector
  • properties がどの layout, dimen, strings 由来なのか表示
Tools attributes https://developer.android.com/studio/write/tool-attributes.html
  • tools:
    • デザイン時の属性を上書き
  • tools:showIn
    • このレイアウトを他のやつに埋め込んで表示する
  • tools:layout
    • fragmentで利用するレイアウト
  • tools:listitem
    • list item のレイアウト
  • tools:parentTag
    • merge tag の parent のレイアウトを指定

Sample Data

* Sample Data は Android Studio 3.0 Canary 3 で使えるようになりました。

  • Default Adapter で使える
  • content を指定する
  • tools:listitem で list item のレイアウトを指定する
  • list item のレイアウトで sample data を使う tools:text="@tools:sample/lorem" tools:text="@tools:sample/full_names" tools:text="@tools:sample/us_phones" tools:text="@tools:sample/date_mmddyyyy"
  • sampledata フォルダーを作る(app > sampledata)
  • フォルダーに colors ファイルを追加 #d50000 #2962ff #00e5ff #aeea00 #ff6d00 tools:background="@sample/colors"
  • フォルダーに json(contacts.json とか)ファイルを追加 { "contacts": [ { "name":"...", ... } ] } tools:text="@sample/contacts.json/contacts/name"
  • Baked-in data types
    • date, names, phone numbers...
  • JSON files
  • Resources in sample data folder
    • Text
    • Color
    • Image (collections if in folder)



2017年5月25日木曜日

What's New in Android Development Tools (Google I/O '17)



Android Studio 3.0

2.4 ではなく 3.0 にした理由
  • incremental change ではないから
  • breaking gradle API change があるから

Develop

最新の IntelliJ stable 27.1 ベース

Kotlin サポート

  • Create Android Project ウィザードに Include Kotlin support チェックボックスが追加
  • 既存のプロジェクトに Kotlin ファイルを直接作成すると自動で project の dependencies が更新
  • [Code] - [Convert Java File to Kotlin File] で既存の Java ファイルを Kotlin に変換
  • show Kotlin Bytecode で Kotlin Bytecode Window を起動し、上部の Decompile ボタンで Java コードをチェック
  • Java で動く lint は Kotlin でも動く

Layout Editor

  • ConstraintLayout 1.0.0 beta1 の機能(barriers など)に対応
新しい sample リソースタイプ tools:text="@tools:sample/lorem" tools:text="@tools:sample/date_day_of_week" 表示データ用の json ファイル(hoge_log.json)を用意して tools:src="@sample/hoge_log.json/hoge/icon" tools:text="@sample/hoge_log.json/hoge/description"

Downloadable Font 対応

  • TextView を選択して Properties の fontFamily から More Fonts... を選択
  • font を検索して選択

Adaptive Icon

  • Image Assert ウィザード で Adaptive Icon に対応

Device File Explorer

  • 右下にある
  • デバイス内のファイルを見たり、アップロード、ダウンロードできる

Instant Apps

  • リファクタリングサポート
    • クラスファイルで Modularize... を起動
    • 依存クラス含めてどれを module に移動するか選択
    • 現状 initial version でまだまだ改善中らしい

Apk Analyzer

  • クラスを右クリック - Show bytecode
  • Load proguard mapping ボタンから mapping ファイルを設定
  • クラスを右クリック - Generate Proguard keep rule
  • クラスを右クリック - Find Usages

Apk Debugging

  • [File] - [Profile or Debug APK...]

Profiler

  • Android Profiler ウィンドウ
  • CPU, Memory, Network

Network Profiler

  • Network をクリック、ズームイン、ネットワークリクエストが表示される
  • ネットワークリクエストをクリックすると、詳細と Call Stack が表示される
  • HttpUrlConnection とそれをベースにしているもの(Volleyとか)、OkHttp に対応

CPU Profiler

  • Recording をクリック、アプリを操作、Stop Recording をクリック
  • Thread が表示される

Memory Profiler

  • Garbage Collection
  • Heap dump
  • Recording


Build

Google's maven Repo

  • Gradle plugin
  • Support Libraries
  • Data-Binding Library
  • Constraint Layout
  • Instant Apps Library
  • Architecture Compoennts
  • Android Testing Libraries
  • Espresso
repositories{ maven {url 'https://maven.google.com'} or google() // 4.0-milestone-2 or later }

Build Performance

  • Incremental Tasks
    • Resource Processing(planned for 3.0)
    • Shrinking (experimental, 2.3)
    • Java Compilation (Gradle 3.5)
    • Dexing (3.0)
    • Annotation Processor x
    • APK Packaging (2.2)

Build Cache

  • Local
    • Switch between branches without recompiling -- build-cache org.gradle.caching=true
  • Distributed
    • Share with team members And Build Server
    • Hazelcast implementation Gradle Enterprise API for custom backend

Multi-modules Advantages

  • Code Reuse
  • Improve Caching
  • API/Dependency Control
  • Compilation Avoidance
複数のモジュールでの Parallel Build に取り組んでいる

Support for Java 8 Language Features

android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } defaultConfig.jackOptions.enabled=true は廃止

Dependency Management

  • いままでは依存ライブラリ(module) の release build が利用されていた
  • 手動で buildType を合わせる方法もあったが割と設定が大変
  • 3.0 では新しい gradle の API によって同じ名前の buildType や flavor があれば自動で合わせてくれるようになった
  • ライブラリに flavor があってアプリ側に対応する flavor がない場合のために、新しい flavorSelection が追加
  • flavor が一つでも flavorDimension が必須に
アプリ側 android { flavorSelection 'color', 'blue' } ライブラリ側 android { flavorDimension 'color' productFlavors { blue {} orange {} } }

Instant Apps

  • feature module (com.android.feature) に分割
  • feature module を組み合わせて Instant-app (com.android.instantapp) を作る


Test

Android Emulator

  • Google Play Store が搭載された Google Play Edition が増えた
  • Open GL ES 3.0
  • Proxy Support

  • Android Open Source Project
    • x : Google APIs
    • x : Google Play
    • o : Elevated Privileges
  • Google Play Edition
    • o : Google APIs
    • o : Google Play
    • x : Elevated Privileges (root access など無し)

App Bug Reporting

  • エミュレータからスクリーンショットなど情報つきでバグレポートをQAチームなどに簡単に送れる

Android Wear Emulator

  • Emulator Rotary Input support

Layout Inspector

  • いろいろ改善した

Optimize

  • Android Profiler (CPU, Memory, Network)
  • APK Analyzer
  • WebP support



2017年5月23日火曜日

What's New in Android Support Library (Google I/O '17)

  • v26.0.0-beta1 の話
  • support library の minSdkVersion が 14 になった
  • メソッドやクラスを削減して、メソッドカウントが約1.4k減った
  • 今後より多くメソッドやクラスを削減したいので 約 30 classes / interfaces, 約 400 メソッドが deprecated になった
    • later version で削除される予定
  • Google Maven Repository で配布されるようになった
    • Constraint Layout Library や Architecture Components Library も含まれる
    • 過去の Support Library version (13.0.0 〜) も含まれる
repositories{ maven { // Google Maven Repository url "https://maven.google.com" } } dependencies { compile "com.android.support:appcopmat-v7:26.0.0-beta1" }

XML Font (14+)

  • font を xml で指定できるようになった
  • res/font/font1.ttf, res/font/xml_font.xml
  • font-family で font をグループ化
res/font/myfont.xml <?xml version="1.0" encoding="utf-8"?> <font-family xmlns:app="http://schemas.android.com/apk/res-auto"> <font app:fontStyle="normal" app:fontWeight="400" app:font="@font/myfont_regular" /> <font app:fontStyle="normal" app:fontWeight="800" app:font="@font/myfont_bold" /> </font-family> <TextView ... android:fontFamily="@font/myfont" android:textStyle="bold" /> Typeface typeface = ResourceCompat.getFont(context, R.font.myFont); textView.setTypeface(typeface);

Downloadable Fonts(14+)

  • 今までもフォントファイルをアプリの中に持って使うことができたがアプリサイズが大きくなる要因
  • Font Provider は font を fetch し、cache し、アプリが必要なフォントを返す
  • 複数のアプリから単一のエントリーポイント(FontsContractCompat)を経て Font Provider にアクセスする
    • 複数のアプリでメモリを節約できる
  • Font Provider は Google Play Services を介して 800+ の Google Fonts を利用できる
FontRequest request = new FontRequest( "com.example.fontprovider.authority", "com.example.fontprovider", "Name fo font", R.array.certs); FontsContractCompat.FontRequestCallback callback = new FontsContractCompat.FontRequestCallback() { @Override public void onTypefaceRetrieved(Typeface typeface) {} @Override public void onTypefaceRequestFailed(int reason) {} }; FontsContractCompat.requestFont(context, request, callback, new Handler()); xml/font/downloadedfont.xml <font-family xmlns:app="http://schemas.android.com/apk/res-auto"> app:fontProviderAuthority="com.example.fontprovider.authority" app:fontProviderPackage="com.example.fontprovider" app:fontProviderQuery="dancing-script" app:fontProviderCerts="@array/certs"> </font-family>
  • これをレイアウトに指定したら、フォントを fetch して適用するまでやってくれる
  • 適用できるまでの間はデフォルトのフォントで表示される
  • Android Studio で google fonts からフォントを選択できるようになった(3.0)
    • 自動で downloadedfont.xml が作られる

Emoji Compatibility Library (19+)

tofu 問題を解決するぞ dependencies { compile "com.android.support:support-emoji:${version}" } FontRequest fontRequest = new FontRequest( "com.example.fontprovider", "com.example", "emoji compat Font Query", CERTIFICATES); ); EmojiCompat.Config config = new FontRequstEmojiCompatConfig(this, fontRequest); EmojiCompat.init(config);
  • Google Play Service がないデバイスをターゲットにするには
    • Bundled configuration - 7MB
dependencies { compile "com.android.support:support-emoji-bundled:${version}" } EmojiCompat.Config config = new BundledEmojiCompatConfig(this); EmojiCompat.init(config);
  • android.support.text.emoji.widget.EmojiTextView, EmojiEditText, EmojiButton
    • 自動で Emoji Compat を利用して Emoji を表示する

Autosizing TextView

<TextView ... app:autoSizeTextType="uniform" /> より細かく指定したい場合
xml で定義したサイズの中から一番合うサイズを選択してくれる <TextView ... app:autoSizeTextType="uniform" app:autoSizePresetSizes="@array/autosize_sizes" /> min, max を指定する場合 <TextView ... app:autoSizeTextType="uniform" app:autoSizeMinTextSize="12sp" app:autoSizeMaxTextSize="100sp" app:autoSizeStepGranularity="2sp" />

DynamicAnimation (16+)

final SpringAnimation anim = new SpringAnimation( bugdroidImageView, // object to animate TRANSLATION_Y, // property to animate 0); // equilibrim state anim.getSpring() .setDampingRatio(0.7f /* lower is more bouncy */) .setStiffness(1500f /* higher oscillates faster */) anim.setStartVelocity(velocityTracker.getYVelocity()) .start();

Vector Drawable Compat - FillType (14+)

  • android:fillType
  • Determines "inside" of shape
  • Corresponds to SVG's fill-rule
  • Commonly used by vector drawing tools

Animated Vector Drawable Compat - pathData morphing (14+)

  • Animate <vector> android:pathData attribute
  • Set valueFrom, valueTo using VectorDrawable path data
  • Path formats must match
res/drawable/buffalo.xml <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="600dp" android:width="320dp" android:viewportHeight="600" android:viewportWidth="320"> <group> <path android:name="buffalo_path" android:pathData="@string/buffalo" /> </group> </vector> res/anim/buffalo_to_hippo.xml <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:propertyName="pathData" android:valueFrom="@string/buffalo" android:valueTo="@string/hippo" android:valueType="pathType" /> res/drawable/animal_morph.xml <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/buffalo"> <target android:name="buffalo_path" android:animation="@anim/buffalo_to_hippo" /> </animated-vector> aapt を使う res/drawable/animal_morph.xml <animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"> <aapt:attr name="android:drawable"> <vector android:height="600dp" android:width="320dp" android:viewportHeight="600" android:viewportWidth="320"> <group> <path android:name="buffalo_path" android:pathData="@string/buffalo" /> </group> </vector> </aapt:attr> <target android:name="buffalo_path" android:animation="@anim/buffalo_to_hippo" /> </animated-vector> 全部を1つのファイルにする res/drawable/animal_morph_bundle.xml <animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"> <aapt:attr name="android:drawable"> <vector android:height="600dp" android:width="320dp" android:viewportHeight="600" android:viewportWidth="320"> <group> <path android:name="buffalo_path" android:pathData="@string/buffalo" /> </group> </vector> </aapt:attr> <target android:name="buffalo_path"> <aapt:attr name="android:animation"> <objectAnimator android:duration="1000" android:propertyName="pathData" android:valueFrom="@string/buffalo" android:valueTo="@string/hippo" android:valueType="pathType" /> </aapt:attr> </target> </animated-vector>

<pathInterpolator>

  • Parity with platform AVD
  • <objectAnimator> で利用 android:interpolator
  • Used VectorDrawable (SVG-like) path data
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:pathData="M 0.0, 0.0 c 0.08,0.0 0.04,1.0 0.2,0.8 l 0.6,0.1 L 1.0,1.0" />

Wear

New support-wear module

TV

Leanback

PreferenceDataStore

PreferenceDataStore
  • preference storage mechanism のカスタマイズを可能に
class CloudDataStore extends PreferenceDataStore { @Override public void putBoolean(String key, boolean value) { // cache value immediately, launch async task to persist // data to cloud service. } @Override public void getBoolean(String key, boolean defValue) { // Return cached value. return false; } } メソッドは Main スレッドで呼ばれるので注意 // Set up this PreferenceFragment to store // and retrieve data using CloudDataStore. PreferenceManager prefManager = getPreferenceManager(); CloudDataStore cloudStore = new CloudDataStore(); prefManager.setPreferenceDataStore(cloudStore);

FragmentManager

executePendingTransaction(), commitNow(), and similar transaction calls are no longer allowed during FragmentManager state changes.

FrameMetricsAggregator

  • FrameMetricsAggregator
  • Performance monitoring tool used to capture a variety of information about Activity drawing.

ActionBarDrawerToggle

setDrawerSlideAnimationEnabled() メソッドで Navigation drawer のアイコンのアニメーションを無効化できる


2017年5月5日金曜日

android コマンドから sdkmanager に移行

android コマンドは廃止になりました。
https://developer.android.com/studio/releases/sdk-tools.html の SDK Tools, Revision 25.3.0 (March 2017)

代わりに sdkmanager コマンドを使います。
使い方は
https://developer.android.com/studio/command-line/sdkmanager.html $ sdkmanager "build-tools;25.0.0" のように使います。 複数のパッケージをファイルに羅列して $ sdkmanager --package_file=file のように指定することもできます。 file の中身はこんな感じ platform-tools build-tools;25.0.0 platforms;android-24 platforms;android-25 extras;android;m2repository extras;google;m2repository extras;google;google_play_services extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.2 extras;m2repository;com;android;support;constraint;constraint-layout;1.0.2

ライセンスの accept はどうするかというと、
https://developer.android.com/studio/intro/update.html#download-with-gradle にあるように、
ローカルで許可したあとの
[sdk dir]/licenses/android-sdk-license
ファイルをビルドサーバーにコピーしておきます。


2017年5月2日火曜日

Android UI Test : Dialog を表示する

@RunWith(AndroidJUnit4.class) @LargeTest public class ShowDialogUiTest { // Activity は起動できて副作用がないやつならなんでもよい @Rule public ActivityTestRule mActivityRule = new ActivityTestRule<>(LoginActivity.class); @Test public void showDialog() throws Throwable { mActivityRule.runOnUiThread(new Runnable() { @Override public void run() { // Dialog は Window token のある context が必要なので Context として Activity を使う new AlertDialog.Builder(mActivityRule.getActivity()) .setTitle(R.string.title) .setMessage(R.string.message) .setPositiveButton(android.R.string.yes, null) .setNegativeButton(android.R.string.no, null) .setCancelable(false) .show(); } }); onView(withText(R.string.message)).check(matches(isDisplayed())); } }
ActivityTestRule の対象にする Activity は「androidTest に DummyActivity を用意する」みたいな方法をとりたかったんだけど、アプリとテストで apk が分かれるので無理そうだ ↓ http://stackoverflow.com/questions/36276909/create-dummyactivity-inside-androidtest-folder-for-testing