son - que es recyclerview android
¿Cómo saber cuándo el RecyclerView ha terminado de colocar los artículos? (5)
He estado luchando para tratar de eliminar OnGlobalLayoutListener
una vez que se activa, pero que lanza una IllegalStateException
. Ya que lo que necesito es desplazar mi recyclerView al segundo elemento, lo que hice fue verificar si ya tiene hijos y si es la primera vez que esto es cierto, solo entonces hago el desplazamiento:
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
}
}
HTH alguien!
(Por supuesto, esto se inspiró en las respuestas de @andrino y @Phatee)
Tengo un RecyclerView
que está dentro de un CardView
. El CardView
tiene una altura de 500dp, pero quiero acortar esta altura si el RecyclerView
es más pequeño. Así que me pregunto si hay algún oyente al que se llame cuando RecyclerView
haya terminado de colocar sus elementos por primera vez, lo que hace posible establecer la altura de RecyclerView
la altura de CardView
(si es menor que 500dp).
Lo que funcionó para mí fue agregar el oyente después de configurar el adaptador RecyclerView.
ServerRequest serverRequest = new ServerRequest(this); serverRequest.fetchAnswersInBackground(question_id, new AnswersDataCallBack() { @Override public void done(ArrayList<AnswerObject> returnedListOfAnswers) { mAdapter = new ForumAnswerRecyclerViewAdapter(returnedListOfAnswers, ForumAnswerActivity.this); recyclerView.setAdapter(mAdapter); recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { progressDialog.dismiss(); } }); } });
Esto descarta el "progressDialog" después de que cambia el estado de diseño global o la visibilidad de las vistas dentro del árbol de vistas.
Modificación de trabajo de @andrino anwser.
Como señaló @Juancho en el comentario anterior. Este método se llama varias veces. En este caso queremos que se active solo una vez.
Creado escucha personalizada con instancia, por ejemplo,
private RecyclerViewReadyCallback recyclerViewReadyCallback;
public interface RecyclerViewReadyCallback {
void onLayoutReady();
}
Luego configure OnGlobalLayoutListener
en su RecyclerView
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (recyclerViewReadyCallback != null) {
recyclerViewReadyCallback.onLayoutReady();
}
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
después de eso solo necesitas implementar un escucha personalizado con tu código
recyclerViewReadyCallback = new RecyclerViewReadyCallback() {
@Override
public void onLayoutReady() {
//
//here comes your code that will be executed after all items are laid down
//
}
};
Si usas Kotlin, entonces hay una solución más compacta. Muestra desde aquí .
Esta escucha de diseño se usa generalmente para hacer algo después de medir una vista, por lo que normalmente deberá esperar hasta que el ancho y la altura sean mayores que 0.
... puede ser utilizado por cualquier objeto que amplíe la Vista y también podrá acceder a todas sus funciones y propiedades específicas desde el oyente.
ServerRequest serverRequest = new ServerRequest(this);
serverRequest.fetchAnswersInBackground(question_id, new AnswersDataCallBack()
{
@Override
public void done(ArrayList<AnswerObject> returnedListOfAnswers)
{
mAdapter = new ForumAnswerRecyclerViewAdapter(returnedListOfAnswers, ForumAnswerActivity.this);
recyclerView.setAdapter(mAdapter);
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
progressDialog.dismiss();
}
});
}
});
También necesitaba ejecutar código después de que mi vista de reciclador terminara de inflar todos los elementos. Intenté registrar onBindViewHolder
en mi adaptador, si la posición era la última, y luego notifiqué al observador. Pero en ese momento, la vista del reciclador aún no estaba completamente poblada.
Como RecyclerView implementa ViewGroup
, esta respuesta fue muy útil. Simplemente necesita agregar un OnGlobalLayoutListener a recyclerView:
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);
}
});