public class MainActivity extends AppCompatActivity { @BindView(R.id.recyclerView) RecyclerView recyclerView; AdapterMainActivity adapterMainActivity; List<Music> listAdapters = new ArrayList<Music>(); OkHttpClient okHttpClient; String SEARCH_KEYWORD = ""; @BindView(R.id.progressLoader) ProgressBar progressLoader; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); adapterMainActivity = new AdapterMainActivity(this, listAdapters); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapterMainActivity); okHttpClient = new OkHttpClient(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.m_main_activity, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { if (newText.length() >= 5) { SEARCH_KEYWORD = newText; adapterMainActivity.clear(); new Async().execute(); } else { if (newText.length() < 5) { adapterMainActivity.clear(); } } return false; } }); return true; } //**********************************Class Loader PlayList********************************** class Async extends AsyncTask { GsonMainActivity gsonMainActivity; @Override protected void onPreExecute() { super.onPreExecute(); progressLoader.setVisibility(View.VISIBLE); } @Override protected Object doInBackground(Object[] objects) { Request request = new Request.Builder() .url("https://itunes.apple.com/search?term=" + SEARCH_KEYWORD) .build(); try { Response response = okHttpClient.newCall(request).execute(); gsonMainActivity = new GsonBuilder() .create() .fromJson(response.body().string(), GsonMainActivity.class); } catch (IOException e) { e.printStackTrace(); } listAdapters.clear(); for (int i = 0; i < gsonMainActivity.results.size(); i++) { Music music = new Music( gsonMainActivity.results.get(i).artistName, gsonMainActivity.results.get(i).trackName, gsonMainActivity.results.get(i).artworkUrl100, gsonMainActivity.results.get(i).previewUrl ); listAdapters.add(music); } return null; } @Override protected void onPostExecute(Object o) { super.onPostExecute(o); adapterMainActivity.notifyItemRangeInserted(0, listAdapters.size()); progressLoader.setVisibility(View.INVISIBLE); } } } clear Adapter
public void clear(){ int size = this.listMusic.size(); this.listMusic.clear(); notifyItemRangeRemoved(0, size); } When I write a word to search with a pause of 3 seconds. That all works well. But if I start writing immediately without stopping, then an error falls out
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder position positionViewHolder {527536ac position = 40 id = -1, oldPos = 0, pLpos: 0 scrap [attachedScrap] tmpDetached not recyclable (1) no parent}
I understand that the problem lies in asyncTask, although the error in RecyclerView occurs, but I think if you solve the problem with AsyncTask then everything will be fine in RecyclerView. It would not be bad to understand how to cut down the asyncTask stream, even if it is executed.
Or it would be better to make me a certain type timer if I do not write for 1 second. Then it starts AsyncTask? And if the person starts writing again, and AsyncTask is executed. I think it would be better to cut down asyncTask If the user started writing something.
Tell me how to do it and do I think correctly?