Ajouter des éléments au bas de la vue recycleur

Code de l'illustration:

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

Voir l'illustration ici

Comment puis-je ajouter de nouveaux éléments (dans mon cas, des messages) à la bottom de la vue Recycler et garder toujours la "gravité" de la vue vers le haut?

Donc, ce qui fonctionne maintenant est le suivant:

  • la gravité de La vue au sommet. Que c'est bon! ✓

Ce qui ne fonctionne pas:

  • les nouveaux messages sont ajoutés en haut de la vue. C'est une mauvaise × Je veux qu'ils soient ajoutés au bas de la vue (après le message précédent) comme: Voir ici
21
demandé sur Niraj Niroula 2017-09-16 15:39:02

5 réponses

SetStackFromEnd=true et setReverseLayout=true

La différence entre ces deux est que setStackFromEnd définira la vue pour afficher le dernier élément, la direction de mise en page restera la même tandis que setReverseLayout changera l'ordre des éléments ajoutés par l'Adaptateur.
Essayez de supprimer ces deux lignes ou de les définir false

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

Essayez d'utiliser cette option pour déplacer votre RecyclerView et EditText lorsque le clavier apparaît

<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>  

Dans AndroidManifest.xml.

À accrochez le RecyclerView en haut

    <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" />

Pour mettre le recyclerView en bas en premier et le pousser vers le haut lorsque le clavier apparaît.

 <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>

Pour faire défiler le recyclerView vers le bas lorsque le clavier apparaît, c'est-à-dire lorsque la mise en page de la vue recycleur est modifiée ( vous pouvez faire la même chose sur Modifier le texte actif ou concentré ou cliqué ou quelque chose comme ça. Je l'ai fait sur recycleur vue du changement de présentation. )

   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);
                }
            }
        });
10
répondu Niraj Niroula 2017-09-25 12:02:04

SetReverseLayout (true) {[9] } cela inversera l'ordre de traversée et de mise en page de l'élément.Le premier élément viendra à la fin pas voir ou contenu.

SetStackFromEnd (true) cela remplira le contenu de la liste des recycleurs à partir du bas de la vue.

Besoin de setStackFromEnd(true) pas setReverseLayout(true)

Et en XML Recyclerview hauteur devrait être match_parent

Ci-dessous, j'ai donné du code de travail.

L'Activité xml

<?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>

Élément de liste xml mise en page

<?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>

Classe D'Adaptateur

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;
    }
}

Classe D'activité

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);

    }
}

entrez la description de l'image ici

3
répondu user1140237 2017-09-25 07:51:57

Le moyen le plus simple d'y parvenir serait de charger les éléments dans Recyclerview dans l'ordre inverse de la façon dont ils sont entrés dans la base de données Firebase.

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

Ce que cela ferait est que l'élément qui est inséré en dernier sera affiché en bas puisque vous chargez les éléments à partir du haut. Pas besoin de changement dans L'un des XMLs ou tout autre code.

J'ai eu les mêmes problèmes avec Recylerview ne se redimensionnant pas lorsque le clavier apparaît et j'ai donc eu recours à ceci méthode.

Tout le meilleur!!

2
répondu Abhishek 2017-09-24 16:47:54

J'ai implémenté et voici mon implémentation en utilisant FirebaseRecyclerView vous devez définir cette setStackFromEnd=true et setReverseLayout=true

Mon xml

Porte-Vue Recycleur

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);
    }
}

Classe De Test

public class TestingUser {

    public String UserName;
    public String mUid;

    public TestingUser() {
    }

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

Code D'Activité

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("");
        }

    }

Le Résultat est lien

1
répondu Salman500 2017-09-24 11:33:22

Essayez ceci, cela fonctionne pour moi.

mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.stackFromEnd(true)
mLinearLayoutManager.isSmoothScrollbarEnabled(true)
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
1
répondu Ramesh 2017-09-27 07:25:01