RecyclerView 与 SearchView。只有在 searchView 上输入文本时列表才会开始显示

RecyclerView with SearchView. List will only start to show when typing a text on searchView

我将此 recyclerView 与来自此 Github Repository

的 searchView 应用程序一起使用

我所做的唯一更改是不再从字符串数组获取结果,而是使用 volley 从 Web 服务器检索数据。我还添加了一个单例 class 来满足 volley 的需要。我遇到的唯一问题是,在应用程序启动时,列表不会显示,直到我单击搜索图标并在其上键入一些 text/characters。我很确定我能够从 Web 服务器检索数据,因为它会在搜索视图中键入内容时显示。尝试测试它伙计们,请告诉我你是否能够解决它。

在 repo 上,MainFragment 看起来与下面的代码相同,只是添加了我从服务器获取数据的代码。看看我的代码:

    public class MainFragment extends Fragment implements SearchView.OnQueryTextListener {

    public static MainFragment newInstance() {
        return new MainFragment();
    }
    private static String url = "http://www.psite7.org/portal/webservices/get_members.php";

    private static final String[] MOVIES = new String[]{
            "The Woman in Black: Angel of Death",
            "20 Once Again",
            "Taken 3",
            "Tevar",
            "I",
            "Blackhat",
            "Spare Parts",
            "The Wedding Ringer",
            "Ex Machina",
            "Mortdecai",
            "Strange Magic",
            "The Boy Next Door",
            "The SpongeBob Movie: Sponge Out of Water",
            "Kingsman: The Secret Service",
            "Boonie Bears: Mystical Winter",
            "Project Almanac",
            "Running Man",
            "Wild Card",
            "It Follows",
            "C'est si bon",
            "Yennai Arindhaal",
            "Shaun the Sheep Movie",
            "Jupiter Ascending",
            "Old Fashioned",
            "Somewhere Only We Know",
            "Fifty Shades of Grey",
            "Dragon Blade",
            "Zhong Kui: Snow Girl and the Dark Crystal",
            "Badlapur",
            "Hot Tub Time Machine 2",
            "McFarland, USA",
            "The Duff",
            "The Second Best Exotic Marigold Hotel",
            "A la mala",
            "Focus",
            "The Lazarus Effect",
            "Chappie",
            "Faults",
            "Road Hard",
            "Unfinished Business",
            "Cinderella",
            "NH10",
            "Run All Night",
            "X+Y",
            "Furious 7",
            "Danny Collins",
            "Do You Believe?",
            "Jalaibee",
            "The Divergent Series: Insurgent",
            "The Gunman",
            "Get Hard",
            "Home"
    };

    private RecyclerView mRecyclerView;
    private ExampleAdapter mAdapter;
    private List<ExampleModel> mModels;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragment_main, container, false);

        mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);

        return view;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        setHasOptionsMenu(true);

        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        mModels = new ArrayList<>();

//        for (String movie : MOVIES) {
//            mModels.add(new ExampleModel(movie));
//        }
        populate();
//        mAdapter = new ExampleAdapter(getActivity(), mModels);
//        mRecyclerView.setAdapter(mAdapter);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_main, menu);

        final MenuItem item = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
        searchView.setOnQueryTextListener(this);
    }

    @Override
    public boolean onQueryTextChange(String query) {
        final List<ExampleModel> filteredModelList = filter(mModels, query);
        mAdapter.animateTo(filteredModelList);
        mRecyclerView.scrollToPosition(0);
        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }

    private List<ExampleModel> filter(List<ExampleModel> models, String query) {
        query = query.toLowerCase();

        final List<ExampleModel> filteredModelList = new ArrayList<>();
        for (ExampleModel model : models) {
            final String text = model.getText().toLowerCase();
            if (text.contains(query)) {
                filteredModelList.add(model);
            }
        }
        return filteredModelList;
    }

    public void populate(){
        JsonArrayRequest request = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray jsonArray) {
//                        hidePDialog();
                        String   email, status;
//                        Member member;
                        final String names[] = new String[jsonArray.length()];
                        for(int i = 0; i < jsonArray.length(); i++) {
                            try {
                                JSONObject object = jsonArray.getJSONObject(i);

                                names[i] = object.getString("firstname") + " " + object.getString("lastname");
                                email = object.getString("email");
                                if(Integer.parseInt(object.getString("activated"))==1){
                                    status = "Active";
                                }else{
                                    status = "Not Active";
                                }
//                                member = new Member(name, email, status);

                            } catch (Exception e) {

                            }
                        }
                        for(String name : names){
                            Log.wtf("name", name);
                            mModels.add(new ExampleModel(name));
                        }
                        mAdapter.notifyDataSetChanged();
                    }
                }, new Response.ErrorListener(){
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                volleyError.printStackTrace();
            }
        });
        AppController.getInstance().addToRequestQueue(request);
        mAdapter = new ExampleAdapter(getActivity(), mModels);
        mRecyclerView.setAdapter(mAdapter);
    }
}

如果您注意到我刚刚评论了回购协议中使用的代码。我尽量复制它。

您混淆了同步代码和异步代码。如果在将所有模型添加到 mModels 之后创建并分配 ExampleAdapter,它应该会按预期工作。

1) 修复您的代码

public void populate() {
    final JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {

        @Override
        public void onResponse(JSONArray jsonArray) {
            try {
                for (int i = 0; i < jsonArray.length(); i++) {
                    final JSONObject object = jsonArray.getJSONObject(i);
                    final String name = object.getString("firstname") + " " + object.getString("lastname");
                    mModels.add(new ExampleModel(name));
                }
                mAdapter = new ExampleAdapter(getActivity(), mModels);
                mRecyclerView.setAdapter(mAdapter);
            } catch (JSONException e) {
                Log.e(LOG_TAG, "Failed to parse member json.", e);
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
            volleyError.printStackTrace();
        }
    });
    AppController.getInstance().addToRequestQueue(request);
}

2) 更好的解决方案

更好的是在 onViewCreated() 中创建一次 Adapter,然后在您的模型列表更改时使用 animateTo() 方法:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mAdapter = new ExampleAdapter(getActivity(), new ArrayList<>());
    mRecyclerView.setAdapter(mAdapter);
    ...
    updateMemberList();
}

public void updateModels() {
    final JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {

        @Override
        public void onResponse(JSONArray jsonArray) {
            try {
                for (int i = 0; i < jsonArray.length(); i++) {
                    final JSONObject object = jsonArray.getJSONObject(i);
                    final String name = object.getString("firstname") + " " + object.getString("lastname");
                    mModels.add(new ExampleModel(name));
                }
                mAdapter.animateTo(mModels);
            } catch (JSONException e) {
                Log.e(LOG_TAG, "Failed to parse member json.", e);
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
            volleyError.printStackTrace();
        }
    });
    AppController.getInstance().addToRequestQueue(request);
}        

这两种方法都有效,只是您正在尝试的 - 修改 Fragment 中的 List - 无效。 Adapter 有自己的内部 List 模型,如果您想更改 RecyclerView 中显示的内容,则需要修改该模型。