SlideShare a Scribd company logo
1 of 63
Download to read offline
DroidKaigi 2017 - 2017/03/09 @cattaka_net
Viewを動的に
変化させるアプローチ
Takao Sumitomo
@cattaka_net
DroidKaigi 2017 - 2017/03/09 @cattaka_net
自己紹介
●
住友 孝郎(Takao Sumitomo)
●
Androidアプリ開発者
●
今やってること
●
Androidアプリケーション
●
昔やってたこと
●
いろいろ(MFCとかStrutsとか)
●
ウォンテッドリー株式会社所属
●
2014年12月〜
●
それ以前は関西で仕事してた
DroidKaigi 2017 - 2017/03/09 @cattaka_net
直近のアプリ
かしこく、名刺管理
人工知能を搭載したカメ
ラで、10枚までの名刺を
わずか3秒でデータ化、そ
して管理可能な、無料で
使えるビジネスパーソン向
けのアプリです。
DroidKaigi 2017 - 2017/03/09 @cattaka_net
発表の内容
●
お題
●
ユーザーの操作に追従させたい
●
キーワード
●
DataBinding
●
ConstraintLayout
●
Material Designに特化した話ではなく、どう実装
するかのお話
DroidKaigi 2017 - 2017/03/09 @cattaka_net
標準APIとSupport Libraryで
できること
DroidKaigi 2017 - 2017/03/09 @cattaka_net
アニメーション
●
ViewPagerの切替時
●
FABが操作の完了時に
出てくる
DroidKaigi 2017 - 2017/03/09 @cattaka_net
AppBarLayout
●
一定以上スクロールす
ると、色が変わる
●
タイトルのみ動かせる
●
補足:このサンプルはバ
グのため動かせなかっ
た、、
DroidKaigi 2017 - 2017/03/09 @cattaka_net
やりたいこと
ユーザーの操作に追従させたい
DroidKaigi 2017 - 2017/03/09 @cattaka_net
今回の話のゴール
DroidKaigi 2017 - 2017/03/09 @cattaka_net
実装アプローチのイメージ
●
意識するのは3つ
●
操作イベント
●
属性値の計算
●
Viewの更新
操作イベント
属性値の計算
Viewの更新
DroidKaigi 2017 - 2017/03/09 @cattaka_net
この3つを見ていきます
操作イベント
属性値の計算
Viewの更新
DroidKaigi 2017 - 2017/03/09 @cattaka_net
何を操作イベントとする?
操作イベント
属性値の計算
Viewの更新
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
タッチイベントは辛い
●
タッチイベントは種類がいっぱい
●
全部で何個種類があるか全部言える人いる?
●
マルチタッチになるとどうなる?
●
ネステッドスクロールはさらに難解
●
flingが入るともうカオス
●
CoordinatorLayoutのBehaviorも同じ
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
無難なイベント
●
スクロールイベント系
●
ScrollView
●
RecyclerView
●
AppBarLayout
●
レイアウト系イベント
●
OnLayoutChangeListener
●
OnGlobalLayoutListener
– ただし注意しないとループに嵌まる
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
よくよく考えると
●
タッチ操作でViewを変化させるというより
●
他のViewに合わせて動くと考えるほうが自然
ViewPagerで
発生したイベント
表示を更新
表示を更新
スクロール量から
計算
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
Viewの属性値の計算はどこでやる?
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
コードでゴリゴリやる
●
行数が増えがちになる
●
コードを読まないとどういう動きかわからない
●
なのであまりやりたくない
DroidKaigi 2017 - 2017/03/09 @cattaka_net
属性値の計算は分けて考える
●
スクロール量などの値を正規化した値にする
●
具体的な属性値への計算は別途やる
0.0〜1.0に
なるように
0.0〜3.0になるように
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
ViewPagerでの計算
●
タブは0.0〜3.0の値か
ら計算
●
FABは0.0〜1.0の値か
ら計算
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ViewPagerでの計算
@Override
public void onPageScrolled(
int position, // 0,1,2などのページ番号
float positionOffset, // 0.0〜1.0の範囲のオフセット
int positionOffsetPixels) {
float absolutePosition = position + positionOffset;
float fabFactor = (position == 0) ? positionOffset : 1;
/* 省略 */
}
本質はここ
0.0〜3.0 の値を算出
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ViewPagerでの計算
1ページ目のみ
0.0〜1.0 の値が欲しい
@Override
public void onPageScrolled(
int position, // 0,1,2などのページ番号
float positionOffset, // 0.0〜1.0の範囲のオフセット
int positionOffsetPixels) {
float absolutePosition = position + positionOffset;
float fabFactor = (position == 0) ? positionOffset : 1;
/* 省略 */
}
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ScrollViewでの計算
●
0.0〜1.0の値から諸々の
属性値を計算する
●
ActionBar
●
タイトル
– 座標と色
●
アイコン
●
その他のテキスト
– 座標と色
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ScrollViewでの計算
@Override
public void onScrollChange(NestedScrollView v,
int scrollX, int scrollY, int oldScrollX, int
oldScrollY) {
int h = mBinding.layoutContents.image.getHeight();
float factor = (h > 0) ? (float) scrollY / h : 0f;
if (factor < 0f) {
factor = 0f;
} else if (factor > 1f) {
factor = 1f;
}
/* 省略 */
}
本質はここ
0.0〜1.0 の値を算出
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ScrollViewでの計算
@Override
public void onScrollChange(NestedScrollView v,
int scrollX, int scrollY, int oldScrollX, int
oldScrollY) {
int h = mBinding.layoutContents.image.getHeight();
float factor = (h > 0) ? (float) scrollY / h : 0f;
if (factor < 0f) {
factor = 0f;
} else if (factor > 1f) {
factor = 1f;
}
/* 省略 */
}
0除算に注意
DroidKaigi 2017 - 2017/03/09 @cattaka_net
Viewに設定する属性値の計算
●
対象となる属性
●
alpha
●
width / height
●
translationX / translationY
●
scaleX / scaleY
●
textSize
●
etc
●
この辺りの計算はDataBindingの計算が便利
DroidKaigi 2017 - 2017/03/09 @cattaka_net
Viewの更新のアプローチ
操作イベント
属性値の計算
Viewの更新
DroidKaigi 2017 - 2017/03/09 @cattaka_net
操作イベント
属性値の計算
Viewの更新
DataBindingが強い
●
変数を渡せる
●
計算式が書ける
DroidKaigi 2017 - 2017/03/09 @cattaka_net
DataBindingの変数
<layout>
<data>
<variable name="fabFactor" type="float" />
</data>
<RelativeLayout android:id="@+id/layout">
<!-- 省略 -->
</RelativeLayout>
</layout>
mBinding.setFabFactor(fabFactor);
layout xmlでの定義
Java側から渡す
xmlで定義すると
setterが作られる
DroidKaigi 2017 - 2017/03/09 @cattaka_net
DataBindingで計算
<android.support.design.widget.FloatingActionButton
android:id="@+id/button_search"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:translationY="@{fabFactor *  @dimen/fab_offset}" />
dimenの値に掛け算で
楽に設定できる
※:@dimen/fab_offset より良い方法を後述
DroidKaigi 2017 - 2017/03/09 @cattaka_net
具体的な例
DroidKaigi 2017 - 2017/03/09 @cattaka_net
FABの現れ方
●
完全に隠れるには
親のheight - 自分のtop
が必要になる
自分のtop
親のheight
これ
DroidKaigi 2017 - 2017/03/09 @cattaka_net
FABの現れ方
<RelativeLayout android:id="@+id/layout">
<!-- 他のViewは省略 -->
<android.support.design.widget.FloatingActionButton
android:id="@+id/button_search"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:translationY="@{fabFactor *
(layout.getHeight() - buttonSearch.getTop())}"
/>
</RelativeLayout>
translationYに
必要な値をここで計算
DroidKaigi 2017 - 2017/03/09 @cattaka_net
タブの動き
●
文字サイズを変える
●
背景色を変える
●
elevationを変える
●
幅を変える
DroidKaigi 2017 - 2017/03/09 @cattaka_net
タブの動き
<TextView
    android:id="@+id/tab_0"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"
    android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"
    android:gravity="center"
    android:text="List"
    android:textAppearance="?android:textAppearanceMedium"
    android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tab_1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}"
/>
DroidKaigi 2017 - 2017/03/09 @cattaka_net
タブの動き:文字サイズを変える
<TextView
    android:id="@+id/tab_0"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"
    android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"
    android:gravity="center"
    android:text="List"
    android:textAppearance="?android:textAppearanceMedium"
    android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tab_1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}"
/>
android:textSize="@{
DataBindingFunctions.evaluateFactor(
position, ←スクロール位置(0.0〜3.0)
0f, ←対象タブの番号(0,1,2)
@dimen/text_tab_small,←未選択時のサイズ
@dimen/text_tab_large ←選択時のサイズ
)}"
独自の補間用メソッド
DroidKaigi 2017 - 2017/03/09 @cattaka_net
タブの動き:背景色を変える
<TextView
    android:id="@+id/tab_0"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"
    android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"
    android:gravity="center"
    android:text="List"
    android:textAppearance="?android:textAppearanceMedium"
    android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tab_1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}"
/>
android:background="@{
DataBindingFunctions.evaluateColor(
position, ←スクロール位置(0.0〜3.0)
0f, ←対象タブの番号(0,1,2)
@color/bgTab, ←未選択時の色
@color/bgTabSelected ←選択時の色
)}"
独自の補間用メソッド
DroidKaigi 2017 - 2017/03/09 @cattaka_net
タブの動き:elevationを変える
<TextView
    android:id="@+id/tab_0"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"
    android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"
    android:gravity="center"
    android:text="List"
    android:textAppearance="?android:textAppearanceMedium"
    android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tab_1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}"
/>
android:elevation="@{
DataBindingFunctions.evaluateFactor(
position, ←スクロール位置(0.0〜3.0)
0f, ←対象タブの番号(0,1,2)
0f, ←未選択時の値
@dimen/elevation_tab ←選択時の値
)}"
独自の補間用メソッド
DroidKaigi 2017 - 2017/03/09 @cattaka_net
タブの動き:幅を変える
<TextView
    android:id="@+id/tab_0"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"
    android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"
    android:gravity="center"
    android:text="List"
    android:textAppearance="?android:textAppearanceMedium"
    android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tab_1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}"
/>
app:setLayoutWeight="@{
DataBindingFunctions.evaluateFactor(
position, ←スクロール位置(0.0〜3.0)
0f, ←対象タブの番号(0,1,2)
3f, ←未選択時のlayout_weight
4f ←選択時のlayout_weight
)}"
独自の補間用メソッド
独自のlayout_weight指定用メソッド(後述)
DroidKaigi 2017 - 2017/03/09 @cattaka_net
DataBindingの制限
●
LayoutParamに直接的に値を設定できない
●
xml上で android:layout_***** となっているもの
●
BindingAdapter用のメソッドを作ればできる
@BindingAdapter("setLayoutWeight")
public static void setLayoutWeight(View view, float value) {
ViewGroup.LayoutParams params = view.getLayoutParams();
if (params instanceof LinearLayout.LayoutParams) {
((LinearLayout.LayoutParams) params).weight = value;
view.setLayoutParams(params);
}
}
DroidKaigi 2017 - 2017/03/09 @cattaka_net
CollapsingToolbarLayout
みたいなことをやる
●
アイコンを動かす
●
テキストを動かす
●
ステータスバーの色を
変える
DroidKaigi 2017 - 2017/03/09 @cattaka_net
アイコンを動かす
<ImageView
    android:id="@+id/image_icon"
    android:layout_width="?android:actionBarSize"
    android:layout_height="?android:actionBarSize"
    android:background="@drawable/oval_fill_white"
    android:padding="4dp"
    android:scaleType="centerCrop"
    android:scaleX="@{2f-scrollFactor}"
    android:scaleY="@{2f-scrollFactor}"
    app:layout_constraintBottom_toBottomOf="@+id/dummy_action_bar"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/dummy_action_bar"
    app:loadImage="@{item.file}"
    app:loadImageTransformation="@{CircleTransform.instance}"
    app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/icon_offset_x)}"
    app:setLayoutMarginTop="@{(int)((1f-scrollFactor) * @dimen/icon_offset_y)}"
    app:useFit="@{false}"
    tools:layout_marginStart="@dimen/icon_offset_x"
    tools:layout_marginTop="@dimen/icon_offset_y"
    tools:scaleX="2"
    tools:scaleY="2"
    tools:src="@drawable/dummy_icon" />
DroidKaigi 2017 - 2017/03/09 @cattaka_net
アイコンを動かす
<ImageView
    android:id="@+id/image_icon"
    android:layout_width="?android:actionBarSize"
    android:layout_height="?android:actionBarSize"
    android:background="@drawable/oval_fill_white"
    android:padding="4dp"
    android:scaleType="centerCrop"
    android:scaleX="@{2f-scrollFactor}"
    android:scaleY="@{2f-scrollFactor}"
    app:layout_constraintBottom_toBottomOf="@+id/dummy_action_bar"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/dummy_action_bar"
    app:loadImage="@{item.file}"
    app:loadImageTransformation="@{CircleTransform.instance}"
    app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/icon_offset_x)}"
    app:setLayoutMarginTop="@{(int)((1f-scrollFactor) * @dimen/icon_offset_y)}"
    app:useFit="@{false}"
    tools:layout_marginStart="@dimen/icon_offset_x"
    tools:layout_marginTop="@dimen/icon_offset_y"
    tools:scaleX="2"
    tools:scaleY="2"
    tools:src="@drawable/dummy_icon" />
android:scaleX="@{2f-scrollFactor}"
android:scaleY="@{2f-scrollFactor}"
app:setLayoutMarginStart="@{
(int)((1f-scrollFactor) * @dimen/icon_offset_x)
}"
app:setLayoutMarginTop="@{
(int)((1f-scrollFactor) * @dimen/icon_offset_y)
}"
DroidKaigi 2017 - 2017/03/09 @cattaka_net
テキストを動かす
<TextView
    android:id="@+id/text_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{item.name}"
    android:textAppearance="?android:textAppearanceLarge"
    android:textColor="@{DataBindingFunctions.evaluateColor(scrollFactor, @android:color/white, @android:color/black)}"
    android:textSize="@{(1f-scrollFactor) * @dimen/text_title_large + scrollFactor * @dimen/text_title_small}"
    app:layout_constraintBottom_toBottomOf="@+id/image_icon"
    app:layout_constraintStart_toEndOf="@id/image_icon"
    app:layout_constraintTop_toTopOf="@+id/image_icon"
    app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/spacing_x4)}"
    tools:layout_marginStart="@dimen/spacing_x4"
    tools:text="Name"
    tools:textColor="@android:color/white"
    tools:textSize="@dimen/text_title_large" />
DroidKaigi 2017 - 2017/03/09 @cattaka_net
テキストを動かす
<TextView
    android:id="@+id/text_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{item.name}"
    android:textAppearance="?android:textAppearanceLarge"
    android:textColor="@{DataBindingFunctions.evaluateColor(scrollFactor, @android:color/white, @android:color/black)}"
    android:textSize="@{(1f-scrollFactor) * @dimen/text_title_large + scrollFactor * @dimen/text_title_small}"
    app:layout_constraintBottom_toBottomOf="@+id/image_icon"
    app:layout_constraintStart_toEndOf="@id/image_icon"
    app:layout_constraintTop_toTopOf="@+id/image_icon"
    app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/spacing_x4)}"
    tools:layout_marginStart="@dimen/spacing_x4"
    tools:text="Name"
    tools:textColor="@android:color/white"
    tools:textSize="@dimen/text_title_large" />
android:textColor="@{
DataBindingFunctions.evaluateColor(
scrollFactor,
@android:color/white,
@android:color/black)
}"
android:textSize="@{
(1f-scrollFactor) * @dimen/text_title_large
+ scrollFactor * @dimen/text_title_small}"
app:setLayoutMarginStart="@{
(int)((1f-scrollFactor) * @dimen/spacing_x4)}"
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ステータスバーの色を変える
●
LOLLIPOP以降なら普通に変えられる
●
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
※:これはDataBinding使わない
int color = DataBindingFunctions.evaluateColor(
factor, mOriginalStatusBarColor, mVibrantColor);
Window window = getWindow();
if (window != null && Build.VERSION.SDK_INT
>= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(color);
}
DroidKaigi 2017 - 2017/03/09 @cattaka_net
tip & trap
DroidKaigi 2017 - 2017/03/09 @cattaka_net
toolsNSを活用しよう
●
layout xmlの最終形がイメージしづらい
●
レイアウトエディタ上でイメージできるようにしよう
DroidKaigi 2017 - 2017/03/09 @cattaka_net
表示が切れる問題
●
親のViewGroupを飛び出すと...
●
表示が切れる
●
elevationの影が切れる
●
android:clipToPadding="false" で回避できる
DroidKaigi 2017 - 2017/03/09 @cattaka_net
OnLayoutChangeListenerのtrap
●
気をつけないとループに嵌まることがある
●
変更通知→レイアウト変更→変更通知→...
●
フリーズはしないので知らないうちにCPUを食い潰す...
●
直前の値を保持して、不要ならメソッドを叩かない
ようにする
DroidKaigi 2017 - 2017/03/09 @cattaka_net
OnGlobalLayoutListenerのtrap
●
removeを忘れるとメモリリークする
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ConstraintLayoutが強力
●
LayoutParamを弄ると、相対的な配置を維持したまま
動く
●
layout_width
●
layout_height
●
layout_margin
●
layout_constraintHorizontal_weight
●
layout_constraintVertical_weight
●
etc
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ConstraintLayoutが強力
●
例
●
3つのテキストはアイコンに対
して相対的に動いている
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ConstraintLayoutのtrap
●
layout_width=0でmatch_parentと同じ挙動
●
100dp→0dpのように動かすと、
0dpのときに突然広がる挙動をして困る
●
BindingAdapterのメソッドの中で0.01などにして、
誤魔化用にすることで回避できる
●
ネガティブマージンが使えない問題
●
ダミーのSpaceを挟むことで回避できる
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ConstraintLayoutのtrap
●
Android Studio 2.3現在
レイアウトエディタでxmlを触ると
たまにxmlが壊れる(´;ω;`)
DroidKaigi 2017 - 2017/03/09 @cattaka_net
DataBindingは
暗黙的型変換をしない
●
計算でfloat, double, intの場合は明示的にキャス
トが必要
●
型が違っているとビルドエラーになる
●
Java言語の仕様に従って、floatなら1.0f、double
なら1.0とか書かないとダメ
DroidKaigi 2017 - 2017/03/09 @cattaka_net
考察
DroidKaigi 2017 - 2017/03/09 @cattaka_net
DataBindingを使う理由
●
色や大きさはXMLに入れるべきか、Javaに入れるべきか
●
Javaに書くと
●
行数が増える
●
xmlと距離が遠くて把握しづらい
●
コードが読める人じゃないとメンテナンスできない
●
DataBindingに書くと
●
xmlの属性の@{...}の部分を見ればだいたいわかる
●
ただ、横に長くなる...
DroidKaigi 2017 - 2017/03/09 @cattaka_net
パフォーマンスに関する考察
●
LayoutParamsをいじるのは正直重い
●
LayoutParamsを変えると、measure系が走る
●
ただ複数のViewが相対的に変化するならどのみち必要
●
必要が無いならtranslateやscaleを使うほうが良
い
DroidKaigi 2017 - 2017/03/09 @cattaka_net
工数に関すること
●
極論で言うと、タッチイベントからやるのがパフォーマ
ンスが出る
●
CoordinatorLayoutと同じアプローチ
– すなわち、CoordinatorLayoutのBehaviorを作る
●
でも難解
●
イベント+DataBindingが楽(と考える)
操作イベント
属性値の計算
Viewの更新
Behaviorだと
これを全部やることになる...
DroidKaigi 2017 - 2017/03/09 @cattaka_net
まとめ
DroidKaigi 2017 - 2017/03/09 @cattaka_net
まとめ
操作イベント
属性値の計算
Viewの更新
スクロールやレイアウトイベントを
トリガーにする
コード側で
値を正規化する
DataBindingで
具体的な値の算出と設定をする
DroidKaigi 2017 - 2017/03/09 @cattaka_net
サンプルアプリ
https://github.com/cattaka/ProteanLayoutExample
DroidKaigi 2017 - 2017/03/09 @cattaka_net
ご清聴ありがとうございました
Takao Sumitomo
@cattaka_net

More Related Content

What's hot

3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)Toru Tamaki
 
LiDAR点群とSfM点群との位置合わせ
LiDAR点群とSfM点群との位置合わせLiDAR点群とSfM点群との位置合わせ
LiDAR点群とSfM点群との位置合わせTakuya Minagawa
 
QGIS初級編2018
QGIS初級編2018QGIS初級編2018
QGIS初級編2018Jyun Tanaka
 
サルでもわかるディープラーニング入門 (2017年) (In Japanese)
サルでもわかるディープラーニング入門 (2017年) (In Japanese)サルでもわかるディープラーニング入門 (2017年) (In Japanese)
サルでもわかるディープラーニング入門 (2017年) (In Japanese)Toshihiko Yamakami
 
深層学習によるHuman Pose Estimationの基礎
深層学習によるHuman Pose Estimationの基礎深層学習によるHuman Pose Estimationの基礎
深層学習によるHuman Pose Estimationの基礎Takumi Ohkuma
 
第1回 配信講義 計算科学技術特論B(2022)
第1回 配信講義 計算科学技術特論B(2022)第1回 配信講義 計算科学技術特論B(2022)
第1回 配信講義 計算科学技術特論B(2022)RCCSRENKEI
 
[DL輪読会]Graph R-CNN for Scene Graph Generation
[DL輪読会]Graph R-CNN for Scene Graph Generation[DL輪読会]Graph R-CNN for Scene Graph Generation
[DL輪読会]Graph R-CNN for Scene Graph GenerationDeep Learning JP
 
2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation
2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation
2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentationTakuya Minagawa
 
The boolean operation for Cubic Bezier
The boolean operation for Cubic BezierThe boolean operation for Cubic Bezier
The boolean operation for Cubic Beziermikanplus
 
QGIS2.18 ラスタ編
QGIS2.18 ラスタ編QGIS2.18 ラスタ編
QGIS2.18 ラスタ編Jyun Tanaka
 
DeepPose: Human Pose Estimation via Deep Neural Networks
DeepPose: Human Pose Estimation via Deep Neural NetworksDeepPose: Human Pose Estimation via Deep Neural Networks
DeepPose: Human Pose Estimation via Deep Neural NetworksShunta Saito
 
VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成
VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成
VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成Hiroshi Yamaguchi
 
パース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifuji
パース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifujiパース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifuji
パース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifujiKIT Cognitive Interaction Design
 
カッパ(妖怪)の生息適地マップ作成入門
カッパ(妖怪)の生息適地マップ作成入門カッパ(妖怪)の生息適地マップ作成入門
カッパ(妖怪)の生息適地マップ作成入門Mizutani Takayuki
 
object detection with lidar-camera fusion: survey
object detection with lidar-camera fusion: surveyobject detection with lidar-camera fusion: survey
object detection with lidar-camera fusion: surveyTakuya Minagawa
 
研究に使える便利なフリーソフト ImageJ
研究に使える便利なフリーソフト ImageJ研究に使える便利なフリーソフト ImageJ
研究に使える便利なフリーソフト ImageJYutaka KATAYAMA
 
リクルートにおける画像解析事例紹介
リクルートにおける画像解析事例紹介リクルートにおける画像解析事例紹介
リクルートにおける画像解析事例紹介Recruit Technologies
 

What's hot (20)

3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)3次元レジストレーション(PCLデモとコード付き)
3次元レジストレーション(PCLデモとコード付き)
 
LiDAR点群とSfM点群との位置合わせ
LiDAR点群とSfM点群との位置合わせLiDAR点群とSfM点群との位置合わせ
LiDAR点群とSfM点群との位置合わせ
 
QGIS初級編2018
QGIS初級編2018QGIS初級編2018
QGIS初級編2018
 
サルでもわかるディープラーニング入門 (2017年) (In Japanese)
サルでもわかるディープラーニング入門 (2017年) (In Japanese)サルでもわかるディープラーニング入門 (2017年) (In Japanese)
サルでもわかるディープラーニング入門 (2017年) (In Japanese)
 
深層学習によるHuman Pose Estimationの基礎
深層学習によるHuman Pose Estimationの基礎深層学習によるHuman Pose Estimationの基礎
深層学習によるHuman Pose Estimationの基礎
 
第1回 配信講義 計算科学技術特論B(2022)
第1回 配信講義 計算科学技術特論B(2022)第1回 配信講義 計算科学技術特論B(2022)
第1回 配信講義 計算科学技術特論B(2022)
 
[DL輪読会]Graph R-CNN for Scene Graph Generation
[DL輪読会]Graph R-CNN for Scene Graph Generation[DL輪読会]Graph R-CNN for Scene Graph Generation
[DL輪読会]Graph R-CNN for Scene Graph Generation
 
2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation
2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation
2018/12/28 LiDARで取得した道路上点群に対するsemantic segmentation
 
The boolean operation for Cubic Bezier
The boolean operation for Cubic BezierThe boolean operation for Cubic Bezier
The boolean operation for Cubic Bezier
 
QGIS2.18 ラスタ編
QGIS2.18 ラスタ編QGIS2.18 ラスタ編
QGIS2.18 ラスタ編
 
DeepPose: Human Pose Estimation via Deep Neural Networks
DeepPose: Human Pose Estimation via Deep Neural NetworksDeepPose: Human Pose Estimation via Deep Neural Networks
DeepPose: Human Pose Estimation via Deep Neural Networks
 
VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成
VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成
VisualSFMとMeshLabとCloudCompareによるドローン撮影画像を用いたデジタル地図作成
 
強化学習1章
強化学習1章強化学習1章
強化学習1章
 
グラフを扱おう:最短路問題
グラフを扱おう:最短路問題グラフを扱おう:最短路問題
グラフを扱おう:最短路問題
 
パース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifuji
パース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifujiパース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifuji
パース哲学への出会いからアブダクション実装までの道程 國藤 進 From peirce to abduction by susumu kunifuji
 
カッパ(妖怪)の生息適地マップ作成入門
カッパ(妖怪)の生息適地マップ作成入門カッパ(妖怪)の生息適地マップ作成入門
カッパ(妖怪)の生息適地マップ作成入門
 
object detection with lidar-camera fusion: survey
object detection with lidar-camera fusion: surveyobject detection with lidar-camera fusion: survey
object detection with lidar-camera fusion: survey
 
Digitaltransformation Journey
Digitaltransformation JourneyDigitaltransformation Journey
Digitaltransformation Journey
 
研究に使える便利なフリーソフト ImageJ
研究に使える便利なフリーソフト ImageJ研究に使える便利なフリーソフト ImageJ
研究に使える便利なフリーソフト ImageJ
 
リクルートにおける画像解析事例紹介
リクルートにおける画像解析事例紹介リクルートにおける画像解析事例紹介
リクルートにおける画像解析事例紹介
 

Viewers also liked

Android lint-srp-practice
Android lint-srp-practiceAndroid lint-srp-practice
Android lint-srp-practicecch-robo
 
実践アニメーション
実践アニメーション実践アニメーション
実践アニメーションNaoya Yunoue
 
全てSになる -RxJavaとLWSを持ち込む楽しさ-
全てSになる -RxJavaとLWSを持ち込む楽しさ-全てSになる -RxJavaとLWSを持ち込む楽しさ-
全てSになる -RxJavaとLWSを持ち込む楽しさ-Ryutaro Miyashita
 
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigiReact Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigiYukiya Nakagawa
 
What is tested by pre-launch (security) reports?
What is tested by pre-launch (security) reports?What is tested by pre-launch (security) reports?
What is tested by pre-launch (security) reports?ak_shio_555
 
Androidアプリのストレージ戦略
Androidアプリのストレージ戦略Androidアプリのストレージ戦略
Androidアプリのストレージ戦略Masahiro Hidaka
 
minneにおけるテスト〜リリース〜リリース後にやっている事の紹介
minneにおけるテスト〜リリース〜リリース後にやっている事の紹介minneにおけるテスト〜リリース〜リリース後にやっている事の紹介
minneにおけるテスト〜リリース〜リリース後にやっている事の紹介Masataka Kono
 
suzukishoten Jaws 201703 launch session
suzukishoten Jaws 201703 launch sessionsuzukishoten Jaws 201703 launch session
suzukishoten Jaws 201703 launch sessionkonbu_wakayama
 
プロダクトを育てるのにGoogleのサービスが助けてくれること
プロダクトを育てるのにGoogleのサービスが助けてくれることプロダクトを育てるのにGoogleのサービスが助けてくれること
プロダクトを育てるのにGoogleのサービスが助けてくれることTakao Sumitomo
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
用途に合わせたアニメーションの実装方法
用途に合わせたアニメーションの実装方法用途に合わせたアニメーションの実装方法
用途に合わせたアニメーションの実装方法Takao Sumitomo
 
How to design smart tourism destination: From viewpoint of data
How to design smart tourism destination: From viewpoint of dataHow to design smart tourism destination: From viewpoint of data
How to design smart tourism destination: From viewpoint of dataHidekazu Kasahara
 
AdapterToolboxでRecyclerViewを楽にする
AdapterToolboxでRecyclerViewを楽にするAdapterToolboxでRecyclerViewを楽にする
AdapterToolboxでRecyclerViewを楽にするTakao Sumitomo
 
クックパッドのグロースハックについて 20140610 ver1.2(更新版)
クックパッドのグロースハックについて 20140610 ver1.2(更新版)クックパッドのグロースハックについて 20140610 ver1.2(更新版)
クックパッドのグロースハックについて 20140610 ver1.2(更新版)Kato Kyosuke
 
KARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalati
KARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalatiKARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalati
KARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalatiKarma Metall
 
Al arabibiyyah-bayna-yadaik-1-a-compressed
Al arabibiyyah-bayna-yadaik-1-a-compressedAl arabibiyyah-bayna-yadaik-1-a-compressed
Al arabibiyyah-bayna-yadaik-1-a-compressedMakhfudh Sidiq
 

Viewers also liked (16)

Android lint-srp-practice
Android lint-srp-practiceAndroid lint-srp-practice
Android lint-srp-practice
 
実践アニメーション
実践アニメーション実践アニメーション
実践アニメーション
 
全てSになる -RxJavaとLWSを持ち込む楽しさ-
全てSになる -RxJavaとLWSを持ち込む楽しさ-全てSになる -RxJavaとLWSを持ち込む楽しさ-
全てSになる -RxJavaとLWSを持ち込む楽しさ-
 
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigiReact Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi
 
What is tested by pre-launch (security) reports?
What is tested by pre-launch (security) reports?What is tested by pre-launch (security) reports?
What is tested by pre-launch (security) reports?
 
Androidアプリのストレージ戦略
Androidアプリのストレージ戦略Androidアプリのストレージ戦略
Androidアプリのストレージ戦略
 
minneにおけるテスト〜リリース〜リリース後にやっている事の紹介
minneにおけるテスト〜リリース〜リリース後にやっている事の紹介minneにおけるテスト〜リリース〜リリース後にやっている事の紹介
minneにおけるテスト〜リリース〜リリース後にやっている事の紹介
 
suzukishoten Jaws 201703 launch session
suzukishoten Jaws 201703 launch sessionsuzukishoten Jaws 201703 launch session
suzukishoten Jaws 201703 launch session
 
プロダクトを育てるのにGoogleのサービスが助けてくれること
プロダクトを育てるのにGoogleのサービスが助けてくれることプロダクトを育てるのにGoogleのサービスが助けてくれること
プロダクトを育てるのにGoogleのサービスが助けてくれること
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
用途に合わせたアニメーションの実装方法
用途に合わせたアニメーションの実装方法用途に合わせたアニメーションの実装方法
用途に合わせたアニメーションの実装方法
 
How to design smart tourism destination: From viewpoint of data
How to design smart tourism destination: From viewpoint of dataHow to design smart tourism destination: From viewpoint of data
How to design smart tourism destination: From viewpoint of data
 
AdapterToolboxでRecyclerViewを楽にする
AdapterToolboxでRecyclerViewを楽にするAdapterToolboxでRecyclerViewを楽にする
AdapterToolboxでRecyclerViewを楽にする
 
クックパッドのグロースハックについて 20140610 ver1.2(更新版)
クックパッドのグロースハックについて 20140610 ver1.2(更新版)クックパッドのグロースハックについて 20140610 ver1.2(更新版)
クックパッドのグロースハックについて 20140610 ver1.2(更新版)
 
KARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalati
KARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalatiKARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalati
KARMA METAL Insaat malzeme tasima kasasi Metal istifleme konteynerleri imalati
 
Al arabibiyyah-bayna-yadaik-1-a-compressed
Al arabibiyyah-bayna-yadaik-1-a-compressedAl arabibiyyah-bayna-yadaik-1-a-compressed
Al arabibiyyah-bayna-yadaik-1-a-compressed
 

Similar to Viewを動的に変化させるアプローチ

(beta)アプリを成長させるためのログ取りとログ解析に必要なこと
(beta)アプリを成長させるためのログ取りとログ解析に必要なこと(beta)アプリを成長させるためのログ取りとログ解析に必要なこと
(beta)アプリを成長させるためのログ取りとログ解析に必要なことTakao Sumitomo
 
アプリを成長させるためのログ取りとログ解析に必要なこと
アプリを成長させるためのログ取りとログ解析に必要なことアプリを成長させるためのログ取りとログ解析に必要なこと
アプリを成長させるためのログ取りとログ解析に必要なことTakao Sumitomo
 
MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴
MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴
MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴Daiji Hirata
 
HTML5でFirefox OSアプリを作ろう
HTML5でFirefox OSアプリを作ろうHTML5でFirefox OSアプリを作ろう
HTML5でFirefox OSアプリを作ろうTakao Sumitomo
 
XRにおけるプロトタイピングについて
XRにおけるプロトタイピングについてXRにおけるプロトタイピングについて
XRにおけるプロトタイピングについてWheetTweet
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 Hiroshi Ito
 
MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6
MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6
MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6Daiji Hirata
 
Mulvery@沖縄Ruby会議02
Mulvery@沖縄Ruby会議02Mulvery@沖縄Ruby会議02
Mulvery@沖縄Ruby会議02Daichi Teruya
 
Movable type 6 Overview (2013.10.24)
Movable type 6 Overview (2013.10.24)Movable type 6 Overview (2013.10.24)
Movable type 6 Overview (2013.10.24)Daiji Hirata
 
詳説 Data api mtddc 拡張版 v3対応
詳説 Data api mtddc 拡張版   v3対応詳説 Data api mtddc 拡張版   v3対応
詳説 Data api mtddc 拡張版 v3対応Yuji Takayama
 
HTML5 conference 2013
HTML5 conference 2013HTML5 conference 2013
HTML5 conference 2013Takuo Kihira
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」Hiroyuki Ohnaka
 
インフォグラフィックス時代のD3.js入門
インフォグラフィックス時代のD3.js入門インフォグラフィックス時代のD3.js入門
インフォグラフィックス時代のD3.js入門貴寛 益子
 
ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2
ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2
ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2Sei Kato (加藤 整)
 
2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」
2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」
2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」aitc_jp
 
RxSwiftのデータバインディングだけ
RxSwiftのデータバインディングだけRxSwiftのデータバインディングだけ
RxSwiftのデータバインディングだけHironytic
 
html5とcss3実例紹介とデモ
html5とcss3実例紹介とデモhtml5とcss3実例紹介とデモ
html5とcss3実例紹介とデモAkihiro Sugiyama
 
Power BI のいろいろな活用パターン
Power BI のいろいろな活用パターンPower BI のいろいろな活用パターン
Power BI のいろいろな活用パターンYugo Shimizu
 
ヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnight
ヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnightヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnight
ヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnightYahoo!デベロッパーネットワーク
 
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみようPreview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみようDaisuke Masubuchi
 

Similar to Viewを動的に変化させるアプローチ (20)

(beta)アプリを成長させるためのログ取りとログ解析に必要なこと
(beta)アプリを成長させるためのログ取りとログ解析に必要なこと(beta)アプリを成長させるためのログ取りとログ解析に必要なこと
(beta)アプリを成長させるためのログ取りとログ解析に必要なこと
 
アプリを成長させるためのログ取りとログ解析に必要なこと
アプリを成長させるためのログ取りとログ解析に必要なことアプリを成長させるためのログ取りとログ解析に必要なこと
アプリを成長させるためのログ取りとログ解析に必要なこと
 
MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴
MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴
MTDDC 2013: Movable Type 6: 新しいMovable Typeのコンセプトと特徴
 
HTML5でFirefox OSアプリを作ろう
HTML5でFirefox OSアプリを作ろうHTML5でFirefox OSアプリを作ろう
HTML5でFirefox OSアプリを作ろう
 
XRにおけるプロトタイピングについて
XRにおけるプロトタイピングについてXRにおけるプロトタイピングについて
XRにおけるプロトタイピングについて
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
 
MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6
MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6
MTDDC Meetup HOKKAIDO 2013 KEYNOTE - Movable Type 6
 
Mulvery@沖縄Ruby会議02
Mulvery@沖縄Ruby会議02Mulvery@沖縄Ruby会議02
Mulvery@沖縄Ruby会議02
 
Movable type 6 Overview (2013.10.24)
Movable type 6 Overview (2013.10.24)Movable type 6 Overview (2013.10.24)
Movable type 6 Overview (2013.10.24)
 
詳説 Data api mtddc 拡張版 v3対応
詳説 Data api mtddc 拡張版   v3対応詳説 Data api mtddc 拡張版   v3対応
詳説 Data api mtddc 拡張版 v3対応
 
HTML5 conference 2013
HTML5 conference 2013HTML5 conference 2013
HTML5 conference 2013
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
 
インフォグラフィックス時代のD3.js入門
インフォグラフィックス時代のD3.js入門インフォグラフィックス時代のD3.js入門
インフォグラフィックス時代のD3.js入門
 
ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2
ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2
ポストAiを見据えた日本企業の経営戦略 加藤整 20171020_v1.2
 
2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」
2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」
2015年7月期AITC女子会「D3.js/Highchartsによるデータの可視化」
 
RxSwiftのデータバインディングだけ
RxSwiftのデータバインディングだけRxSwiftのデータバインディングだけ
RxSwiftのデータバインディングだけ
 
html5とcss3実例紹介とデモ
html5とcss3実例紹介とデモhtml5とcss3実例紹介とデモ
html5とcss3実例紹介とデモ
 
Power BI のいろいろな活用パターン
Power BI のいろいろな活用パターンPower BI のいろいろな活用パターン
Power BI のいろいろな活用パターン
 
ヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnight
ヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnightヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnight
ヤフーのロギングSDKの挑戦〜データドリブン企業を目指して〜 #yjdsnight
 
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみようPreview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
 

More from Takao Sumitomo

僕は上スワイプでBottomSheetを出したかっただけなんだ
僕は上スワイプでBottomSheetを出したかっただけなんだ僕は上スワイプでBottomSheetを出したかっただけなんだ
僕は上スワイプでBottomSheetを出したかっただけなんだTakao Sumitomo
 
sharedUserIdを使った俺得開発ツールの作り方
sharedUserIdを使った俺得開発ツールの作り方sharedUserIdを使った俺得開発ツールの作り方
sharedUserIdを使った俺得開発ツールの作り方Takao Sumitomo
 
CIのビルドを通知する仕組みをAndroidとFirestoreで作った話
CIのビルドを通知する仕組みをAndroidとFirestoreで作った話CIのビルドを通知する仕組みをAndroidとFirestoreで作った話
CIのビルドを通知する仕組みをAndroidとFirestoreで作った話Takao Sumitomo
 
Camera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンド
Camera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンドCamera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンド
Camera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンドTakao Sumitomo
 
高速でトライ&エラーを するために気をつけてること
高速でトライ&エラーを するために気をつけてること高速でトライ&エラーを するために気をつけてること
高速でトライ&エラーを するために気をつけてることTakao Sumitomo
 
Maker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきた
Maker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきたMaker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきた
Maker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきたTakao Sumitomo
 
エンジニアがプロダクト育成を始めるまでにやったこと
エンジニアがプロダクト育成を始めるまでにやったことエンジニアがプロダクト育成を始めるまでにやったこと
エンジニアがプロダクト育成を始めるまでにやったことTakao Sumitomo
 
Wantedlyのテスト事情
Wantedlyのテスト事情Wantedlyのテスト事情
Wantedlyのテスト事情Takao Sumitomo
 
potatotips (iOS/Android開発Tips共有会) 第19回 資料
potatotips (iOS/Android開発Tips共有会) 第19回 資料potatotips (iOS/Android開発Tips共有会) 第19回 資料
potatotips (iOS/Android開発Tips共有会) 第19回 資料Takao Sumitomo
 
SQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗くSQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗くTakao Sumitomo
 
開発を効率的に進めるられるまでの道程
開発を効率的に進めるられるまでの道程開発を効率的に進めるられるまでの道程
開発を効率的に進めるられるまでの道程Takao Sumitomo
 
テストがあればなんとかなる〜効率化までの道程〜
テストがあればなんとかなる〜効率化までの道程〜テストがあればなんとかなる〜効率化までの道程〜
テストがあればなんとかなる〜効率化までの道程〜Takao Sumitomo
 
勉強会資料 データ構造とアルゴリズム
勉強会資料 データ構造とアルゴリズム勉強会資料 データ構造とアルゴリズム
勉強会資料 データ構造とアルゴリズムTakao Sumitomo
 
勉強会資料 Uml概要
勉強会資料 Uml概要勉強会資料 Uml概要
勉強会資料 Uml概要Takao Sumitomo
 
Firefox OSの何が嬉しいか
Firefox OSの何が嬉しいかFirefox OSの何が嬉しいか
Firefox OSの何が嬉しいかTakao Sumitomo
 
フォクすけロボ開発進捗報告
フォクすけロボ開発進捗報告フォクすけロボ開発進捗報告
フォクすけロボ開発進捗報告Takao Sumitomo
 
今更ながらCSS3を試してみた
今更ながらCSS3を試してみた今更ながらCSS3を試してみた
今更ながらCSS3を試してみたTakao Sumitomo
 
Crystalskullを改造してみる
Crystalskullを改造してみるCrystalskullを改造してみる
Crystalskullを改造してみるTakao Sumitomo
 
もしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったら
もしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったらもしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったら
もしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったらTakao Sumitomo
 

More from Takao Sumitomo (20)

僕は上スワイプでBottomSheetを出したかっただけなんだ
僕は上スワイプでBottomSheetを出したかっただけなんだ僕は上スワイプでBottomSheetを出したかっただけなんだ
僕は上スワイプでBottomSheetを出したかっただけなんだ
 
sharedUserIdを使った俺得開発ツールの作り方
sharedUserIdを使った俺得開発ツールの作り方sharedUserIdを使った俺得開発ツールの作り方
sharedUserIdを使った俺得開発ツールの作り方
 
CIのビルドを通知する仕組みをAndroidとFirestoreで作った話
CIのビルドを通知する仕組みをAndroidとFirestoreで作った話CIのビルドを通知する仕組みをAndroidとFirestoreで作った話
CIのビルドを通知する仕組みをAndroidとFirestoreで作った話
 
Camera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンド
Camera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンドCamera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンド
Camera API 1と2が混在するプロダクトの開発で 泣いたこととそのワークアラウンド
 
高速でトライ&エラーを するために気をつけてること
高速でトライ&エラーを するために気をつけてること高速でトライ&エラーを するために気をつけてること
高速でトライ&エラーを するために気をつけてること
 
Maker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきた
Maker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきたMaker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきた
Maker Faire Bay Areaに行きたかったのでGoogle I/Oに行ってきた
 
エンジニアがプロダクト育成を始めるまでにやったこと
エンジニアがプロダクト育成を始めるまでにやったことエンジニアがプロダクト育成を始めるまでにやったこと
エンジニアがプロダクト育成を始めるまでにやったこと
 
Wantedlyのテスト事情
Wantedlyのテスト事情Wantedlyのテスト事情
Wantedlyのテスト事情
 
Uml速習会
Uml速習会Uml速習会
Uml速習会
 
potatotips (iOS/Android開発Tips共有会) 第19回 資料
potatotips (iOS/Android開発Tips共有会) 第19回 資料potatotips (iOS/Android開発Tips共有会) 第19回 資料
potatotips (iOS/Android開発Tips共有会) 第19回 資料
 
SQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗くSQLiteDatabaseを無理矢理覗く
SQLiteDatabaseを無理矢理覗く
 
開発を効率的に進めるられるまでの道程
開発を効率的に進めるられるまでの道程開発を効率的に進めるられるまでの道程
開発を効率的に進めるられるまでの道程
 
テストがあればなんとかなる〜効率化までの道程〜
テストがあればなんとかなる〜効率化までの道程〜テストがあればなんとかなる〜効率化までの道程〜
テストがあればなんとかなる〜効率化までの道程〜
 
勉強会資料 データ構造とアルゴリズム
勉強会資料 データ構造とアルゴリズム勉強会資料 データ構造とアルゴリズム
勉強会資料 データ構造とアルゴリズム
 
勉強会資料 Uml概要
勉強会資料 Uml概要勉強会資料 Uml概要
勉強会資料 Uml概要
 
Firefox OSの何が嬉しいか
Firefox OSの何が嬉しいかFirefox OSの何が嬉しいか
Firefox OSの何が嬉しいか
 
フォクすけロボ開発進捗報告
フォクすけロボ開発進捗報告フォクすけロボ開発進捗報告
フォクすけロボ開発進捗報告
 
今更ながらCSS3を試してみた
今更ながらCSS3を試してみた今更ながらCSS3を試してみた
今更ながらCSS3を試してみた
 
Crystalskullを改造してみる
Crystalskullを改造してみるCrystalskullを改造してみる
Crystalskullを改造してみる
 
もしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったら
もしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったらもしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったら
もしソフトウェアディベロッパーが3Dプリンターで『フォクすけ』を作ったら
 

Recently uploaded

クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成Hiroshi Tomioka
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 

Recently uploaded (9)

クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版) 2024年4月作成
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 

Viewを動的に変化させるアプローチ

  • 1. DroidKaigi 2017 - 2017/03/09 @cattaka_net Viewを動的に 変化させるアプローチ Takao Sumitomo @cattaka_net
  • 2. DroidKaigi 2017 - 2017/03/09 @cattaka_net 自己紹介 ● 住友 孝郎(Takao Sumitomo) ● Androidアプリ開発者 ● 今やってること ● Androidアプリケーション ● 昔やってたこと ● いろいろ(MFCとかStrutsとか) ● ウォンテッドリー株式会社所属 ● 2014年12月〜 ● それ以前は関西で仕事してた
  • 3. DroidKaigi 2017 - 2017/03/09 @cattaka_net 直近のアプリ かしこく、名刺管理 人工知能を搭載したカメ ラで、10枚までの名刺を わずか3秒でデータ化、そ して管理可能な、無料で 使えるビジネスパーソン向 けのアプリです。
  • 4. DroidKaigi 2017 - 2017/03/09 @cattaka_net 発表の内容 ● お題 ● ユーザーの操作に追従させたい ● キーワード ● DataBinding ● ConstraintLayout ● Material Designに特化した話ではなく、どう実装 するかのお話
  • 5. DroidKaigi 2017 - 2017/03/09 @cattaka_net 標準APIとSupport Libraryで できること
  • 6. DroidKaigi 2017 - 2017/03/09 @cattaka_net アニメーション ● ViewPagerの切替時 ● FABが操作の完了時に 出てくる
  • 7. DroidKaigi 2017 - 2017/03/09 @cattaka_net AppBarLayout ● 一定以上スクロールす ると、色が変わる ● タイトルのみ動かせる ● 補足:このサンプルはバ グのため動かせなかっ た、、
  • 8. DroidKaigi 2017 - 2017/03/09 @cattaka_net やりたいこと ユーザーの操作に追従させたい
  • 9. DroidKaigi 2017 - 2017/03/09 @cattaka_net 今回の話のゴール
  • 10. DroidKaigi 2017 - 2017/03/09 @cattaka_net 実装アプローチのイメージ ● 意識するのは3つ ● 操作イベント ● 属性値の計算 ● Viewの更新 操作イベント 属性値の計算 Viewの更新
  • 11. DroidKaigi 2017 - 2017/03/09 @cattaka_net この3つを見ていきます 操作イベント 属性値の計算 Viewの更新
  • 12. DroidKaigi 2017 - 2017/03/09 @cattaka_net 何を操作イベントとする? 操作イベント 属性値の計算 Viewの更新
  • 13. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 タッチイベントは辛い ● タッチイベントは種類がいっぱい ● 全部で何個種類があるか全部言える人いる? ● マルチタッチになるとどうなる? ● ネステッドスクロールはさらに難解 ● flingが入るともうカオス ● CoordinatorLayoutのBehaviorも同じ
  • 14. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 無難なイベント ● スクロールイベント系 ● ScrollView ● RecyclerView ● AppBarLayout ● レイアウト系イベント ● OnLayoutChangeListener ● OnGlobalLayoutListener – ただし注意しないとループに嵌まる
  • 15. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 よくよく考えると ● タッチ操作でViewを変化させるというより ● 他のViewに合わせて動くと考えるほうが自然 ViewPagerで 発生したイベント 表示を更新 表示を更新 スクロール量から 計算
  • 16. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 Viewの属性値の計算はどこでやる?
  • 17. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 コードでゴリゴリやる ● 行数が増えがちになる ● コードを読まないとどういう動きかわからない ● なのであまりやりたくない
  • 18. DroidKaigi 2017 - 2017/03/09 @cattaka_net 属性値の計算は分けて考える ● スクロール量などの値を正規化した値にする ● 具体的な属性値への計算は別途やる 0.0〜1.0に なるように 0.0〜3.0になるように
  • 19. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 ViewPagerでの計算 ● タブは0.0〜3.0の値か ら計算 ● FABは0.0〜1.0の値か ら計算
  • 20. DroidKaigi 2017 - 2017/03/09 @cattaka_net ViewPagerでの計算 @Override public void onPageScrolled( int position, // 0,1,2などのページ番号 float positionOffset, // 0.0〜1.0の範囲のオフセット int positionOffsetPixels) { float absolutePosition = position + positionOffset; float fabFactor = (position == 0) ? positionOffset : 1; /* 省略 */ } 本質はここ 0.0〜3.0 の値を算出
  • 21. DroidKaigi 2017 - 2017/03/09 @cattaka_net ViewPagerでの計算 1ページ目のみ 0.0〜1.0 の値が欲しい @Override public void onPageScrolled( int position, // 0,1,2などのページ番号 float positionOffset, // 0.0〜1.0の範囲のオフセット int positionOffsetPixels) { float absolutePosition = position + positionOffset; float fabFactor = (position == 0) ? positionOffset : 1; /* 省略 */ }
  • 22. DroidKaigi 2017 - 2017/03/09 @cattaka_net ScrollViewでの計算 ● 0.0〜1.0の値から諸々の 属性値を計算する ● ActionBar ● タイトル – 座標と色 ● アイコン ● その他のテキスト – 座標と色
  • 23. DroidKaigi 2017 - 2017/03/09 @cattaka_net ScrollViewでの計算 @Override public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { int h = mBinding.layoutContents.image.getHeight(); float factor = (h > 0) ? (float) scrollY / h : 0f; if (factor < 0f) { factor = 0f; } else if (factor > 1f) { factor = 1f; } /* 省略 */ } 本質はここ 0.0〜1.0 の値を算出
  • 24. DroidKaigi 2017 - 2017/03/09 @cattaka_net ScrollViewでの計算 @Override public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { int h = mBinding.layoutContents.image.getHeight(); float factor = (h > 0) ? (float) scrollY / h : 0f; if (factor < 0f) { factor = 0f; } else if (factor > 1f) { factor = 1f; } /* 省略 */ } 0除算に注意
  • 25. DroidKaigi 2017 - 2017/03/09 @cattaka_net Viewに設定する属性値の計算 ● 対象となる属性 ● alpha ● width / height ● translationX / translationY ● scaleX / scaleY ● textSize ● etc ● この辺りの計算はDataBindingの計算が便利
  • 26. DroidKaigi 2017 - 2017/03/09 @cattaka_net Viewの更新のアプローチ 操作イベント 属性値の計算 Viewの更新
  • 27. DroidKaigi 2017 - 2017/03/09 @cattaka_net 操作イベント 属性値の計算 Viewの更新 DataBindingが強い ● 変数を渡せる ● 計算式が書ける
  • 28. DroidKaigi 2017 - 2017/03/09 @cattaka_net DataBindingの変数 <layout> <data> <variable name="fabFactor" type="float" /> </data> <RelativeLayout android:id="@+id/layout"> <!-- 省略 --> </RelativeLayout> </layout> mBinding.setFabFactor(fabFactor); layout xmlでの定義 Java側から渡す xmlで定義すると setterが作られる
  • 29. DroidKaigi 2017 - 2017/03/09 @cattaka_net DataBindingで計算 <android.support.design.widget.FloatingActionButton android:id="@+id/button_search" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:translationY="@{fabFactor *  @dimen/fab_offset}" /> dimenの値に掛け算で 楽に設定できる ※:@dimen/fab_offset より良い方法を後述
  • 30. DroidKaigi 2017 - 2017/03/09 @cattaka_net 具体的な例
  • 31. DroidKaigi 2017 - 2017/03/09 @cattaka_net FABの現れ方 ● 完全に隠れるには 親のheight - 自分のtop が必要になる 自分のtop 親のheight これ
  • 32. DroidKaigi 2017 - 2017/03/09 @cattaka_net FABの現れ方 <RelativeLayout android:id="@+id/layout"> <!-- 他のViewは省略 --> <android.support.design.widget.FloatingActionButton android:id="@+id/button_search" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:translationY="@{fabFactor * (layout.getHeight() - buttonSearch.getTop())}" /> </RelativeLayout> translationYに 必要な値をここで計算
  • 33. DroidKaigi 2017 - 2017/03/09 @cattaka_net タブの動き ● 文字サイズを変える ● 背景色を変える ● elevationを変える ● 幅を変える
  • 34. DroidKaigi 2017 - 2017/03/09 @cattaka_net タブの動き <TextView     android:id="@+id/tab_0"     android:layout_width="0dp"     android:layout_height="match_parent"     android:layout_weight="1"     android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"     android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"     android:gravity="center"     android:text="List"     android:textAppearance="?android:textAppearanceMedium"     android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"     app:layout_constraintBottom_toBottomOf="parent"     app:layout_constraintEnd_toStartOf="@+id/tab_1"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="parent"     app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}" />
  • 35. DroidKaigi 2017 - 2017/03/09 @cattaka_net タブの動き:文字サイズを変える <TextView     android:id="@+id/tab_0"     android:layout_width="0dp"     android:layout_height="match_parent"     android:layout_weight="1"     android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"     android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"     android:gravity="center"     android:text="List"     android:textAppearance="?android:textAppearanceMedium"     android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"     app:layout_constraintBottom_toBottomOf="parent"     app:layout_constraintEnd_toStartOf="@+id/tab_1"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="parent"     app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}" /> android:textSize="@{ DataBindingFunctions.evaluateFactor( position, ←スクロール位置(0.0〜3.0) 0f, ←対象タブの番号(0,1,2) @dimen/text_tab_small,←未選択時のサイズ @dimen/text_tab_large ←選択時のサイズ )}" 独自の補間用メソッド
  • 36. DroidKaigi 2017 - 2017/03/09 @cattaka_net タブの動き:背景色を変える <TextView     android:id="@+id/tab_0"     android:layout_width="0dp"     android:layout_height="match_parent"     android:layout_weight="1"     android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"     android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"     android:gravity="center"     android:text="List"     android:textAppearance="?android:textAppearanceMedium"     android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"     app:layout_constraintBottom_toBottomOf="parent"     app:layout_constraintEnd_toStartOf="@+id/tab_1"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="parent"     app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}" /> android:background="@{ DataBindingFunctions.evaluateColor( position, ←スクロール位置(0.0〜3.0) 0f, ←対象タブの番号(0,1,2) @color/bgTab, ←未選択時の色 @color/bgTabSelected ←選択時の色 )}" 独自の補間用メソッド
  • 37. DroidKaigi 2017 - 2017/03/09 @cattaka_net タブの動き:elevationを変える <TextView     android:id="@+id/tab_0"     android:layout_width="0dp"     android:layout_height="match_parent"     android:layout_weight="1"     android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"     android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"     android:gravity="center"     android:text="List"     android:textAppearance="?android:textAppearanceMedium"     android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"     app:layout_constraintBottom_toBottomOf="parent"     app:layout_constraintEnd_toStartOf="@+id/tab_1"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="parent"     app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}" /> android:elevation="@{ DataBindingFunctions.evaluateFactor( position, ←スクロール位置(0.0〜3.0) 0f, ←対象タブの番号(0,1,2) 0f, ←未選択時の値 @dimen/elevation_tab ←選択時の値 )}" 独自の補間用メソッド
  • 38. DroidKaigi 2017 - 2017/03/09 @cattaka_net タブの動き:幅を変える <TextView     android:id="@+id/tab_0"     android:layout_width="0dp"     android:layout_height="match_parent"     android:layout_weight="1"     android:background="@{DataBindingFunctions.evaluateColor(position, 0f, @color/bgTab, @color/bgTabSelected)}"     android:elevation="@{DataBindingFunctions.evaluateFactor(position, 0f, 0f, @dimen/elevation_tab)}"     android:gravity="center"     android:text="List"     android:textAppearance="?android:textAppearanceMedium"     android:textSize="@{DataBindingFunctions.evaluateFactor(position, 0f, @dimen/text_tab_small, @dimen/text_tab_large)}"     app:layout_constraintBottom_toBottomOf="parent"     app:layout_constraintEnd_toStartOf="@+id/tab_1"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="parent"     app:setLayoutWeight="@{DataBindingFunctions.evaluateFactor(position, 0f, 3f, 4f)}" /> app:setLayoutWeight="@{ DataBindingFunctions.evaluateFactor( position, ←スクロール位置(0.0〜3.0) 0f, ←対象タブの番号(0,1,2) 3f, ←未選択時のlayout_weight 4f ←選択時のlayout_weight )}" 独自の補間用メソッド 独自のlayout_weight指定用メソッド(後述)
  • 39. DroidKaigi 2017 - 2017/03/09 @cattaka_net DataBindingの制限 ● LayoutParamに直接的に値を設定できない ● xml上で android:layout_***** となっているもの ● BindingAdapter用のメソッドを作ればできる @BindingAdapter("setLayoutWeight") public static void setLayoutWeight(View view, float value) { ViewGroup.LayoutParams params = view.getLayoutParams(); if (params instanceof LinearLayout.LayoutParams) { ((LinearLayout.LayoutParams) params).weight = value; view.setLayoutParams(params); } }
  • 40. DroidKaigi 2017 - 2017/03/09 @cattaka_net CollapsingToolbarLayout みたいなことをやる ● アイコンを動かす ● テキストを動かす ● ステータスバーの色を 変える
  • 41. DroidKaigi 2017 - 2017/03/09 @cattaka_net アイコンを動かす <ImageView     android:id="@+id/image_icon"     android:layout_width="?android:actionBarSize"     android:layout_height="?android:actionBarSize"     android:background="@drawable/oval_fill_white"     android:padding="4dp"     android:scaleType="centerCrop"     android:scaleX="@{2f-scrollFactor}"     android:scaleY="@{2f-scrollFactor}"     app:layout_constraintBottom_toBottomOf="@+id/dummy_action_bar"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="@+id/dummy_action_bar"     app:loadImage="@{item.file}"     app:loadImageTransformation="@{CircleTransform.instance}"     app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/icon_offset_x)}"     app:setLayoutMarginTop="@{(int)((1f-scrollFactor) * @dimen/icon_offset_y)}"     app:useFit="@{false}"     tools:layout_marginStart="@dimen/icon_offset_x"     tools:layout_marginTop="@dimen/icon_offset_y"     tools:scaleX="2"     tools:scaleY="2"     tools:src="@drawable/dummy_icon" />
  • 42. DroidKaigi 2017 - 2017/03/09 @cattaka_net アイコンを動かす <ImageView     android:id="@+id/image_icon"     android:layout_width="?android:actionBarSize"     android:layout_height="?android:actionBarSize"     android:background="@drawable/oval_fill_white"     android:padding="4dp"     android:scaleType="centerCrop"     android:scaleX="@{2f-scrollFactor}"     android:scaleY="@{2f-scrollFactor}"     app:layout_constraintBottom_toBottomOf="@+id/dummy_action_bar"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="@+id/dummy_action_bar"     app:loadImage="@{item.file}"     app:loadImageTransformation="@{CircleTransform.instance}"     app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/icon_offset_x)}"     app:setLayoutMarginTop="@{(int)((1f-scrollFactor) * @dimen/icon_offset_y)}"     app:useFit="@{false}"     tools:layout_marginStart="@dimen/icon_offset_x"     tools:layout_marginTop="@dimen/icon_offset_y"     tools:scaleX="2"     tools:scaleY="2"     tools:src="@drawable/dummy_icon" /> android:scaleX="@{2f-scrollFactor}" android:scaleY="@{2f-scrollFactor}" app:setLayoutMarginStart="@{ (int)((1f-scrollFactor) * @dimen/icon_offset_x) }" app:setLayoutMarginTop="@{ (int)((1f-scrollFactor) * @dimen/icon_offset_y) }"
  • 43. DroidKaigi 2017 - 2017/03/09 @cattaka_net テキストを動かす <TextView     android:id="@+id/text_name"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:text="@{item.name}"     android:textAppearance="?android:textAppearanceLarge"     android:textColor="@{DataBindingFunctions.evaluateColor(scrollFactor, @android:color/white, @android:color/black)}"     android:textSize="@{(1f-scrollFactor) * @dimen/text_title_large + scrollFactor * @dimen/text_title_small}"     app:layout_constraintBottom_toBottomOf="@+id/image_icon"     app:layout_constraintStart_toEndOf="@id/image_icon"     app:layout_constraintTop_toTopOf="@+id/image_icon"     app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/spacing_x4)}"     tools:layout_marginStart="@dimen/spacing_x4"     tools:text="Name"     tools:textColor="@android:color/white"     tools:textSize="@dimen/text_title_large" />
  • 44. DroidKaigi 2017 - 2017/03/09 @cattaka_net テキストを動かす <TextView     android:id="@+id/text_name"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:text="@{item.name}"     android:textAppearance="?android:textAppearanceLarge"     android:textColor="@{DataBindingFunctions.evaluateColor(scrollFactor, @android:color/white, @android:color/black)}"     android:textSize="@{(1f-scrollFactor) * @dimen/text_title_large + scrollFactor * @dimen/text_title_small}"     app:layout_constraintBottom_toBottomOf="@+id/image_icon"     app:layout_constraintStart_toEndOf="@id/image_icon"     app:layout_constraintTop_toTopOf="@+id/image_icon"     app:setLayoutMarginStart="@{(int)((1f-scrollFactor) * @dimen/spacing_x4)}"     tools:layout_marginStart="@dimen/spacing_x4"     tools:text="Name"     tools:textColor="@android:color/white"     tools:textSize="@dimen/text_title_large" /> android:textColor="@{ DataBindingFunctions.evaluateColor( scrollFactor, @android:color/white, @android:color/black) }" android:textSize="@{ (1f-scrollFactor) * @dimen/text_title_large + scrollFactor * @dimen/text_title_small}" app:setLayoutMarginStart="@{ (int)((1f-scrollFactor) * @dimen/spacing_x4)}"
  • 45. DroidKaigi 2017 - 2017/03/09 @cattaka_net ステータスバーの色を変える ● LOLLIPOP以降なら普通に変えられる ● FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS ※:これはDataBinding使わない int color = DataBindingFunctions.evaluateColor( factor, mOriginalStatusBarColor, mVibrantColor); Window window = getWindow(); if (window != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { window.setStatusBarColor(color); }
  • 46. DroidKaigi 2017 - 2017/03/09 @cattaka_net tip & trap
  • 47. DroidKaigi 2017 - 2017/03/09 @cattaka_net toolsNSを活用しよう ● layout xmlの最終形がイメージしづらい ● レイアウトエディタ上でイメージできるようにしよう
  • 48. DroidKaigi 2017 - 2017/03/09 @cattaka_net 表示が切れる問題 ● 親のViewGroupを飛び出すと... ● 表示が切れる ● elevationの影が切れる ● android:clipToPadding="false" で回避できる
  • 49. DroidKaigi 2017 - 2017/03/09 @cattaka_net OnLayoutChangeListenerのtrap ● 気をつけないとループに嵌まることがある ● 変更通知→レイアウト変更→変更通知→... ● フリーズはしないので知らないうちにCPUを食い潰す... ● 直前の値を保持して、不要ならメソッドを叩かない ようにする
  • 50. DroidKaigi 2017 - 2017/03/09 @cattaka_net OnGlobalLayoutListenerのtrap ● removeを忘れるとメモリリークする
  • 51. DroidKaigi 2017 - 2017/03/09 @cattaka_net ConstraintLayoutが強力 ● LayoutParamを弄ると、相対的な配置を維持したまま 動く ● layout_width ● layout_height ● layout_margin ● layout_constraintHorizontal_weight ● layout_constraintVertical_weight ● etc
  • 52. DroidKaigi 2017 - 2017/03/09 @cattaka_net ConstraintLayoutが強力 ● 例 ● 3つのテキストはアイコンに対 して相対的に動いている
  • 53. DroidKaigi 2017 - 2017/03/09 @cattaka_net ConstraintLayoutのtrap ● layout_width=0でmatch_parentと同じ挙動 ● 100dp→0dpのように動かすと、 0dpのときに突然広がる挙動をして困る ● BindingAdapterのメソッドの中で0.01などにして、 誤魔化用にすることで回避できる ● ネガティブマージンが使えない問題 ● ダミーのSpaceを挟むことで回避できる
  • 54. DroidKaigi 2017 - 2017/03/09 @cattaka_net ConstraintLayoutのtrap ● Android Studio 2.3現在 レイアウトエディタでxmlを触ると たまにxmlが壊れる(´;ω;`)
  • 55. DroidKaigi 2017 - 2017/03/09 @cattaka_net DataBindingは 暗黙的型変換をしない ● 計算でfloat, double, intの場合は明示的にキャス トが必要 ● 型が違っているとビルドエラーになる ● Java言語の仕様に従って、floatなら1.0f、double なら1.0とか書かないとダメ
  • 56. DroidKaigi 2017 - 2017/03/09 @cattaka_net 考察
  • 57. DroidKaigi 2017 - 2017/03/09 @cattaka_net DataBindingを使う理由 ● 色や大きさはXMLに入れるべきか、Javaに入れるべきか ● Javaに書くと ● 行数が増える ● xmlと距離が遠くて把握しづらい ● コードが読める人じゃないとメンテナンスできない ● DataBindingに書くと ● xmlの属性の@{...}の部分を見ればだいたいわかる ● ただ、横に長くなる...
  • 58. DroidKaigi 2017 - 2017/03/09 @cattaka_net パフォーマンスに関する考察 ● LayoutParamsをいじるのは正直重い ● LayoutParamsを変えると、measure系が走る ● ただ複数のViewが相対的に変化するならどのみち必要 ● 必要が無いならtranslateやscaleを使うほうが良 い
  • 59. DroidKaigi 2017 - 2017/03/09 @cattaka_net 工数に関すること ● 極論で言うと、タッチイベントからやるのがパフォーマ ンスが出る ● CoordinatorLayoutと同じアプローチ – すなわち、CoordinatorLayoutのBehaviorを作る ● でも難解 ● イベント+DataBindingが楽(と考える) 操作イベント 属性値の計算 Viewの更新 Behaviorだと これを全部やることになる...
  • 60. DroidKaigi 2017 - 2017/03/09 @cattaka_net まとめ
  • 61. DroidKaigi 2017 - 2017/03/09 @cattaka_net まとめ 操作イベント 属性値の計算 Viewの更新 スクロールやレイアウトイベントを トリガーにする コード側で 値を正規化する DataBindingで 具体的な値の算出と設定をする
  • 62. DroidKaigi 2017 - 2017/03/09 @cattaka_net サンプルアプリ https://github.com/cattaka/ProteanLayoutExample
  • 63. DroidKaigi 2017 - 2017/03/09 @cattaka_net ご清聴ありがとうございました Takao Sumitomo @cattaka_net