TL;DR
安易なscroll.fullScroll()はFocusが勝手に移るから、面倒だけど↓これ使おう
https://stackoverflow.com/a/34866634
注意事項
API Level 27環境です。
あんまりこういう事例見かけないから、betterなやり方があるのかも。
要件
- 複数のEditTextやらTextViewやらが並ぶリストがある
- だいたいのViewにフォーカスが移るたびに何かしら処理させたい
- それぞれのViewに応じて別のViewの表示/非表示を切り替えたいとか・・・
- View.OnFocusChangeListener使うか〜〜〜
- scroll.fullScroll()で最下段まで勝手にスクロールも、、、あれ?
問題
scroll.fullScroll()したら上段のEditText君にFocus当たってね?
OnFocusChangeも呼ばれちゃって意図しない処理が実行される
こんなコードを改修する
以下のコードが実行された直後の状態だと、おそらく画面に写っている、もしくはscrollvViewに格納されている最初の子ViewにFocusが移り、その子ViewのonFocusChangeイベントが発生します。(もちろんhasfocus=true)
〜省略〜
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
〜省略〜
そもそもそんな設計が間違っている、スマートじゃないという話しもありますが、なるべく少ない作業量で修正しなきゃいけない場面も来るわけで。
試した事
Stackoverflowでの以下の質問。
Android: ScrollView force to bottom
「bottomにスクロールしたいけどどうすんの?」みたいな質問に対して、色々回答がありますが、その中のこの回答が本問題に対する打開策になります。
〜省略〜
View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
int bottom = lastChild.getBottom() + scrollLayout.getPaddingBottom();
int sy = scrollLayout.getScrollY();
int sh = scrollLayout.getHeight();
int delta = bottom - (sy + sh);
scrollLayout.smoothScrollBy(0, delta);
〜省略〜
回答主も「Focus移っちゃうからこうしなよ」って感じのスタンスで書いています。
回答に寄せられているコメントを見ても、
- 「もっと評価されるべき!」
- 「これがベストアンサーだ!」
などなど賞賛されているので良いのでは?
実際に自分の環境でも変にOnFocusChangeが呼ばれず、無事解決しました。
終わりに
なんでfullScrollしたらFocus移るん?って感じですが、冒頭に述べたように何かbetterな方法があるのかもしれません。ご参考までに。