【问题标题】:OnQueryTextChange is not refreshing RecyclerView Adapter with AsyncTaskOnQueryTextChange 不使用 AsyncTask 刷新 RecyclerView 适配器
【发布时间】:2018-12-19 18:48:32
【问题描述】:

OnQueryTextChange 侦听器未更新 RecyclerAdapter 类中使用的 ArrayList。

我做了一个静态ArrayList来访问后台类使用的ArrayList中存储的数据,并调用RecyclerAdapter类的update方法通过OnQueryTextChange方法刷新RecyclerView。但是 RecyclerView 并不刷新。

MainActivity.java:

package com.example.varundhuria.recyclerfilterexample

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

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

    public void recycle(View view) {
        startActivity(new Intent(this,Search.class));
    }
}

搜索.java:

package com.example.varundhuria.recyclerfilterexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.Arrays;

public class Search extends AppCompatActivity implements SearchView.OnQueryTextListener {
    RecyclerAdapter adapter;
        ArrayList<AndroidVersions> list2=new ArrayList<>();

    public Search(){

    }

    public Search(ArrayList<AndroidVersions> list) {
        this.list2=list;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        background bg=new background(this);
        bg.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        MenuItem menuItem=menu.findItem(R.id.toolbar_search);
        SearchView searchView= (SearchView) menuItem.getActionView();
        searchView.setOnQueryTextListener(this);
        return true;
    }
    @Override
    public boolean onQueryTextSubmit(String s) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String s) {
        adapter=new RecyclerAdapter();
        String userInput=s.toLowerCase();
        ArrayList<AndroidVersions> newList=new ArrayList<>();
        for(AndroidVersions av:adapter.list2){
            if(av.getVersions().toLowerCase().contains(userInput)){
                newList.add(av);
            }
        }
        adapter.updateList(newList);
        return true;
    }
}

RecyclerAdapter.java:

package com.example.varundhuria.recyclerfilterexample;

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
    public ArrayList<AndroidVersions> list=new ArrayList<>();
    public static ArrayList<AndroidVersions> list2=new ArrayList<>();

    public RecyclerAdapter(){
    }

    public RecyclerAdapter(ArrayList<AndroidVersions> list) {
        this.list = list;
        this.list2=list;
    }

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

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
        AndroidVersions av=list.get(i);
        myViewHolder.VersionName.setText(av.getVersions());
    }

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

    public void updateList(ArrayList<AndroidVersions> newList) {
        list=new ArrayList<>();
        list.addAll(newList);
        notifyDataSetChanged();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView VersionName;
        public MyViewHolder(View itemView) {
            super(itemView);
            VersionName=(TextView)itemView.findViewById(R.id.text1);
        }
    }
}

背景.java:

package com.example.varundhuria.recyclerfilterexample;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import java.util.ArrayList;
public class background extends AsyncTask<String,AndroidVersions,String> {
    Activity activity;
    RecyclerView recyclerView;
    RecyclerView.Adapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<AndroidVersions> list=new ArrayList<>();
    Context ctx;

    public background(Context ctx) {
        this.ctx = ctx;
        activity=(Activity)ctx;
    }

    @Override
    protected void onPreExecute() {
        try {
            recyclerView = (RecyclerView) activity.findViewById(R.id.myRecycle);
            layoutManager = new LinearLayoutManager(ctx);
            recyclerView.setLayoutManager(layoutManager);
            recyclerView.setHasFixedSize(true);
            adapter = new RecyclerAdapter(list);
            recyclerView.setAdapter(adapter);
        } catch (Exception e) {
            Log.d("Runtime Error", e.getMessage());
        }
    }

    @Override
    protected void onPostExecute(String o) {
        //super.onPostExecute(o);
    }

    @Override
    protected String doInBackground(String... voids) {
        String result = "";
        AndroidVersions av= new AndroidVersions("pie");
        publishProgress(av);
        AndroidVersions av2= new AndroidVersions("Oreo");
        publishProgress(av2);
        AndroidVersions av3= new AndroidVersions("Nougat");
        publishProgress(av3);

        return result;
    }

    @Override
    protected void onProgressUpdate(AndroidVersions... values) {
        list.add(values[0]);
        adapter.notifyDataSetChanged();
        //super.onProgressUpdate(values);
    }
}

Androidversions.java:

package com.example.varundhuria.recyclerfilterexample;

public class AndroidVersions {
    String versions;

    public AndroidVersions(String versions) {
        this.versions = versions;
    }

    public String getVersions() {
        return versions;
    }

    public void setVersions(String versions) {
        this.versions = versions;
    }

}

OnQueryTextChange 用后台类更新 RecyclerView 适配器内的 ArrayList 并显示搜索结果。

【问题讨论】:

标签: android


【解决方案1】:

未能获得搜索结果的主要原因有两个:

  1. 您的 OnQueryTextChange() 方法总是会创建一个新的 RecyclerView 适配器, 因此它在搜索时包含空的数据列表。
  2. 您在 background.java 类中的 onProgressUpdate() 方法仅更新列表本身,但不更新适配器数据列表。所以 adapter.notifyDataSetChanged() 没有效果。但是,如果您正确更新适配器,您也不会收到搜索结果。因为您没有在 Search.java 类中使用该适配器,而是使用新的适配器。

我的建议是根本不要在 background.java 类中使用 RecyclerView 适配器。要从 onProgressUpdate() 中检索结果,您可以在 Search.java 类中实现回调/侦听器,然后在收到回调后相应地更新适配器。

【讨论】:

  • 谢谢先生,我在 Search.java 中添加了一个 AsynTask 类来访问相同的 ArrayList,它工作正常。非常感谢您为解决此问题提供的宝贵建议。
  • 嗨,@Varun 你介意将此答案标记为已接受,这可以帮助面临类似问题的其他人。
【解决方案2】:

每次更改查询文本时,您都会创建一个新适配器。您应该在设置为回收器视图的适配器上调用 updateList() 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多