Search code examples
androidandroid-fragmentsandroid-listviewonitemclicklistenerandroid-adapterview

Fragment ListView onItemClick Highlights Incorrect Item


I have a ListView that is contained within a Fragment. In the onCreateView section I have set a onItemClickListener for the list. My intention was to highlight the item selected, however upon click the space between ListViewItems are colored instead of the item itself. I've also considered using a Selector but have been unsuccessful, IE: view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));

Is there a way to correct this? Or does it necessitate bringing in a new Row with LayoutInflater? Thanks in advance.

Fragment

 public static class FragmentRoutine extends Fragment {
    DatabaseHandler db;
    private ListView routineListView;
    private List<Routine> routines = new ArrayList<Routine>();
    ArrayAdapter<Routine> routineAdapter;
    Routine longClickedItemRoutines;
    private SelectedAdapter selectedAdapter;
    ImageButton btnMoveUp,btnMoveDown;
    public FragmentRoutine() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.routines,
                container, false);
        db = new DatabaseHandler(getActivity().getApplicationContext());
        routineListView = (ListView) rootView.findViewById(R.id.routineList);
        registerForContextMenu(routineListView);
        db.closeDB();
        if (db.getRoutineCount() != 0)
            routines.clear();
        routines.addAll(db.getAllRoutines());
        populateList();
        selectedAdapter = new SelectedAdapter(this.getActivity(),0,routines);
        selectedAdapter.setNotifyOnChange(true);
        routineListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                longClickedItemRoutines = routines.get(position);
                return false;
            }
        });
        routineListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView adapterView, View view,
                                    int position, long id) {
                for (int h = 0; h < adapterView.getChildCount(); h++)
                    adapterView.getChildAt(h).setBackgroundColor(Color.TRANSPARENT);
                // change the background color of the selected element
                view.setBackgroundColor(Color.LTGRAY);
            }
        });// move up event handler

        ImageButton btnMoveUp =(ImageButton) rootView.findViewById(R.id.btnMoveUp);
        btnMoveUp.setOnClickListener(new AdapterView.OnClickListener() {
            public void onClick(View arg0) {
                moveUp();
            }
        });

        // move down event handler
        ImageButton btnMoveDown =(ImageButton) rootView.findViewById(R.id.btnMoveDown);
        btnMoveDown.setOnClickListener(new AdapterView.OnClickListener() {
            public void onClick(View arg0) {
                moveDown();
            }
        });

        setHasOptionsMenu(true);
        return rootView;
    }

Solution

  • you should not update view in setOnItemClickListener, instead, record the position in this function:

    update

    mActiveListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        sSelectedIndex = position;
        // notify ListView's ArrayAdapter that the data attached has been changed, 
        // and any View reflecting the data set should refresh itself.
        yourArrayAdapter.notifyDataSetChanged();
      }
    }
    

    And then update your fragment listview in getView method:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_menu, null);
        }
    
        if (position == sSelectedIndex) {
            convertView.setBackgroundColor(...);
        } else {
            convertView.setBackgroundColor(...);
        }
    
        return convertView;
    }