Firebase RecyclerView 项目之间的填充

Posted

技术标签:

【中文标题】Firebase RecyclerView 项目之间的填充【英文标题】:Padding between Firebase RecyclerView items 【发布时间】:2020-10-02 10:08:02 【问题描述】:

我一直在尝试在 Firebase RecyclerView 项之间添加一些填充。我尝试使用 ItemDecoration,但它仅适用于 RecyclerView 的第一项。 如果您能指出我的错误,那将是一个很大的帮助。

这就是我得到的

我想要得到的是一个布局,其中每个 recyclerview 项目之间都有一个填充,以便我可以看到每个项目的阴影。

这是我使用 Firebase RecyclerView 加载项目的 Java 代码。

public class CommunityFragment extends Fragment 
    private static final String KEY_RECYCLER_STATE = "";
    private RecyclerView mConvList;
    private DatabaseReference mConvDatabase;
    private DatabaseReference mUsersDatabase;
    private DatabaseReference mMessageDatabase;
    private Bundle mBundleRecyclerViewState;
    private Parcelable mListState;
    private static final String TAG = "ChatsFragment";

    public CommunityFragment() 
        // Required empty public constructor
    


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 


        View mMainView = inflater.inflate(R.layout.fragment_chats, container, false);

        mConvList = (RecyclerView) mMainView.findViewById(R.id.conv_list);
        FirebaseAuth mAuth = FirebaseAuth.getInstance();

        String mCurrent_user_id = Objects.requireNonNull(mAuth.getCurrentUser()).getUid();

        mConvDatabase = FirebaseDatabase.getInstance().getReference().child("Chat").child(mCurrent_user_id);
        mConvDatabase.keepSynced(true);

        mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
        mUsersDatabase.keepSynced(true);

        mMessageDatabase = FirebaseDatabase.getInstance().getReference().child("messages").child(mCurrent_user_id);
        mMessageDatabase.keepSynced(true);

        mConvList = mMainView.findViewById(R.id.conv_list);
        mConvList.setHasFixedSize(true);
        mConvList.setLayoutManager(new LinearLayoutManager(getContext()));

        // Inflate the layout for this fragment
        return mMainView;
    

    @Override
    public void onStart() 
        super.onStart();

        Query conversationQuery = mConvDatabase.orderByChild("timestamp");

        FirebaseRecyclerOptions<Conv> friendsFirebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Conv>()
                .setQuery(conversationQuery, Conv.class)
                .build();

        FirebaseRecyclerAdapter<Conv, ConvViewHolder> firebaseConvAdapter = new FirebaseRecyclerAdapter<Conv, ConvViewHolder>(friendsFirebaseRecyclerOptions) 
            @Override
            protected void onBindViewHolder(@NonNull final ConvViewHolder holder, int position, @NonNull final Conv model) 

                final String list_user_id = getRef(position).getKey();

                assert list_user_id != null;
                Query lastMessageQuery = mMessageDatabase.child(list_user_id).limitToLast(1);

                lastMessageQuery.addChildEventListener(new ChildEventListener() 

                    @Override
                    public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 
                        String data = Objects.requireNonNull(dataSnapshot.child("message").getValue()).toString();
                        String seen_ = Objects.requireNonNull(dataSnapshot.child("seen").getValue()).toString();
                        holder.setMessage(data, Boolean.parseBoolean(seen_));

                    

                    @Override
                    public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 

                    

                    @Override
                    public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) 

                    

                    @Override
                    public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 

                    

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) 

                    
                );

                mUsersDatabase.child(list_user_id).addValueEventListener(new ValueEventListener() 
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
                        final String userName = dataSnapshot.child("Name").getValue().toString();
                        holder.setName(userName);
                        holder.mView.setOnClickListener(new View.OnClickListener() 
                            @Override
                            public void onClick(View v) 
                                Intent chatIntent = new Intent(getContext(), ChatActivity.class);
                                chatIntent.putExtra("user_id", list_user_id);
                                chatIntent.putExtra("user_name",userName);
                                startActivity(chatIntent);
                            
                        );

                    


                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) 

                    
                );

            
            @NonNull
            @Override
            public ConvViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) 
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_q_layout, viewGroup, false);
                return new ConvViewHolder(view);
            
        ;
        mConvList.addItemDecoration(new PaddingItemDecoration(200));
        firebaseConvAdapter.startListening();
        mConvList.setAdapter(firebaseConvAdapter);

    

    public void onPause()
        super.onPause();
        mBundleRecyclerViewState = new Bundle();
        mListState = mConvList.getLayoutManager().onSaveInstanceState();
        mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, mListState);
    

    public void onResume()
        super.onResume();
        if (mBundleRecyclerViewState != null) 
            new Handler().postDelayed(new Runnable() 

                @Override
                public void run() 
                    mListState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
                    mConvList.getLayoutManager().onRestoreInstanceState(mListState);

                
            , 50);
        
        mConvList.setLayoutManager(new LinearLayoutManager(getContext()));
    

    public  class ConvViewHolder extends RecyclerView.ViewHolder 

        View mView;

        public ConvViewHolder(@NonNull View itemView) 
            super(itemView);
            mView = itemView;
        

        public void setName(String name)
            TextView userNameView = (TextView) mView.findViewById(R.id.question_title);
            userNameView.setText(name);
        

        public void setMessage(String message, boolean isSeen) 
            TextView userStatusView = (TextView) mView.findViewById(R.id.question_catergory);

            //Log.i("textData", "State is " + isSeen);
            if(!isSeen)
                userStatusView.setText("New Message");
                userStatusView.setTypeface(userStatusView.getTypeface(), Typeface.BOLD);
            else
                userStatusView.setText("No New Messages");
                userStatusView.setTypeface(userStatusView.getTypeface(), Typeface.NORMAL);
            

        
    


这是我的 PaddingItemDecoration 类。

public class PaddingItemDecoration extends RecyclerView.ItemDecoration 
    private final int size;

    public PaddingItemDecoration(int size) 
        this.size = size;
    

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) 
        super.getItemOffsets(outRect, view, parent, state);

        // Apply offset only to first item
        if (parent.getChildAdapterPosition(view) == 0) 
            outRect.top += size;
            outRect.bottom += size;

        
    

这是我用来加载 RecyclerView 项目的适配器的 XML 文件。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/relativeLayout3"
    android:layout_
    android:layout_
    android:background="@drawable/message_text_background"
    android:elevation="4dp"
    android:padding="10dp">

    <TextView
        android:id="@+id/question_title"
        android:layout_
        android:layout_
        android:layout_marginTop="8dp"
        android:padding="10dp"
        android:text="Display Name"
        android:textColor="#020202"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/question_catergory"
        android:layout_
        android:layout_
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:text="catergory"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/question_title" />

    <TextView
        android:id="@+id/counter_value"
        android:layout_
        android:layout_
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="counter"
        app:layout_constraintEnd_toStartOf="@+id/answers_given"
        app:layout_constraintTop_toBottomOf="@+id/question_title" />

    <TextView
        android:id="@+id/answers_given"
        android:layout_
        android:layout_
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="answers"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/question_title" />

</androidx.constraintlayout.widget.ConstraintLayout>

【问题讨论】:

你能分享你的截图吗?你目前的结果是什么,你想要达到什么目标? 感谢您抽出宝贵时间@towhid。如果有人想投反对票,请原谅我并留下必要的额外细节作为评论,或者在投反对票之前告诉我这个问题有什么问题,因为我真的想解决这个问题。我真的很感激。 几乎没有人有时间或耐心去浏览你的所有代码并想象你当前的视图。您可以通过仅显示两个简单的图像来解释您的问题,例如,您要实现的目标以及当前的结果是什么。这种方式很容易回答。你的答案是保证金。只需在您的约束布局中添加边距并完成。 android:marginBottom="10dp" 你也不需要任何 paddingDecoration。 【参考方案1】:

不要使用这个 PaddingItemDecoration,只需在适配器的 XML 文件周围添加边距。

我可以看到您已经在父约束布局中添加了填充(尝试使用边距),所以只需删除您的装饰类并尝试简单地将列表打印到屏幕上,您应该可以开始了。

下图是我的应用中适配器的 ListItem 布局示例,您的也应该看起来像这样。

尝试添加margin 10dp

如果您不能这样做,请尝试实现this 文章中显示的方式。

【讨论】:

如果您仍然无法实现这一点,请告诉我,很乐意进一步提供帮助 我没有浏览过你的 Java 代码,但是对于 RecyclerViewAdapter,我使用了 FirebaseUI。如果你不知道github.com/firebase/FirebaseUI-Android/blob/master/database/…. 增加填充没有任何区别。我参考了这篇文章并了解到这是我的适配器布局没有边距的问题。添加这个android:layout_marginBottom="8dp" 解决了我的问题。 是的,很抱歉我把填充和边距 xD 混淆了

以上是关于Firebase RecyclerView 项目之间的填充的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView没有被来自firebase的项目填充,只是一个空白的活动页面。

Firebase UI RecyclerView onClick

Firebase recyclerview 活动中的原生广告

每次firebase实时数据库数据集时,RecyclerView都会重新加载

如何通过firebase实时数据库永久隐藏RecyclerView中的imageview

我正在从 firebase Realtime Db 获取数据并获取 recyclerview 问题是 Collection.shuffling 在 android studio 中重复相同的项目