在 Firebase RecyclerView 项目之间填充
Padding between Firebase RecyclerView items
我一直在尝试在 Firebase RecyclerView 之间获得一些填充 items.I 尝试使用 ItemDecoration,但它仅适用于 RecyclerView 的第一项。
如果您能指出我的错误,将对您有很大的帮助。
这就是我得到的
我想要得到的是一个布局,其中每个 recyclerview 项目之间都有一个填充,这样我就可以看到每个项目的阴影。
这是我的 Java 代码,我在其中使用 Firebase RecyclerView 加载项目。
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 class。
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_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/message_text_background"
android:elevation="4dp"
android:padding="10dp">
<TextView
android:id="@+id/question_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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>
不要使用这个 PaddingItemDecoration,只需在适配器的 XML 文件周围添加边距即可。
正如我所看到的,您已经向父约束布局添加了填充(尝试边距),所以只需删除您的装饰 class 并尝试简单地将列表打印到屏幕上,您就可以开始了。
下图是我的应用程序中适配器的 ListItem 布局示例,您的也应该是这个样子。
尝试增加边距10dp
如果您无法这样做,请尝试实施 this 文章中所示的方法。
我一直在尝试在 Firebase RecyclerView 之间获得一些填充 items.I 尝试使用 ItemDecoration,但它仅适用于 RecyclerView 的第一项。 如果您能指出我的错误,将对您有很大的帮助。
这就是我得到的
我想要得到的是一个布局,其中每个 recyclerview 项目之间都有一个填充,这样我就可以看到每个项目的阴影。
这是我的 Java 代码,我在其中使用 Firebase RecyclerView 加载项目。
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 class。
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_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/message_text_background"
android:elevation="4dp"
android:padding="10dp">
<TextView
android:id="@+id/question_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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>
不要使用这个 PaddingItemDecoration,只需在适配器的 XML 文件周围添加边距即可。
正如我所看到的,您已经向父约束布局添加了填充(尝试边距),所以只需删除您的装饰 class 并尝试简单地将列表打印到屏幕上,您就可以开始了。
下图是我的应用程序中适配器的 ListItem 布局示例,您的也应该是这个样子。
尝试增加边距10dp
如果您无法这样做,请尝试实施 this 文章中所示的方法。