Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
小林 俊 Yahoo! JAPAN アプリエンジニア
タブブラウザSDK
を
作った話
2017年4月20日
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
アジェンダ
2
・自己紹介
・背景
・タブブラウザSDKとは
・三桁を実現させるタブの管理
・WebViewとCoordinatorLayout
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
自己紹介
3
名前:
小林 俊(こばやし しゅん)
担当サービス:
Yahoo! JAPAN アプリ
Android歴:そろそろ2年
アイマス歴:そろそろ10年
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
背景
4
Yahoo! JAPANYahoo!ブラウザ
ブラウザ機能を持つ2つのアプリ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
背景
5
Yahoo! JAPANYahoo!ブラウザ
実は、共通化されたブラウザ機能を利用
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
タブブラウザSDKとは
6
どんな機能があるの?
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
タブブラウザSDKとは
7
・WebView管理
・タブ管理
・CoordinatorLayout対応
・URLスキーマハンドリング
・ページ内検索
・標準的な振る舞いの提供
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
タブブラウザSDKとは
8
・WebView管理
・タブ管理
・CoordinatorLayout対応
・URLスキーマハンドリング
・ページ内検索
・標準的な振る舞いの提供
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
タブ管理
9
三桁を実現させるタブの管理
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
10
タブ1 タブ2 タブ3 タブN
…
WebView1
WebView2
WebView M
…
上限M
上限N
全体像
「タブの上限」と
「WebViewの上限」は別扱い
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
11
タブ1 タブ2 タブ3
上限N
WebView1
WebView2
WebView3
上限3
タブ1→2→3の順に開かれた状態
4つ目のタブを開くと?
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
12
タブ1 タブ2 タブ3
上限N
WebView2
WebView3
上限3
タブ4
New!!!
WebView4
破棄
新しく4つ目のタブが開かれると
最もアクセス時刻の古いWebView1
が破棄される
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
13
タブ1
上限N
・open Tab1
・open Tab2
・open Tab3
・attach Tab1
・attach Tab3
・open Tab4
上記手順を踏んだ場合はWebView2が破
棄
WebView1
上限3
New!!!
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
14
タブ1 タブ2
上限N
・open Tab1
・open Tab2
・open Tab3
・attach Tab1
・attach Tab3
・open Tab4
上記手順を踏んだ場合はWebView2が破
棄
WebView1
WebView2
上限3
New!!!
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
15
タブ1 タブ2 タブ3
上限N
・open Tab1
・open Tab2
・open Tab3
・attach Tab1
・attach Tab3
・open Tab4
上記手順を踏んだ場合はWebView2が破
棄
WebView1
WebView2
WebView3
上限3
New!!!
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
16
タブ1 タブ2 タブ3
上限N
・open Tab1
・open Tab2
・open Tab3
・attach Tab1
・attach Tab3
・open Tab4
上記手順を踏んだ場合はWebView2が破
棄
WebView1
上限3
再表示
WebView2
WebView3
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
17
タブ1 タブ2 タブ3
上限N
・open Tab1
・open Tab2
・open Tab3
・attach Tab1
・attach Tab3
・open Tab4
上記手順を踏んだ場合はWebView2が破
棄
WebView2
WebView3
上限3
再表示
WebView1
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
18
タブ1 タブ2 タブ3
上限N
タブ4
・open Tab1
・open Tab2
・open Tab3
・attach Tab1
・attach Tab3
・open Tab4
上記手順を踏んだ場合はWebView2が破
棄
WebView1
WebView3
上限3
New!!!
WebView4
破棄
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
19
破棄されたWebView
保存・復元はどうなるか?
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
20
final Bundle state = new Bundle();
webview.saveState(state); // 保存用のメソッドが用意されている
state.putString(“url”, url);
state.putString(“title”, title);
// あとはファイルへ保存
■保存
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
21
// ファイルからBundleを読み込む
final String url = state.getString(“url”);
final String title = state.getString(“title”);
webview.restoreState(state); // 復元も同様に用意されている
■復元
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
三桁を実現させるタブの管理
22
まとめ
・タブとWebViewは別々に管理
・不要なWebViewは小まめに破棄
・WebViewの
saveState/restoreStateが便利
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
CoordinatorLayout対応
23
WebViewとCoordinatorLayout
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
24
これだけではダメ!
<CoordinatorLayout>
 <AppBarLayout>
 <Toolbar

app:layout_scrollFlags="scroll|enterAlwaysCollapsed" />
 </AppBarLayout>

 <FrameLayout
app:layout_behavior=“AppBarLayout$ScrollingViewBehavior">
<WebView />
</FrameLayout>

</CoordinatorLayout>
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
25
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
https://developer.android.com/reference/android/webkit/WebView.html
WebViewにはNestedScrollingChildが実装され
ていない。自分で実装が必要。
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
26
public class CommonWebView extends WebView implements NestedScrollingChild {
private final NestedScrollingChildHelper mHelper;
private float mPrevY;
@SuppressWarnings("CheckStyle")
private final int[] mConsumed = new int[2];
public CommonWebView(final @NonNull Context context) {
super(context);
mHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
switch (action) {
…
}
return super.onTouchEvent(event);
}
@Override
public void setNestedScrollingEnabled(final boolean enabled) {
mHelper.setNestedScrollingEnabled(enabled);
}
(省略)
}
これだけでは不十分
ウェブの表現を考慮す
る必要がある
・地図操作
・カルーセル
・ピンチイン・アウト
対応例を次スライドか
ら紹介
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
27
public CommonWebView(final @NonNull Context context) {
super(context);
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = configuration.getScaledPagingTouchSlop();
}
private void onTouchMove(MotionEvent event) {
if (mScrolling) {
final int dy = (int) (mPrevY - event.getRawY());
dispatchNestedPreScroll(0, dy, mConsumed, null);
final int consumedY = mConsumed[1];
dispatchNestedScroll(0, consumedY, 0, dy - consumedY, null);
} else {
final float dx = Math.abs(mStartX - event.getRawX());
final float dy = Math.abs(mStartY - event.getRawY());
if (dy > dx && dy > mTouchSlop && mScrollable) {
mScrolling = true;
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
}
}
}
横スクロール時に縦スクロールが発生する事による、
WebViewの移動&サイズ変更による操作の阻害
・縦横の移動量を考慮(dy > dx)
・縦についても遊びを持たせる(dy > mTouchSlop)
・地図操作
・カルーセル
・ピンチイン・アウト
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
28
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
(略)
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() != 1) {
break;
}
onTouchMove(event);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
(略)
default:
break;
}
mPrevY = event.getRawY();
return super.onTouchEvent(event);
}
スクロール操作以外で動かないようにする。
・タッチポイントの数を検知
(event.getPointerCount() != 1)
・地図操作
・カルーセル
・ピンチイン・アウト
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
29
@Override
protected int computeVerticalScrollRange() {
final int verticalScrollRange = super.computeVerticalScrollRange();
mScrollable = verticalScrollRange > getHeight() + mScrollMargin;
return verticalScrollRange;
}
WebViewサイズいっぱいで
操作させるページで動かないように。
・サイトのコンテンツサイズ(高さ)と
WebViewのサイズを比較
・地図操作
・カルーセル
・ピンチイン・アウト
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
WebViewとCoordinatorLayout
30
まとめ
・WebViewにNestedScrollChildを実装
・ウェブサイトの作りへの考慮が必要
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved.
ご静聴ありがとうござ
いました!

タブブラウザSDKを作った話 #yjcamp

  • 1.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 小林 俊 Yahoo! JAPAN アプリエンジニア タブブラウザSDK を 作った話 2017年4月20日
  • 2.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. アジェンダ 2 ・自己紹介 ・背景 ・タブブラウザSDKとは ・三桁を実現させるタブの管理 ・WebViewとCoordinatorLayout
  • 3.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 自己紹介 3 名前: 小林 俊(こばやし しゅん) 担当サービス: Yahoo! JAPAN アプリ Android歴:そろそろ2年 アイマス歴:そろそろ10年
  • 4.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 背景 4 Yahoo! JAPANYahoo!ブラウザ ブラウザ機能を持つ2つのアプリ
  • 5.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 背景 5 Yahoo! JAPANYahoo!ブラウザ 実は、共通化されたブラウザ機能を利用
  • 6.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. タブブラウザSDKとは 6 どんな機能があるの?
  • 7.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. タブブラウザSDKとは 7 ・WebView管理 ・タブ管理 ・CoordinatorLayout対応 ・URLスキーマハンドリング ・ページ内検索 ・標準的な振る舞いの提供
  • 8.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. タブブラウザSDKとは 8 ・WebView管理 ・タブ管理 ・CoordinatorLayout対応 ・URLスキーマハンドリング ・ページ内検索 ・標準的な振る舞いの提供
  • 9.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. タブ管理 9 三桁を実現させるタブの管理
  • 10.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 10 タブ1 タブ2 タブ3 タブN … WebView1 WebView2 WebView M … 上限M 上限N 全体像 「タブの上限」と 「WebViewの上限」は別扱い
  • 11.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 11 タブ1 タブ2 タブ3 上限N WebView1 WebView2 WebView3 上限3 タブ1→2→3の順に開かれた状態 4つ目のタブを開くと?
  • 12.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 12 タブ1 タブ2 タブ3 上限N WebView2 WebView3 上限3 タブ4 New!!! WebView4 破棄 新しく4つ目のタブが開かれると 最もアクセス時刻の古いWebView1 が破棄される
  • 13.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 13 タブ1 上限N ・open Tab1 ・open Tab2 ・open Tab3 ・attach Tab1 ・attach Tab3 ・open Tab4 上記手順を踏んだ場合はWebView2が破 棄 WebView1 上限3 New!!!
  • 14.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 14 タブ1 タブ2 上限N ・open Tab1 ・open Tab2 ・open Tab3 ・attach Tab1 ・attach Tab3 ・open Tab4 上記手順を踏んだ場合はWebView2が破 棄 WebView1 WebView2 上限3 New!!!
  • 15.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 15 タブ1 タブ2 タブ3 上限N ・open Tab1 ・open Tab2 ・open Tab3 ・attach Tab1 ・attach Tab3 ・open Tab4 上記手順を踏んだ場合はWebView2が破 棄 WebView1 WebView2 WebView3 上限3 New!!!
  • 16.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 16 タブ1 タブ2 タブ3 上限N ・open Tab1 ・open Tab2 ・open Tab3 ・attach Tab1 ・attach Tab3 ・open Tab4 上記手順を踏んだ場合はWebView2が破 棄 WebView1 上限3 再表示 WebView2 WebView3
  • 17.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 17 タブ1 タブ2 タブ3 上限N ・open Tab1 ・open Tab2 ・open Tab3 ・attach Tab1 ・attach Tab3 ・open Tab4 上記手順を踏んだ場合はWebView2が破 棄 WebView2 WebView3 上限3 再表示 WebView1
  • 18.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 18 タブ1 タブ2 タブ3 上限N タブ4 ・open Tab1 ・open Tab2 ・open Tab3 ・attach Tab1 ・attach Tab3 ・open Tab4 上記手順を踏んだ場合はWebView2が破 棄 WebView1 WebView3 上限3 New!!! WebView4 破棄
  • 19.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 19 破棄されたWebView 保存・復元はどうなるか?
  • 20.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 20 final Bundle state = new Bundle(); webview.saveState(state); // 保存用のメソッドが用意されている state.putString(“url”, url); state.putString(“title”, title); // あとはファイルへ保存 ■保存
  • 21.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 21 // ファイルからBundleを読み込む final String url = state.getString(“url”); final String title = state.getString(“title”); webview.restoreState(state); // 復元も同様に用意されている ■復元
  • 22.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. 三桁を実現させるタブの管理 22 まとめ ・タブとWebViewは別々に管理 ・不要なWebViewは小まめに破棄 ・WebViewの saveState/restoreStateが便利
  • 23.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. CoordinatorLayout対応 23 WebViewとCoordinatorLayout
  • 24.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 24 これだけではダメ! <CoordinatorLayout>
 <AppBarLayout>
 <Toolbar
 app:layout_scrollFlags="scroll|enterAlwaysCollapsed" />
 </AppBarLayout>

 <FrameLayout app:layout_behavior=“AppBarLayout$ScrollingViewBehavior"> <WebView /> </FrameLayout>

</CoordinatorLayout>
  • 25.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 25 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html https://developer.android.com/reference/android/webkit/WebView.html WebViewにはNestedScrollingChildが実装され ていない。自分で実装が必要。
  • 26.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 26 public class CommonWebView extends WebView implements NestedScrollingChild { private final NestedScrollingChildHelper mHelper; private float mPrevY; @SuppressWarnings("CheckStyle") private final int[] mConsumed = new int[2]; public CommonWebView(final @NonNull Context context) { super(context); mHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getAction(); switch (action) { … } return super.onTouchEvent(event); } @Override public void setNestedScrollingEnabled(final boolean enabled) { mHelper.setNestedScrollingEnabled(enabled); } (省略) } これだけでは不十分 ウェブの表現を考慮す る必要がある ・地図操作 ・カルーセル ・ピンチイン・アウト 対応例を次スライドか ら紹介
  • 27.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 27 public CommonWebView(final @NonNull Context context) { super(context); final ViewConfiguration configuration = ViewConfiguration.get(context); mTouchSlop = configuration.getScaledPagingTouchSlop(); } private void onTouchMove(MotionEvent event) { if (mScrolling) { final int dy = (int) (mPrevY - event.getRawY()); dispatchNestedPreScroll(0, dy, mConsumed, null); final int consumedY = mConsumed[1]; dispatchNestedScroll(0, consumedY, 0, dy - consumedY, null); } else { final float dx = Math.abs(mStartX - event.getRawX()); final float dy = Math.abs(mStartY - event.getRawY()); if (dy > dx && dy > mTouchSlop && mScrollable) { mScrolling = true; startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); } } } 横スクロール時に縦スクロールが発生する事による、 WebViewの移動&サイズ変更による操作の阻害 ・縦横の移動量を考慮(dy > dx) ・縦についても遊びを持たせる(dy > mTouchSlop) ・地図操作 ・カルーセル ・ピンチイン・アウト
  • 28.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 28 @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: (略) case MotionEvent.ACTION_MOVE: if (event.getPointerCount() != 1) { break; } onTouchMove(event); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: (略) default: break; } mPrevY = event.getRawY(); return super.onTouchEvent(event); } スクロール操作以外で動かないようにする。 ・タッチポイントの数を検知 (event.getPointerCount() != 1) ・地図操作 ・カルーセル ・ピンチイン・アウト
  • 29.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 29 @Override protected int computeVerticalScrollRange() { final int verticalScrollRange = super.computeVerticalScrollRange(); mScrollable = verticalScrollRange > getHeight() + mScrollMargin; return verticalScrollRange; } WebViewサイズいっぱいで 操作させるページで動かないように。 ・サイトのコンテンツサイズ(高さ)と WebViewのサイズを比較 ・地図操作 ・カルーセル ・ピンチイン・アウト
  • 30.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. WebViewとCoordinatorLayout 30 まとめ ・WebViewにNestedScrollChildを実装 ・ウェブサイトの作りへの考慮が必要
  • 31.
    Copyrig ht ©2017 Yahoo Japan Corporation. All Rig hts Reserved. ご静聴ありがとうござ いました!