首页 > 解决方案 > 单击下拉菜单中的项目后更改 RecyclerView 内容

问题描述

我的家庭活动中有两个容器,一个是Top Bar Fragment Container,另一个是ViewPagers ContainerTop Bar Fragment Container仅包含一个 Fragment,即 Top Bar Fragment(允许用户选择标签),而 Viewpagers 由 2 个 Fragment 组成,在每个 Fragment 中,它们都有一个回收器视图,用于在 Top Bar 上显示带有所选标签的帖子分段。

我试图实现的是,当在顶部栏片段上单击一个项目时,它会获取文本的值,然后使用接口将其发送到活动,稍后片段 Viewpagers 将从活动中获取该值并设置 firebase 查询按照通过的文本。

到目前为止,片段使用接口互相发送数据都做得很好。但是,适配器仅在创建视图时侦听一次,而不是在从 Fragments 传递数据时。从顶部栏片段发送数据后如何更新适配器?

这是我的 ViewPagerFragment(RecyclerView):

    FirebaseRecyclerOptions options, options2;
    FirebaseRecyclerAdapter<Question, QuestionsViewHolder> adapter;

     <!---- oncreate Code---->

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        String ChosenTag = tvtest.getText().toString();

        if (text.equals("")){
            Query query = questionReference.orderByChild("location").equalTo("jakarta");


            options = new FirebaseRecyclerOptions.Builder<Question>()
                            .setQuery(query, Question.class)
                            .build();

            adapter = new FirebaseRecyclerAdapter<Question, QuestionsViewHolder>(options) {

                @Override
                protected void onBindViewHolder(@NonNull QuestionsViewHolder holder, int position, @NonNull Question model) {
                    holder.username.setText(model.getUsername());
                }

                @NonNull
                @Override
                public  QuestionsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.snippet_card_question_new, viewGroup, false);
                    QuestionsViewHolder viewHolder = new QuestionsViewHolder(view);
                    return viewHolder;
                }
            };

            qListRv.setAdapter(adapter);
            adapter.startListening();
        } else {

            Query query = questionReference.orderByChild("tags").equalTo(ChosenTag);

            options2 = new FirebaseRecyclerOptions.Builder<Question>()
                    .setQuery(query, Question.class)
                    .build();
            adapter.updateOptions(options2);
        }
    }

简而言之,如果用户没有在 TopBarFragment 上进行选择,则文本返回 null,然后适配器将查询用户的当前位置。否则,如果用户在 Top Bar Fragment 上选择了一个标签,Top Bar Fragment 然后将标签发送到字符串,更新String ChosenTag,然后适配器将其选项更新为options2,查询所选标签。

选择后我无法刷新我的回收站视图。然而接口工作正常。有什么办法可以做到这一点?

标签: javafirebaseandroid-fragmentsfirebase-realtime-databaseandroid-recyclerview

解决方案


我到处搜索,似乎没有人可以帮助我,所以这就是我所做的,这对我有用。希望这可以帮助。

我将 Fragment B (TopBarFragment) 更改为 Activity (TopBarActivity)

我将片段更改为活动的原因是因为我希望整个 RecyclerView 适配器在用户被定向到 TopBar 活动时停止侦听。这样我可以在返回到包含 RecyclerViews 的 Activity 时启动一个新的适配器。

计划

  1. 制作两组适配器(一组用于 defaultAdapter,另一组用于用户在 TopBarActivity 上单击的内容。我们称之为 menuItemAdapter)。
  2. 在用户单击 MainActivity 时从 TopBarActivity 发送字符串的附加功能。从那时起,片段将检查 MainActivity 的字符串。
  3. 创建两个覆盖方法(onPause 和 onResume),以停止侦听适配器或开始侦听它们。我们将在这里创建条件来监听默认适配器或监听用户点击的内容。这些条件将检查点 2 上的字符串是否存在。如果存在,则侦听 menuItemAdapter,否则,如果字符串不存在,则侦听 defaultAdapters。

TopBarActivity 代码

             @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_top_bar); 

              //I am using Recycler view to display the  menu item lists on this activity.
             //RecyclerView Codes goes here

                    holder.itemView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent i = new Intent(getBaseContext(), MainActivity.class);
                            i.putExtra("CHOSENITEM", (model.getItemName()));
                            startActivity(i);
                        }
                 }

主要活动

public class MainActivity extends AppCompatActivity {
        private String choicesName = "";

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);

            setupTopBarStringListener();
    }

    private void setupTopBarStringListener() {
        choicesName = getIntent().getStringExtra("CHOSENITEM");
    }

    public String ChoicesString() {
        return choicesName;
    }
}

稍后将在 Fragment A 中调用String ChoicesString()

分段代码

    public class QuestionFragment extends Fragment {
    private String myStringFromActivity;
    RecyclerView contentListRv;
    FirebaseRecyclerOptions options, newoptions;
    FirebaseRecyclerAdapter<Post, PostsViewHolder> adapter, newadapters;


        @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Log.i(TAG, "onViewCreated: restart");


        contentListRv= view.findViewById(R.id.contentListRv);
        contentListRv.setLayoutManager(new LinearLayoutManager(getContext()));

        HomeActivity activity = (HomeActivity) getActivity();
        myStringFromActivity = activity.ChoicesString();
        Log.i(TAG, "choices from activity= " + myStringFromActivity);

    }
 }

将默认回收器添加到片段 A

    public void setupRecyclers() {

    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot dschild : dataSnapshot.getChildren()) {
                String location = "" + dschild.child("location").getValue();

                Query query = questionReference.orderByChild("location").equalTo(location);


                options = new FirebaseRecyclerOptions.Builder<Question>()
                        .setQuery(query, Post.class)
                        .build();

                adapter = new FirebaseRecyclerAdapter<Post, PostsViewHolder>(options) {
                    @Override
                    protected void onBindViewHolder(@NonNull PostsViewHolder holder, int position, @NonNull Question model) {

                       holder.username.setText(model.getUsername());

                    }

                    @NonNull
                    @Override
                    public QuestionsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.snippet_posts_view, viewGroup, false);
                        PostsViewHolder viewHolder = new PostsViewHolder(view);
                        return viewHolder;
                    }

                };
                contentListRV.setAdapter(adapter);
                adapter.startListening();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });

}

然后将 menuItem Recyclers 添加到 Fragment A

    public void menuItemRecyclers() {

                Query query2 = questionReference.orderByChild("tags").equalTo(myStringFromActivity);


                newoptions = new FirebaseRecyclerOptions.Builder<Question>()
                        .setQuery(query2, Post.class)
                        .build();

                newadapters = new FirebaseRecyclerAdapter<Post, PostsViewHolder>(options) {
                    @Override
                    protected void onBindViewHolder(@NonNull PostsViewHolder holder, int position, @NonNull Question model) {

                       holder.username.setText(model.getUsername());

                    }

                    @NonNull
                    @Override
                    public QuestionsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.snippet_posts_view, viewGroup, false);
                        PostsViewHolder viewHolder = new PostsViewHolder(view);
                        return viewHolder;
                    }

                };
                contentListRV.setAdapter(newadapters);
                newadapters.startListening();
            }
        }
}

上面的代码显示从 MainActivity 检索到的字符串myStringFromActivity将是我们对新适配器的查询。

最后,我们在 Fragment A 中实现 onPause 和 onResume 方法

    @Override
public void onPause() {
    super.onPause();
    Log.i(TAG, "onStop: adapter stopped");
    if(myStringFromActivity== null){
        adapter.stopListening();
    } else {
        newadapters.stopListening();
    }

}

@Override
public void onResume() {
    super.onResume();
    if(myStringFromActivity==null){
        setupRecyclers();
        Log.e(TAG, "onResume: String null" );
    }else{
        menuItemRecyclers();
    }
}

上面的代码显示,如果我们 String myStringFromActivity为空(用户没有点击我们的 Topbaractivity 中的任何项目,那么它运行默认的 Recyclers。否则,如果用户选择了一个项目,那么它运行 menuItemRecyclers(基于用户选择的内容) )。

我仍然愿意对此进行更好的实施。希望这可以帮助!


推荐阅读