【问题标题】:Show Recyclerview only after submitting search仅在提交搜索后显示 Recyclerview
【发布时间】:2020-08-13 15:34:01
【问题描述】:

我希望 MainActivity 在启动时为空,并且只有在提交搜索后,recyclerview 才会显示结果(因此它永远不会显示整个 recyclerview 列表)。截至目前,该应用程序正常运行,但 MainActivity 以推送到回收器视图的所有数据开始。

如果列表很大,它会影响性能,所以我需要一种方法将其设为空(或填充但不显示它)并仅显示搜索结果的 recyclerview,或者创建一个之前开始的新活动MainActivity 只有 Searchview 和 MainActivity 上的结果。

这是我当前的代码:

MainActivity.class(不包括导入)

public class MainActivity extends AppCompatActivity{

private AdapterListe adapter;
private RESTTask asyncTask;

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

    RecyclerView recyclerView = findViewById(R.id.lista);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    adapter = new AdapterListe(this);
    //adapter.setClickListener(this);
    recyclerView.setAdapter(adapter);

    asyncTask = new RESTTask();
    asyncTask.execute( getString(R.string.REST_URL));
}

private class RESTTask extends AsyncTask<String, Void, List<Ontologija>> {
    protected List<Ontologija> doInBackground(String... adresa) {
        String stringUrl = adresa[0];
        List<Ontologija> vrati = null;
        try {
            URL myUrl = new URL(stringUrl);
            HttpURLConnection connection = (HttpURLConnection)
                    myUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setReadTimeout(15000);
            connection.setConnectTimeout(15000);
            connection.connect();
            InputStreamReader streamReader = new
                    InputStreamReader(connection.getInputStream());
            BufferedReader reader = new BufferedReader(streamReader);
            Type listType = new TypeToken<ArrayList<Ontologija>>() {
            }.getType();
            vrati = new Gson().fromJson(reader, listType);
            reader.close();
            streamReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return vrati;
    }

    protected void onProgressUpdate(Integer... progress) {

    }

    protected void onPostExecute(List<Ontologija> podaci) {
        adapter.setPodaci(podaci);
        adapter.notifyDataSetChanged();
    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    MenuItem item = menu.findItem(R.id.search_icon);
    SearchView searchView = (SearchView) item.getActionView();
    searchView.setQueryHint("Pretraži...");
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            adapter.getFilter().filter(query);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            //adapter.getFilter().filter(newText);
            return false;
        }
    });
    return super.onCreateOptionsMenu(menu);
}

}

适配器

public class AdapterListe extends RecyclerView.Adapter<AdapterListe.Red> implements Filterable {

private List<Ontologija> podaci;
private List<Ontologija> podaciTemp;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;

// Podatke proslijedimo kroz konstruktor
public AdapterListe(Context context) {
    this.mInflater = LayoutInflater.from(context);
    podaci = new ArrayList<>();
}

// napuni predložak red (datoteka red_liste.xml)
@Override
public Red onCreateViewHolder(ViewGroup roditelj, int viewType) {
    podaciTemp = new ArrayList<>(podaci);
    View view = mInflater.inflate(R.layout.red_liste, roditelj, false);
    return new Red(view);
}

// Veže podatke za svaki red
@Override
public void onBindViewHolder(Red red, int position) {
    Ontologija o = podaci.get(position);
    red.naziv.setText(o.getNaziv());
    red.tip.setText(o.getTip());
    red.opis.setText(o.getOpis());
    red.anotacija.setText(o.getAnotacija());
}

// Ukupan broj redova (mora biti implementirano)
@Override
public int getItemCount() {
    return podaci==null ? 0 : podaci.size();
}

// Pohranjuje i reciklira pogled kako se prolazi kroz listu
public class Red extends RecyclerView.ViewHolder implements View.OnClickListener {
    private TextView naziv;
    private TextView tip;
    private TextView opis;
    private TextView anotacija;

    Red(View itemView) {
        super(itemView);
        naziv = itemView.findViewById(R.id.naziv);
        tip = itemView.findViewById(R.id.tip);
        opis = itemView.findViewById(R.id.opis);
        anotacija = itemView.findViewById(R.id.anotacija);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
    }
}

// klikom na listu dobijemo samo poziciju koju stavku liste smo odabrali.
// Ova metoda pomaže da na osnovu pozicije dobijemo cijeli objekt u toj stavci
public Ontologija getItem(int id) {
    return podaci.get(id);
}

public void setPodaci(List<Ontologija> itemList) {
    this.podaci = itemList;
}

// dopusti hvatanje odabira (klik/dotakni)
public void setClickListener(ItemClickListener itemClickListener) {
    this.mClickListener = itemClickListener;
}

// potrebno kako bi mogli hvatati klikove/dodire
public interface ItemClickListener {
    void onItemClick(View view, int position);
}

@Override
public Filter getFilter() {
    return new Filter() {
        //background
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<Ontologija> filteredList = new ArrayList<>();
            if (constraint.toString().isEmpty()) {
                filteredList.addAll(podaciTemp);
            } else {
                if(constraint.toString().length() >= 3) {
                    for (Ontologija element : podaciTemp) {
                        if (element.getNaziv().toLowerCase().contains(constraint.toString().toLowerCase())) {
                            filteredList.add(element);
                        }
                    }
                }
            }

            FilterResults filterResults = new FilterResults();
            filterResults.values = filteredList;

            return filterResults;
        }

        //ui
        @Override
        protected void publishResults(CharSequence constraint, FilterResults filterResults) {
            podaci.clear();
            podaci.addAll((Collection<? extends Ontologija>) filterResults.values);
            notifyDataSetChanged();
        }
    };
}

}

无论是代码、一些参考视频/帖子或基本上任何类型的帮助都将不胜感激,但到目前为止,我只看到了整个 recyclerview 的基本过滤器 searchview 教程,对我的具体情况没有任何帮助。

【问题讨论】:

    标签: java android android-recyclerview android-adapter searchview


    【解决方案1】:

    如果你不想显示,只需删除 notifyDataSetChanged

    protected void onPostExecute(List<Ontologija> podaci) {
            adapter.setPodaci(podaci);
            //adapter.notifyDataSetChanged();
        }
    

    编辑:

    if (!query.isEmpty()) {
        adapter.getFilter().filter(query);
    }
    

    或使用searchView.clearFocus();

    【讨论】:

    • 它在活动开始时不显示为真,但在我点击搜索图标后立即显示(而不是在提交搜索查询后)
    • 您的评论很有用,所以我将其标记为答案,但实际上我通过在 api 中添加路由解决了这个问题。