SwipeRefreshLayout 无需下拉即可刷新RecyclerView
SwipeRefreshLayout refreshes RecyclerView without having to pull down
我正在尝试在我的应用程序中实施 SwipeRefreshLayout
。我想要发生的是,当用户最初打开应用程序时,无需下拉布局即可从 Firebase 检索数据,从而刷新数据。之后,如果用户想要查看新数据,他们必须下拉布局,以便 RecyclerView
刷新为其他用户上传的新 post。
我 运行 遇到的问题是,当我从我的模拟器上传 post 时,它会自动在我的 phone 屏幕上弹出,而无需我下拉。那不是我想要的。首先,应自动检索应用程序初始打开数据,而无需下拉。之后每次想看新数据,我去不同的fragment再回来数据应该不会刷新,除非我拉下来
我目前的代码如下。有人能告诉我为什么它没有按照我希望的方式工作吗?
我比较确定这是因为我的 readPosts();
方法中的 notifyDataSetChanged();
,但我不确定如何修复它...我应该从 [=14 中删除它吗=] 并将其添加到 mSwipeRefreshLayout.post...Runnable
?
HomeFragment
public class HomeTabLayoutFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private ProgressBar mProgressBar;
private PostAdapter mPostAdapter;
private List<Post> mPostLists;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private List<String> mFollowingList;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home_tab_layout, container, false);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mProgressBar = v.findViewById(R.id.progress_circular);
RecyclerView recyclerView = v.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
mPostLists = new ArrayList<>();
mPostAdapter = new PostAdapter(getContext(), mPostLists);
recyclerView.setAdapter(mPostAdapter);
mSwipeRefreshLayout = v.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.post(() -> {
mSwipeRefreshLayout.setRefreshing(true);
readPosts();
});
checkIfUserExists();
checkFollowing();
return v;
}
@Override
public void onRefresh() {
readPosts();
}
private void checkIfUserExists() {
if (mFirebaseAuth == null) {
Intent intent = new Intent(getContext(), RegisterActivity.class);
startActivity(intent);
}
}
private void checkFollowing() {
mFollowingList = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Follow").child(mFirebaseUser.getUid()).child("Following");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mFollowingList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
mFollowingList.add(snapshot.getKey());
}
readPosts();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void readPosts() {
mSwipeRefreshLayout.setRefreshing(true);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
mSwipeRefreshLayout.setRefreshing(false);
}
private boolean shouldAddPost(@NotNull Post post) {
boolean isFollowingPublisher = false;
for (String id : mFollowingList) {
if (post.getPublisher().equals(id)) {
isFollowingPublisher = true;
break;
}
}
boolean isPublisher = post.getPublisher().equals(mFirebaseUser.getUid());
return isFollowingPublisher || isPublisher;
}
}
那是因为您使用的是addValueEventListener
。在这种情况下,每次在此层次结构中进行任何更改时,都会调用 ValueEventListener
。
如果您只需要一次数据,您应该使用 addListenerForSingleValueEvent
。换句话说,如果您不想实时更新节点,那么您可以使用 addListenerForSingleValueEvent
.
->关于 mSwipeRefreshLayout.setRefreshing(false)
定位在 readPost
内的回答。
现在你如何添加 mSwipeRefreshLayout.setRefreshing(true)
和 mSwipeRefreshLayout.setRefreshing(false)
实际上是没有用的。它会立即调用。你应该做的是改变监听器内部的状态。
private void readPosts() {
mSwipeRefreshLayout.setRefreshing(true);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
mSwipeRefreshLayout.setRefreshing(false);
}
});
我正在尝试在我的应用程序中实施 SwipeRefreshLayout
。我想要发生的是,当用户最初打开应用程序时,无需下拉布局即可从 Firebase 检索数据,从而刷新数据。之后,如果用户想要查看新数据,他们必须下拉布局,以便 RecyclerView
刷新为其他用户上传的新 post。
我 运行 遇到的问题是,当我从我的模拟器上传 post 时,它会自动在我的 phone 屏幕上弹出,而无需我下拉。那不是我想要的。首先,应自动检索应用程序初始打开数据,而无需下拉。之后每次想看新数据,我去不同的fragment再回来数据应该不会刷新,除非我拉下来
我目前的代码如下。有人能告诉我为什么它没有按照我希望的方式工作吗?
我比较确定这是因为我的 readPosts();
方法中的 notifyDataSetChanged();
,但我不确定如何修复它...我应该从 [=14 中删除它吗=] 并将其添加到 mSwipeRefreshLayout.post...Runnable
?
HomeFragment
public class HomeTabLayoutFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private ProgressBar mProgressBar;
private PostAdapter mPostAdapter;
private List<Post> mPostLists;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private List<String> mFollowingList;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home_tab_layout, container, false);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mProgressBar = v.findViewById(R.id.progress_circular);
RecyclerView recyclerView = v.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
mPostLists = new ArrayList<>();
mPostAdapter = new PostAdapter(getContext(), mPostLists);
recyclerView.setAdapter(mPostAdapter);
mSwipeRefreshLayout = v.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.post(() -> {
mSwipeRefreshLayout.setRefreshing(true);
readPosts();
});
checkIfUserExists();
checkFollowing();
return v;
}
@Override
public void onRefresh() {
readPosts();
}
private void checkIfUserExists() {
if (mFirebaseAuth == null) {
Intent intent = new Intent(getContext(), RegisterActivity.class);
startActivity(intent);
}
}
private void checkFollowing() {
mFollowingList = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Follow").child(mFirebaseUser.getUid()).child("Following");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mFollowingList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
mFollowingList.add(snapshot.getKey());
}
readPosts();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void readPosts() {
mSwipeRefreshLayout.setRefreshing(true);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
mSwipeRefreshLayout.setRefreshing(false);
}
private boolean shouldAddPost(@NotNull Post post) {
boolean isFollowingPublisher = false;
for (String id : mFollowingList) {
if (post.getPublisher().equals(id)) {
isFollowingPublisher = true;
break;
}
}
boolean isPublisher = post.getPublisher().equals(mFirebaseUser.getUid());
return isFollowingPublisher || isPublisher;
}
}
那是因为您使用的是addValueEventListener
。在这种情况下,每次在此层次结构中进行任何更改时,都会调用 ValueEventListener
。
如果您只需要一次数据,您应该使用 addListenerForSingleValueEvent
。换句话说,如果您不想实时更新节点,那么您可以使用 addListenerForSingleValueEvent
.
->关于 mSwipeRefreshLayout.setRefreshing(false)
定位在 readPost
内的回答。
现在你如何添加 mSwipeRefreshLayout.setRefreshing(true)
和 mSwipeRefreshLayout.setRefreshing(false)
实际上是没有用的。它会立即调用。你应该做的是改变监听器内部的状态。
private void readPosts() {
mSwipeRefreshLayout.setRefreshing(true);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
mSwipeRefreshLayout.setRefreshing(false);
}
});