有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android RecyclerView未正确更新

为了练习,我正在尝试为我的应用程序编写动态搜索功能。每次用户在SearchView{}中输入一个字符时,将发出server返回JSONArray,前10个用户的名字以搜索查询开始。我知道server返回正确的数据,因为在Emmiter.Listener内我循环通过JSONArray,在每个循环中我创建一个JSONObject,然后从该JSONObject创建模型类对象。问题是,对于每个搜索查询,在RecyclerView中只显示1项,而我知道有2项已添加到模型类的ArrayList中。我知道这一点,因为在调用adapter.notifyDataSetChanged()之前,我调用了adapter.getItemCount(),它返回了2

以下是我目前的代码:

public class SearchActivity extends AppCompatActivity {

    private Socket socket;
    public ArrayList<SearchResultUser> searchResultUsers;
    public SearchAdapter searchAdapter;
    public RecyclerView rvSearchResults;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        setUpConnectionToServer();

        searchResultUsers = new ArrayList<>();
        searchAdapter = new SearchAdapter(searchResultUsers);
        rvSearchResults = (RecyclerView)findViewById(R.id.rvSearchResults);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
        rvSearchResults.setLayoutManager(mLayoutManager);
        rvSearchResults.setItemAnimator(new DefaultItemAnimator());
        rvSearchResults.setAdapter(searchAdapter);

        rvSearchResults.addOnItemTouchListener(new RecyclerTouchListener(this,
                rvSearchResults, new RecyclerViewClickListener() {
            @Override
            public void onClick(View view, int position) {

            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    private void setUpConnectionToServer() {
        try {
            socket = IO.socket("http://youripaddress:3000");
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }

        socket.connect();
        socket.on("search", searchListener);
    }

    private Emitter.Listener searchListener = new Emitter.Listener(){
        @Override
        public void call(final Object... args){
            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    //clear current search result set
                    searchResultUsers.clear();
                    searchAdapter.notifyDataSetChanged();

                    //get new search result
                    JSONArray jsonArray = (JSONArray)args[0];

                    try {
                        //loop through all new search results
                        for(int i = 0; i < jsonArray.length(); i++){
                            //for every new search result create JSON object
                            JSONObject jsonObject = jsonArray.getJSONObject(i);

                            //from every JSON object create SearchResultUser model object
                            SearchResultUser mySearchResultUser = new SearchResultUser(jsonObject.getInt("id"),
                                    jsonObject.getString("name"));

                            //add every new SearchResultUser model object to the array list
                            searchResultUsers.add(mySearchResultUser);
                        }


                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    //notify the adapter of data set change
                    searchAdapter.notifyDataSetChanged();
                }
            });
        }
    };

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(base));
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_search, menu);

        // Associate searchable configuration with the SearchView
        // SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search_activity));
        // searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setOnQueryTextListener(onQueryTextListener);
        return super.onCreateOptionsMenu(menu);

    }

    public SearchView.OnQueryTextListener onQueryTextListener = new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            //Toast.makeText(SearchActivity.this,"search query => " + query, Toast.LENGTH_LONG).show();
            //socket.emit("search",query);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            //Toast.makeText(SearchActivity.this,"newText query => " + newText, Toast.LENGTH_SHORT).show();
            socket.emit("search",newText);
            if(newText.equals("")){
                searchResultUsers.clear();
                searchAdapter.notifyDataSetChanged();
            }
            return false;
        }
    };

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_search_activity) {
            Log.d("test","clicked on search");

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

public class SearchResultUser {

    private int id;
    private String name;


    public SearchResultUser() {
    }

    public SearchResultUser(int id, String name) {
        this.id = id;
        this.name = name;

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.MyViewHolder> {

    private ArrayList<SearchResultUser> searchResultUserList;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public ImageView ivProfileSearchResult;
        public TextView tvUserNameSearchResult;


        public MyViewHolder(View view) {
            super(view);
            ivProfileSearchResult = (ImageView) view.findViewById(R.id.ivProfileSearchResult);
            tvUserNameSearchResult = (TextView) view.findViewById(R.id.tvUserNameSearchResult);
        }
    }


    public SearchAdapter(ArrayList<SearchResultUser> searchResultUserList) {
        this.searchResultUserList = searchResultUserList;
    }

//this doen't work
    public void update(ArrayList<SearchResultUser> searchResultUserList){
        this.searchResultUserList.clear();
        for (SearchResultUser searchResultUser: searchResultUserList) {
            this.searchResultUserList.add(searchResultUser);
        }
        notifyDataSetChanged();
    }

    @Override
    public SearchAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.search_result_item, parent, false);

        return new SearchAdapter.MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(SearchAdapter.MyViewHolder holder, int position) {
        SearchResultUser searchResultUser = searchResultUserList.get(position);
        holder.tvUserNameSearchResult.setText(searchResultUser.getName());

    }

    @Override
    public int getItemCount() {
        return searchResultUserList.size();
    }
}

共 (0) 个答案