【问题标题】:Add items to bottom of Recycler View将项目添加到回收站视图的底部
【发布时间】:2018-02-25 11:56:53
【问题描述】:

插图代码:

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

See illustration here

如何将新项目(在我的情况下为消息)添加到 Recycler View 的底部,同时仍将视图的“重力”保持在顶部?

所以,现在有效的是:

  • 视图的重力位于顶部。那挺好的! ✓

什么不起作用:

  • 新消息添加到视图顶部。不好× 我希望将它们添加到视图底部(在上一条消息之后),如下所示: See here

【问题讨论】:

  • 可能会反转您拥有的对象列表,再次将其传递给适配器并调用 notifyDataSetChanged()
  • 你试过notifyDataSetChanged吗,当arraylist值改变时你必须调用notifyDataSetChanged,就像这个adapter.notifyDataSetChanged();
  • @Gowthaman 您能否在答案中提供更多背景信息?
  • @Ashish 你能在答案中提供更多细节吗?
  • @user8618899 发布你尝试过的代码

标签: java android firebase firebase-realtime-database


【解决方案1】:

尝试删除这两行或设置它们false

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

setStackFromEnd 将视图设置为显示最后一个元素,布局方向将保持不变,而setReverseLayout 将更改适配器添加的元素的顺序。

当键盘出现时,尝试使用它来移动你的RecyclerView 和EditText

<activity name="YourActivity"
          android:windowSoftInputMode="stateHidden|adjustResize">
          //stateHidden -> keyboard is hidden when you first open the activity
          //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到底部,即当recycler view的布局改变时(你可以在Edit Text active或focused或clicked或类似的东西上做同样的事情。我已经在recycler view的布局上完成了改变。)

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

【讨论】:

  • 我不知道谁删除了他以前的 cmets 但这是我的 XML 文件:pastebin.com/XGrN5Dsj
  • 一旦提问者的问题得到解决,将获得赏金。
  • 问题仍未解决。
  • 我想当软键盘弹起时,RecyclerView也能推送。
  • 你试过编辑过的吗?伙计,你为什么不试验你的xml!慢慢来。
【解决方案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("");
            }
    
        }
    

    结果是 link

    【讨论】:

      【解决方案5】:

      试试这个,它对我有用。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-20
        相关资源
        最近更新 更多