-3

I am developing android app I have implemented searchview but when I start to search news in search bar

I am getting following exception 

Process: edgar.yodgorbek.sportnews, PID: 5146 java.util.ConcurrentModificationException at java.util.ArrayList$Itr.next(ArrayList.java:860) at edgar.yodgorbek.sportnews.sportactivities.BBCSportFragment.doFilter(BBCSportFragment.java:126) at edgar.yodgorbek.sportnews.MainActivity$1.onQueryTextChange(MainActivity.java:126)

below BBCSportFragment.java

public class BBCSportFragment extends Fragment implements ArticleAdapter.ClickListener {

    public static List<Article> articleList = new ArrayList<>();
    public List<Search> searchList = new ArrayList<>();
    @ActivityContext
    public Context activityContext;
    Search search;
    @ApplicationContext
    public Context mContext;

    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;
    BBCSportFragmentComponent bbcSportFragmentComponent;
    BBCFragmentContextModule bbcFragmentContextModule;
    private SportNews sportNews;
    private static ArticleAdapter articleAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_bbcsport, container, false);
        ButterKnife.bind(this, view);
        SportInterface sportInterface = SportClient.getApiService();
        Call<SportNews> call = sportInterface.getArticles();
        call.enqueue(new Callback<SportNews>() {
            @Override
            public void onResponse(Call<SportNews> call, Response<SportNews> response) {
                if (response == null) {
                    sportNews = response.body();
                    if (sportNews != null && sportNews.getArticles() != null) {
                        articleList.addAll(sportNews.getArticles());
                    }
                    articleAdapter = new ArticleAdapter(articleList, sportNews);
                    ApplicationComponent applicationComponent;
                    applicationComponent = (ApplicationComponent) MyApplication.get(Objects.requireNonNull(getActivity())).getApplicationContext();
                    bbcSportFragmentComponent = (BBCSportFragmentComponent) DaggerApplicationComponent.builder().contextModule(new ContextModule(getContext())).build();
                    bbcSportFragmentComponent.injectBBCSportFragment(BBCSportFragment.this);
                    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext(applicationComponent));
                    recyclerView.setLayoutManager(layoutManager);
                    recyclerView.setAdapter(articleAdapter);
                }
            }

            @Override
            public void onFailure(Call<SportNews> call, Throwable t) {

            }
        });


        SportInterface searchInterface = SportClient.getApiService();
        Call<Search> searchCall = searchInterface.getSearchViewArticles("q");
         searchCall.enqueue(new Callback<Search>() {
             @Override
             public void onResponse(Call<Search> call, Response<Search> response) {
                 search = response.body();

                 if (search != null && search.getArticles() != null) {
                     articleList.addAll(search.getArticles());
                 }

                 articleAdapter = new ArticleAdapter(articleList, search);
                 RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
                 recyclerView.setLayoutManager(layoutManager);
                 recyclerView.setAdapter(articleAdapter);
             }

             @Override
             public void onFailure(Call<Search> call, Throwable t) {

             }
         });


        return view;


    }

    private Context getContext(ApplicationComponent applicationComponent) {
        return null;
    }

    public static void doFilter(String searchQuery) {
       searchQuery = searchQuery.toLowerCase();

        for(Article article:  articleList){
            final String text = "";
            if (text.equals(searchQuery))
                articleList.add(article);
        }
         articleList.clear();
        if(articleList.isEmpty())
     articleAdapter.notifyDataSetChanged();

    }
}

below MainActivity.java

public class MainActivity extends AppCompatActivity {
    private DrawerLayout mDrawer;
    private Toolbar toolbar;
    private NavigationView nvDrawer;
    private ActionBarDrawerToggle drawerToggle;
    Context mContext;

    // Default active navigation menu
    int mActiveMenu;

    // TAGS
    public static final int MENU_FIRST = 0;
    public static final int MENU_SECOND = 1;
    public static final int MENU_THIRD = 2;
    public static final int MENU_FOURTH = 3;
    public static final int MENU_FIFTH = 3;
    public static final String TAG = "crash";


    // Action bar search widget
    SearchView searchView;
    String searchQuery = "";


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

        // Set a Toolbar to replace the ActionBar.
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Find our drawer view
        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerToggle = setupDrawerToggle();

        // Tie DrawerLayout events to the ActionBarToggle
        mDrawer.addDrawerListener(drawerToggle);

        nvDrawer = (NavigationView) findViewById(R.id.nvView);

// Inflate the header view at runtime
        View headerLayout = nvDrawer.inflateHeaderView(R.layout.nav_header);
// We can now look up items within the header if needed
        ImageView ivHeaderPhoto = (ImageView) headerLayout.findViewById((R.id.header_image));
        ivHeaderPhoto.setImageResource(R.drawable.ic_sportnews);
        setupDrawerContent(nvDrawer);
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.flContent, new BBCSportFragment()).commit();
        fragmentManager.beginTransaction().replace(R.id.flContent, new FoxSportsFragment()).commit();
        fragmentManager.beginTransaction().replace(R.id.flContent, new TalkSportsFragment()).commit();

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // The action bar home/up action should open or close the drawer.
        switch (item.getItemId()) {
            case android.R.id.home:
                mDrawer.openDrawer(GravityCompat.START);
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);

        // Getting search action from action bar and setting up search view
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchItem.getActionView();

        // Setup searchView
        setupSearchView(searchView);
        Log.e(TAG,"crash");
        return true;
    }

    public void setupSearchView(SearchView searchView) {
        SearchManager searchManager = (SearchManager) this.getSystemService(Context.SEARCH_SERVICE);
        if (searchManager != null) {
            SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
            searchView.setSearchableInfo(info);
        }

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String newText) {
                searchQuery = newText;

                // Load search data on respective fragment
                if (mActiveMenu == MENU_FIRST)   // First
                {
                    BBCSportFragment.doFilter(newText);
                }

                if (mActiveMenu == MENU_SECOND)   // First
                {
                    BBCSportFragment.doFilter(newText);
                }

                if (mActiveMenu == MENU_THIRD)   // First
                {
                    BBCSportFragment.doFilter(newText);
                }

                if (mActiveMenu == MENU_FOURTH)   // First
                {
                    BBCSportFragment.doFilter(newText);
                } else if (mActiveMenu == MENU_FIFTH) // Second
                {
                    ESPNFragment.doFilter(newText);
                }
                return true;
            }

            @Override
            public boolean onQueryTextSubmit(String query) {
                //searchView.clearFocus();
                return false;
            }
        });

        // Handling focus change of search view
        searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {

                // Focus changed after pressing back key or pressing done in keyboard
                if (!hasFocus) {
                    searchQuery = "";
                }
            }
        });
    }


    private void setupDrawerContent(NavigationView navigationView) {
        navigationView.setNavigationItemSelectedListener(
                menuItem -> {
                    selectDrawerItem(menuItem);
                    return true;
                });
    }

    public void selectDrawerItem(MenuItem menuItem) {
        // Create a new fragment and specify the fragment to show based on nav item clicked
        Fragment fragment = null;
        Class fragmentClass = null;
        switch (menuItem.getItemId()) {
            case R.id.bbcsports_fragment:
                fragmentClass = BBCSportFragment.class;
                break;
            case R.id.talksports_fragment:
                fragmentClass = TalkSportsFragment.class;
                break;
            case R.id.foxsports_fragment:
                fragmentClass = FoxSportsFragment.class;
                break;

            case R.id.footballitalia_fragment:
                fragmentClass = FootballItaliaFragment.class;
                break;

            case R.id.espn_fragment:
                fragmentClass = ESPNFragment.class;
                break;

            default:

        }

        try {
            fragment = (Fragment) fragmentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Insert the fragment by replacing any existing fragment

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
        // Highlight the selected item has been done by NavigationView
        menuItem.setChecked(true);
        // Set action bar title
        setTitle(menuItem.getTitle());
        // Close the navigation drawer
        mDrawer.closeDrawers();
    }

    private ActionBarDrawerToggle setupDrawerToggle() {
        // NOTE: Make sure you pass in a valid toolbar reference.  ActionBarDrawToggle() does not require it
        // and will not render the hamburger icon without it.
        return new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.drawer_open, R.string.drawer_close);
    }


    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggles
        drawerToggle.onConfigurationChanged(newConfig);
    }


}
7
  • 1
    Method doFilter is the culprit . You are iterating and adding items to same list ,, Commented Jun 3, 2019 at 8:48
  • what do you mean Commented Jun 3, 2019 at 8:49
  • it is not possible duplicate please check my question first Commented Jun 3, 2019 at 8:49
  • use a separate list .. add the elements to it.. and then use addAll(..) interface implementation to the main list Commented Jun 3, 2019 at 8:50
  • 1
    @EdgarShvedskiy it is a duplicate, you can't add new elements to the list while iterating over it. The login in the doFilter is flawed in general, you're iterating over a list, adding copies of the elements to it and then clearing it. What's the point of that? Edit. it adds duplicates of all elements if searchQuery is empty. Commented Jun 3, 2019 at 8:51

1 Answer 1

0

On response of your WebService, create one copy of data list. Like,

// define globally
public static List<Article> origArticleList = new ArrayList<>();

//Add below two line after "articleList.addAll(search.getArticles());"
origArticleList.clear();
origArticleList.addAll(search.getArticles());

And change doFilter method like this.

public static void doFilter(String searchQuery) {
     searchQuery = searchQuery.toLowerCase();
     articleList.clear();
     for(Article article:  origArticleList){
     final String text = "";
       if (text.equals(searchQuery))
           articleList.add(article);
     }
     articleAdapter.notifyDataSetChanged();
}
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for your code but it is showing white screen
Assign value to this "text" variable which you need to compare. Like final String text = article.getName();
it is still the same
what is your suggestion
I want to show first top headlines then after searching everything

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.