【问题标题】:Android ViewPager and GridView selectionAndroid ViewPager 和 GridView 选择
【发布时间】:2014-08-01 07:15:02
【问题描述】:

我在我的应用程序中使用ViewPager,在这个寻呼机内部是GridView 和数据。用户可以从网格视图中选择一项并在ViewPager 下显示详细信息。当用户单击GridView 中的项目时,该项目被颜色标记为选中。

问题是,当时只能在寻呼机的所有页面中选择一项。因此,当用户单击第 1 页上的项目时,它被标记,而当他在第 2 页上选择另一个项目时,它也被标记,并且前一页上的第一个项目仍被标记为选中。这就是问题所在。我需要一次只选择一个项目,所以我需要在新选择后取消选择之前的选择。 如果它仅在同一页面上,则它可以正常工作。下一次选择后,取消选择上一项。

MainFragment -> PagerAdapter -> GridFragment -> GridViewAdapter

在GridFragment 中,我处理OnItemClick 并通知GridAdapter 选择了哪个位置以及notifyDataSetChanged()。

对于每个页面,我都使用他自己的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;
    }

【问题讨论】:

  • 您是否对不同的页面使用多个gridview?可以分享一些代码sn-p来更好的理解你的问题。
  • 也粘贴 PagerAdapter
  • 请查看我编辑的问题。是的,我正在为不同的页面使用多个 GridView。问题也可能是,ViewPager 适配器包含主页以及上一个和下一个
  • 我添加了它,请查看我编辑的问题。但没什么特别的
  • 正如您提到的,您在不同页面上使用多个 gridview,因为您必须在单击所选页面 gridview 项目选择时更新您的 gridview 项目位置,然后在该选择的同一 onclick 上通知所有 gridview网格视图项。

标签: android android-layout gridview android-fragments android-viewpager


【解决方案1】:

您需要将所选项目索引保留在寻呼机适配器中。点击片段内的任何项目都会更改该值。

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

在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;

    }
}

将您的 GridFragment 更改为:

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;
}

最后在适配器中:

     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;
    }

【讨论】:

  • 非常感谢您!主要原理工作正常。不幸的是,我遇到了另一个问题。寻呼机保存实际页面以及上一页和下一页。因此,当我在一个页面上选择项目时,转到下一个并选择项目,而不是返回上一个,上一个项目仍然被选中,因为我没有为上一页和下一页调用 notifyDataSetChanged()。你知道我该如何解决吗?对于寻呼机持有的其他页面,我应该在哪里调用 notifyDataSetChanged()?
  • 在上面的帖子中,您会发现每次片段可见时都会调用一个函数。您可以在此调用 notifyDataSetChanged
  • 太棒了!我试图使用 onAttach,但它不起作用(片段已经附加)但这有效!你救了我的一天! THX
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多