query guardar example datos datasnapshot consultas configurar java android firebase firebase-realtime-database

java - guardar - Agregar elementos a la parte inferior de la Vista del reciclador



guardar datos en firebase android (5)

He implementado y aquí está mi Implementación usando FirebaseRecyclerView que necesita configurar setStackFromEnd=true y setReverseLayout=true

mi xml

Reciclador View Holder

public class TestingFirebaseHolder extends RecyclerView.ViewHolder { private TextView mTextView; private TextView mTextView2; public TestingFirebaseHolder(View itemView) { super(itemView); mTextView = itemView.findViewById(R.id.textViewTesting); mTextView2 = itemView.findViewById(R.id.textViewTesting2); } public void setTextView(String text,String text2) { mTextView.setText(text); mTextView2.setText(text2); } }

Clase de prueba

public class TestingUser { public String UserName; public String mUid; public TestingUser() { } public TestingUser(String userName, String uid) { UserName = userName; mUid = uid; } }

Código de actividad

private EditText mEditText; private RecyclerView mRecyclerView; private FirebaseRecyclerAdapter<TestingUser,TestingFirebaseHolder> mAdapter; private FirebaseUser mUser; private DatabaseReference mReference; mEditText = findViewById(R.id.testingEditText); mRecyclerView = findViewById(R.id.hello_rec); mUser = FirebaseAuth.getInstance().getCurrentUser(); mReference = FirebaseDatabase.getInstance().getReference(); LinearLayoutManager ll = new LinearLayoutManager(this); ll.setReverseLayout(true); // set this ll.setStackFromEnd(true); // set this mRecyclerView.setLayoutManager(ll); Query query = mReference.child("Testing").child(mUser.getUid()).orderByValue(); mAdapter = new FirebaseRecyclerAdapter<TestingUser, TestingFirebaseHolder>( TestingUser.class,R.layout.testing_recycler_layout,TestingFirebaseHolder.class,query ) { @Override protected void populateViewHolder(TestingFirebaseHolder viewHolder, TestingUser model, int position) { viewHolder.setTextView(model.mUid,model.UserName); } }; mRecyclerView.setAdapter(mAdapter); public void buttonClick(View view) { if(!mEditText.getText().toString().isEmpty()) { TestingUser user = new TestingUser("Salman",mEditText.getText().toString()); mReference.child("Testing").child(mUser.getUid()).push().setValue(user); mEditText.setText(""); } }

El resultado es link

Código de la ilustración:

mLinearLayoutManager = new LinearLayoutManager(this); mLinearLayoutManager.setReverseLayout(true); mLinearLayoutManager.setStackFromEnd(true); mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);

Vea la ilustracion aqui

¿Cómo puedo agregar nuevos elementos (en mi caso, mensajes) a la parte inferior de la Vista del reciclador y aún mantener la "gravedad" de la vista en la parte superior?

Entonces, lo que funciona ahora es lo siguiente:

  • La gravedad de la vista está en la parte superior. ¡Eso es bueno! ✓

Lo que no funciona:

  • Los mensajes nuevos se agregan a la parte superior de la vista. Eso es malo × Quiero que se agreguen en la parte inferior de la vista (después del mensaje anterior) así: ver aquí

Intenta esto, funciona para mí.

mLinearLayoutManager = new LinearLayoutManager(this); mLinearLayoutManager.stackFromEnd(true) mLinearLayoutManager.isSmoothScrollbarEnabled(true) mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);


La forma más sencilla de lograr esto sería cargar los elementos en el Recyclerview en orden inverso a cómo se ingresan en la base de datos de Firebase.

@Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { Log.d(TAG, "Element " + position + " set."); viewHolder.getTextView().setText(mDataSet.get(getItemCount() - 1 -position)); }

Lo que haría esto es que el último elemento insertado se mostrará en la parte inferior, ya que está cargando los elementos desde la parte superior. No es necesario realizar ningún cambio en ninguno de los XML ni en ningún otro código.

Tuve los mismos problemas con Recylerview al no cambiarse de tamaño cuando se abre el teclado y, por lo tanto, recurrí a este método.

¡¡Todo lo mejor!!


setReverseLayout(true) esto revertirá el recorrido de los elementos y el orden de diseño. El primer elemento no terminará de ver ni de ver el contenido.

setStackFromEnd(true) esto llenará el contenido de la lista de recicladores a partir de la parte inferior de la vista.

Necesidad de setStackFromEnd(true) no setReverseLayout(true)

Y en XML Recyclerview la altura debe ser match_parent

A continuación les he dado el código de trabajo.

xml de actividad

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btnAdd" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Add" /> <android.support.v7.widget.RecyclerView android:id="@+id/rcList" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="true" /> </LinearLayout>

lista de elementos de diseño XML

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:gravity="center_vertical"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:textSize="23sp" android:layout_height="wrap_content" android:textColor="#4a4883" android:text="Test Text" /> </FrameLayout>

Clase de adaptador

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private static final String TAG = "CustomAdapter"; private ArrayList<String> mDataSet; private int size = 0; public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; public ViewHolder(View v) { super(v); v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "Element " + getAdapterPosition() + " clicked."); } }); textView = (TextView) v.findViewById(R.id.textView); } public TextView getTextView() { return textView; } } public CustomAdapter(ArrayList<String> dataSet) { mDataSet = dataSet; if (mDataSet != null && !mDataSet.isEmpty()) { size = mDataSet.size(); } } public void refreshData(String add) { if (!TextUtils.isEmpty(add)) { mDataSet.add(add); size = mDataSet.size(); notifyDataSetChanged(); } } @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view. View v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.list_item, viewGroup, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { Log.d(TAG, "Element " + position + " set."); viewHolder.getTextView().setText(mDataSet.get(position)); } @Override public int getItemCount() { return size; } }

Clase de actividad

public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; protected CustomAdapter mAdapter; protected LinearLayoutManager mLayoutManager; protected ArrayList<String> listString = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = (RecyclerView) findViewById(R.id.rcList); mLayoutManager = new LinearLayoutManager(this); mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); /** *setStackFromEnd true will fill the content(list item) from the bottom of the view */ mLayoutManager.setStackFromEnd(true); mLayoutManager.setReverseLayout(true); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.setItemAnimator(new DefaultItemAnimator()); findViewById(R.id.btnAdd).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int temp = mAdapter.getItemCount() + 1; mAdapter.refreshData("Test text " + temp); mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount()); } }); mAdapter = new CustomAdapter(listString); mRecyclerView.setAdapter(mAdapter); } }


setStackFromEnd = true y setReverseLayout = true

setStackFromEnd configurará la vista para mostrar el último elemento, la dirección del diseño seguirá siendo la misma, mientras que setReverseLayout cambiará el orden de los elementos agregados por el Adaptador.
Intenta eliminar estas dos líneas o ponlas en false

layoutManager.setReverseLayout(true); layoutManager.setStackFromEnd(true);

Intente usar esto para mover su RecyclerView y EditText hacia arriba cuando aparezca el teclado

<activity name="YourActivity" android:windowSoftInputMode="stateHidden|adjustResize"> //stateHidden--->keyboard is hidden when you first open the activity and adjustResize---> this will adjust the layout resize option. ... </activity>

en AndroidManifest.xml .

Para enganchar el RecyclerView en la parte superior

<android.support.v7.widget.RecyclerView android:id="@+id/messageRecyclerViewRep" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/linearLayout3" android:layout_marginLeft="36dp" android:scrollbars="vertical" />

Para poner el recyclerView en la parte inferior primero y empujarlo hacia arriba cuando el teclado salte.

<LinearLayout android:id="@+id/recyclerContainer" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/linearLayout3" android:layout_above="@+id/linearLayout" android:gravity="bottom"> <android.support.v7.widget.RecyclerView android:id="@+id/messageRecyclerViewRep" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="36dp" android:scrollbars="vertical" /> </LinearLayout>

Para desplazar el recyclerView a la parte inferior cuando se abre el teclado, es decir, cuando se modifica el diseño de la vista del reciclador (puede hacer lo mismo en Editar texto activo o enfocado o al hacer clic o algo así. Lo he hecho en el cambio de diseño de la vista del reciclador).

recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { if (bottom < oldBottom) { recyclerView.postDelayed(new Runnable() { @Override public void run() { recyclerView.smoothScrollToPosition(mAdapter.getItemCount()); } }, 100); } } });