0

I'm using ViewPager in my app and inside this pager is GridView with data. User is able to select one item from the grid view and show detail information under ViewPager. When user clicked to the item in the GridView, the item is marked by color as selected.

The problem is, that only one item at the time can be selected in all pages of the pager. So when user click on the item on page 1 its marked and than when he selected another one on the page 2 its also marked and the first one on the previous page is still marked as selected. And that is the problem. I need to have selected only one item at time so I need to deselect previous selection after new selection. If it's only on the same page, it works correctly. After next selection, previous item is deselected.

MainFragment -> PagerAdapter -> GridFragment -> GridViewAdapter

In GridFragment I handle OnItemClick and notify GridAdapter on which position was item selected and notifyDataSetChanged().

For each page I'm using his own GridView

PagerAdapter:

 @Override 
 public Fragment getItem(int position) {
        return GridFragment.getInstance(position-(Integer.MAX_VALUE / 2));
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

GridFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_calednar, container, false);

    mAdapter = new CalendarGridViewAdapter(getActivity(), getDateTime(position), MONDAY);

    mGridView = (GridView) rootView.findViewById(R.id.gridView);
    mGridView.setAdapter(mAdapter);

    // TODO handle on item click listener
    mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            mAdapter.setSelectedItem(i);
            mAdapter.notifyDataSetChanged();
        }
    });

    return rootView;
}

GridViewAdapter:

@Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {
       // if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.grid_item_day, null);
        //}

        TextView txt = (TextView) convertView.findViewById(R.id.dayText);
        txt.setText(""+datetimeList.get(i).getDay());
        View actSelection = convertView.findViewById(R.id.actSelection);
        actSelection.setVisibility(View.INVISIBLE);
        if(selectedPosition == i){
            actSelection.setVisibility(View.VISIBLE);
        }

        ....

        return  convertView;
    }

    public void setSelectedItem(int position){
        selectedPosition = position;
    }
Cœur
  • 37,241
  • 25
  • 195
  • 267
Stepan Sanda
  • 2,322
  • 7
  • 31
  • 55
  • paste PagerAdapter as well – vipul mittal Aug 01 '14 at 07:29
  • I added it, please see my edited question. But nothing special there – Stepan Sanda Aug 01 '14 at 07:31
  • Check my ans. It's a bit log but let me know if something is not clear. – vipul mittal Aug 01 '14 at 07:44
  • Are you using multiple gridview for different pages? can share some code snippet to better understand your problem. – Rohit DP Aug 01 '14 at 07:21
  • As you mention that you using multiple gridview on diffrent page in that you have to update your gridview item position on click of selected page gridview item selection and then notify the all gridview on the same onclick of that select gridview item. – Rohit DP Aug 01 '14 at 07:43
  • for better ment of code you can make a data model class which have detail of item your passing to all 3 grid view but you to devide the data position equally with the index or postion so when ever you click on any a item it update the current selection index and then you will update your datamodel object that is common for a three gridview.now you have to just notify the grid view to refresh with latest item. – Rohit DP Aug 01 '14 at 07:51
  • Please see my edited question. Yes, I'm using multiple GridViews for different pages. The problem also can be, that ViewPager adapter holds main page and also previous and next – Stepan Sanda Aug 01 '14 at 07:29

1 Answers1

1

You need to keep the selected item index inside pager adapter instead. And on click of any item inside a fragment change that value.

interface ItemSelectionInterface{
 void onItemSelectionChanged(int fragmentPosition,int itemIndex);
 int getSelectedItemOnFragment(int fragmentPosition); 
}

implement above interface in PagerAdapter:

class YourPagerAdapter.......  implements ItemSelectionInterface{

    int selectedFragment,selectedItem;
@Override 
 public Fragment getItem(int position) {
        return GridFragment.getInstance(position-(Integer.MAX_VALUE / 2),this);
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

     void onItemSelectionChanged(int fragmentPosition,int itemIndex){
          selectedFragment=fragmentPosition;selectedItem=itemIndex;
    }
     int getSelectedItemOnFragment(int fragmentPosition){
      if(fragmentPosition!=selectedFragment) return -1;
      return selectedItem;

    }
}

Change your GridFragment to:

class GridFragment ....{
ItemSelectionInterface selectionInterface;


    @Override
public void setMenuVisibility(final boolean visible) {
    super.setMenuVisibility(visible);
    if (visible) {
        mAdapter.notifyDataSetChanged();
    }
}
public static GridFragment  getInstance(int position, ItemSelectionInterface selectionInterface){
  ...........
  ...........
  this.selectionInterface=selectionInterface;
  }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_calednar, container, false);

    mAdapter = new CalendarGridViewAdapter(getActivity(), getDateTime(position), MONDAY);
mAdapter.setSelectionInterface(selectionInterface);
    mGridView = (GridView) rootView.findViewById(R.id.gridView);
    mGridView.setAdapter(mAdapter);

    // TODO handle on item click listener
    mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            selectionInterface.onItemSelectionChanged(position,i);
            mAdapter.notifyDataSetChanged();
        }
    });
}
    return rootView;
}

And finally in adapter:

     ItemSelectionInterface selectionInterface; //Create a setter for
     int position;//create a setter
@Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {
       // if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.grid_item_day, null);
        //}

        TextView txt = (TextView) convertView.findViewById(R.id.dayText);
        txt.setText(""+datetimeList.get(i).getDay());
        View actSelection = convertView.findViewById(R.id.actSelection);
        actSelection.setVisibility(View.INVISIBLE);
        if(selectionInterface.getSelectedItemOnFragment(position)== i){
            actSelection.setVisibility(View.VISIBLE);
        }

        ....

        return  convertView;
    }
vipul mittal
  • 17,343
  • 3
  • 41
  • 44
  • Big thank you for this! The main princip is working correctly. Unfortunately I'm getting another problem. The pager holds actual page and also previous and next page. So when I select item on one page, go to the next and select item and than go back to previous, the previous item is still selected, because I didn't call notifyDataSetChanged() for previous and next pages. Do you know how can I solve it? Where should I call notifyDataSetChanged() for others pages that pager holds? – Stepan Sanda Aug 01 '14 at 08:03
  • http://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager – vipul mittal Aug 01 '14 at 08:10
  • In the above post you will find a function that is called every time a fragment becomes visible. You can call notifyDataSetChanged in this – vipul mittal Aug 01 '14 at 08:10
  • Great! I was trying to use onAttach, but it doesn't work (the fragment was already attached) But this is working! You saved my day! THX – Stepan Sanda Aug 01 '14 at 08:15