Подтвердить что ты не робот

Добавить элементы внизу обзора Recycler

Код иллюстрации:

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

Смотрите рисунок здесь

Как добавить новые элементы (в моем случае, сообщения) в снизу просмотра Recycler и по-прежнему удерживать "тяжести" вида сверху?

Итак, что теперь работает:

  • Сверху вид сверху. Это хорошо! ✓

Что не работает:

  • Новые сообщения добавляются в верхнюю часть представления. Это плохо × Я хочу, чтобы они были добавлены в нижней части представления (после предыдущего сообщения) следующим образом: См. здесь
4b9b3361

Ответ 1

setStackFromEnd = true и setReverseLayout = true

Разница между этими двумя заключается в том, что setStackFromEnd установит представление для отображения последнего элемента, направление макета останется тем же, тогда как setReverseLayout изменит порядок элементов, добавленных адаптером.
Попробуйте удалить эти две строки или установить их false

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

Попробуйте использовать это, чтобы переместить RecyclerView и EditText вверх при появлении клавиатуры

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

в AndroidManifest.xml.

Чтобы перехватить RecyclerView вверху

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

Чтобы сначала загрузить recyclerView внизу и нажимать его, когда клавиатура появляется.

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

Чтобы прокрутить recyclerView снизу, когда клавиатура появляется, т.е. когда изменяется макет вида ресайклера (вы можете сделать то же самое в "Редактировании текста" активным или сфокусированным или нажатым или что-то в этом роде. Я сделал это на макете просмотра ресайклеров измените.)

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

Ответ 2

setReverseLayout (true), это изменит порядок обхода и расположения макета. Первый элемент завершится без просмотра или содержимого.

setStackFromEnd (true), это заполнит содержимое списка ресайклеров, начиная со дна представления.

Требуется setStackFromEnd(true) не setReverseLayout(true)

И в XML Высота Recyclerview должна быть match_parent

Ниже приведен рабочий код.

активность 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>

Элемент списка элементов 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>

Класс адаптера

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

Класс действия

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

    }
}

введите описание изображения здесь

Ответ 3

Самый простой способ добиться этого - загрузить элементы в Recyclerview в обратном порядке, как они будут введены в базу данных Firebase.

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

Что бы это могло сделать, так это то, что элемент, который вставлен последним, будет отображаться внизу, так как вы загружаете элементы сверху. Нет необходимости в каких-либо изменениях в любом из XML или любом другом коде.

У меня были те же проблемы, что и Recylerview, не изменяя размер, когда клавиатура всплывает, и поэтому я прибегал к этому методу.

Все самое лучшее!

Ответ 4

Я реализовал и вот моя реализация с использованием FirebaseRecyclerView вам нужно установить этот setStackFromEnd=true и setReverseLayout=true

my xml

Держатель рекуператора

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

Класс тестирования

public class TestingUser {

    public String UserName;
    public String mUid;

    public TestingUser() {
    }

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

Код действия

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

    }

Результат ссылка

Ответ 5

Попробуй, это работает для меня.

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