RecyclerView
の中にCardView
があります。 CardView
の高さは500dpですが、RecyclerView
が小さい場合はこの高さを短くします。 RecyclerView
が初めてアイテムの配置を終了し、RecyclerView
の高さをCardView
の高さに設定できるようになったときに呼び出されるリスナーがあるかどうか500dpより小さい場合)。
また、リサイクラービューがすべての要素を膨らませた後にコードを実行する必要がありました。位置が最後である場合、アダプターでonBindViewHolder
をチェックインしてから、オブザーバーに通知しました。しかし、その時点では、リサイクル業者の見解はまだ完全には定着していませんでした。
RecyclerView はViewGroup
を実装しているので、 this anwser は非常に役に立ちました。 recyclerViewに OnGlobalLayoutListener を追加するだけです。
View recyclerView = findViewById(R.id.myView);
recyclerView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//At this point the layout is complete and the
//dimensions of recyclerView and any child views are known.
//Remove listener after changed RecyclerView's height to prevent infinite loop
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
@andrino anwserの作業修正。
@Juanchoが上記のコメントで指摘したように。このメソッドは数回呼び出されます。この場合、一度だけトリガーされるようにします。
インスタンスを使用してカスタムリスナーを作成します。
private RecyclerViewReadyCallback recyclerViewReadyCallback;
public interface RecyclerViewReadyCallback {
void onLayoutReady();
}
次に、OnGlobalLayoutListener
にRecyclerView
を設定します
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (recyclerViewReadyCallback != null) {
recyclerViewReadyCallback.onLayoutReady();
}
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
その後、コードでカスタムリスナーを実装するだけです
recyclerViewReadyCallback = new RecyclerViewReadyCallback() {
@Override
public void onLayoutReady() {
//
//here comes your code that will be executed after all items are laid down
//
}
};
Kotlinを使用する場合、よりコンパクトなソリューションがあります。 here のサンプル。
。
... Viewを拡張する任意のオブジェクトで使用でき、リスナーから特定のすべての機能とプロパティにアクセスすることもできます。
// define 'afterMeasured' layout listener:
inline fun <T: View> T.afterMeasured(crossinline f: T.() -> Unit) {
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (measuredWidth > 0 && measuredHeight > 0) {
viewTreeObserver.removeOnGlobalLayoutListener(this)
f()
}
}
})
}
// using 'afterMeasured' handler:
recycler.afterMeasured {
// do the scroll (you can use the RecyclerView functions and properties directly)
// ...
}
一度トリガーされたらOnGlobalLayoutListener
を削除しようとして苦労していますが、IllegalStateException
がスローされます。私が必要なのは、recyclerViewを2番目の要素にスクロールすることで、すでに子供がいるかどうかを確認することであり、これが初めての場合は、スクロールするだけです:
public class MyActivity extends BaseActivity implements BalanceView {
...
private boolean firstTime = true;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ViewTreeObserver vto = myRecyclerView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (myRecyclerView.getChildCount() > 0 && MyActivity.this.firstTime){
MyActivity.this.firstTime = false;
scrollToSecondPosition();
}
}
});
}
...
private void scrollToSecondPosition() {
// do the scroll
}
}
誰か!
(もちろん、これは@andrinoと@Phateeの回答に触発されました)
また、同じ場合には、リスト/グリッド項目がポップアップされた後、RecyclerView.post()
メソッドを使用してコードを実行できます。私の場合、それで十分でした。