TabLayoutでaddTabした直後にselectしてもスクロールされない件

2015-08-23T04:27:36+09:00 Java Android

Android Design Support Libraryで?追加されているTabLayoutを使った場合に、addTabをした直後にselectメソッドを呼んだりaddTabの第2引数でtrue(selected)にしてもそのタブにフォーカスは当たるけど自動アニメーションスクロールによる処理が行われない為に自分でそのタブが出てる所までスライドしないといけない問題が出てるのですが...

なんとか解決出来たっぽいのでメモ

簡単な検証要件

SearchViewで検索した結果をTabLayoutにタブを動的に追加して検索結果をFragmentで出力するという内容。その動作キャプチャ

となるようにする。わかりづらいと思うが、上記でも書いてるようにaddTabメソッドのselected引数にtrueを設定したりaddTabした後にtabインスタンスでselectメソッドを呼んだり、TabLayout.getTabAt(TabLayout.getTabCount() -1).selectみたいに呼んでも動画のようにスクロールしないと見えない所に配置される場合にそれのフォーカスは行くけどそこまでアニメーションでスライドされないので自前で持っていくしかない。NGパターンで失敗ケースが

のように検索を実行した後、Tab.selectはされているけどスライドでフォーカスまでは至ってないので自前でスクロールしないと見えないっていう。それをなんとかするっていうのが今回の本要件

MainActivity.java

※部分的な抜粋のみ

public boolean onQueryTextSubmit(String query) {
    collapseSearchView();

    final TabLayout.Tab tab = createTab("検索 " + query, R.drawable.ic_search, R.id.tab_menu_search);
    // 第2引数でtrueを渡しても作用しない
    tabLayout.addTab(tab);

    // これをやっても作用しない
    // tab.select();

    setContentFragment(SearchFragment.newInstance(query));

    new Thread() {
        @Override
        public void run() {
            try {
                // 適当な妥当だと思われるタイムラグを発生させる
                Thread.sleep(300);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tab.select();
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();

    return false;
}

というような感じで、タブを追加した後にちょっとしたタイムラグを持ちそれからselectを実行する事で上記検証動画と同様になる。おそらくはaddTabをした直後でもまだUIがdrawされてなくてポジションがどこにあたるのかが不定になるからなのではと。もちろん理論的な理由では無いので...

っていうような感じでやれば上記のような感じになる。理論的な理由が分かれば追記するか別途でネタにするかと

余談

ViewPagerを使う場合にはTabLayout + ViewPager で初期ページを設定してもタブがスクロールしてない問題が参考になるのではないかと

angular.js $animateCss Mockitoでfinalクラスをモック化 (3)