将项目添加到回收站视图的底部
Posted
技术标签:
【中文标题】将项目添加到回收站视图的底部【英文标题】: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 发布你尝试过的代码 【参考方案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_
android:layout_
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_
android:layout_
android:layout_below="@+id/linearLayout3"
android:layout_above="@+id/linearLayout"
android:gravity="bottom">
<android.support.v7.widget.RecyclerView
android:id="@+id/messageRecyclerViewRep"
android:layout_
android:layout_
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_
android:layout_
android:orientation="vertical">
<Button
android:id="@+id/btnAdd"
android:layout_
android:layout_
android:text="Add" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rcList"
android:layout_
android:layout_
android:clipToPadding="true" />
</LinearLayout>
列表项 xml 布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_ android:textSize="23sp"
android:layout_ 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);
【讨论】:
感谢您的长篇回答。但是,我已经在使用 FirebaseRecyclerAdapter 这是一个类似的项目,它也使用 FirebaseRecyclerAdapter:github.com/firebase/friendlychat-android/tree/master/android【参考方案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);
【讨论】:
以上是关于将项目添加到回收站视图的底部的主要内容,如果未能解决你的问题,请参考以下文章