GridView MultiChoiceModeListener未显示在Fragment中

时间:2015-08-12 09:29:20

标签: android android-fragments android-gridview

背景

我有Activity,其中包含FragmentFragment包含GridView,其中显示了多个项目。这些项目实现了可检查的界面,该界面根据状态改变背景颜色,并且按预期工作。

现在我想为MultiChoiceModeListener实施GridViewItem

问题是我在MultiChoiceModeListener上设置了GridView,但是当我点击GridView中的项目时,它就不会显示出来。

代码

Activity.java:

public class MainMenuActivity extends AppCompatActivity implements View.OnClickListener {

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {       
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            Intent i = new Intent(this, SettingsActivity.class);
            startActivity(i);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

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

    private void setUpComponents(){
        //Setting up buttons etc.
    }

    @Override
    public void onClick(View v) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        fragmentTransaction.replace(android.R.id.content, new ChoosePhotosFragment());
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
        }
    }
}

Fragment.java:

public class ChoosePhotosFragment extends Fragment implements MediaStoreProvider.OnQueryResultListener, AdapterView.OnItemClickListener {

    private GridView gridView;
    private GridViewAdapter gridAdapter;
    private ArrayList<GridViewObject> objects;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_choose_photos, container, false);
        objects = new ArrayList<>();
        gridView = (GridView) v.findViewById(R.id.gvChoosePhotos);
        gridAdapter = new GridViewAdapter(getActivity(), objects);
        gridView.setAdapter(gridAdapter);
        gridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE);
        gridView.setMultiChoiceModeListener(new MultiChoiceModeListener());
        gridView.setOnItemClickListener(this);

        getData();

        return v;
    }

    public void getData() {
        //Fetching and setting up the adapter with data.
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        System.out.println(gridView.isItemChecked(position));
    }

    public class MultiChoiceModeListener implements
            GridView.MultiChoiceModeListener {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mode.setTitle("Select Items");
            mode.setSubtitle("One item selected");
            System.out.println("onCreateActionMode");
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            System.out.println("onActionItemClicked");
            return true;
        }


        @Override
        public void onDestroyActionMode(ActionMode mode) {
        }

        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                                              long id, boolean checked) {
            System.out.println("onItemCheckedStateChanged");
            int selectCount = gridView.getCheckedItemCount();
            switch (selectCount) {
                case 1:
                    mode.setSubtitle("One item selected");
                    break;
                default:
                    mode.setSubtitle("" + selectCount + " items selected");
                    break;
            }
        }
    }
}

GridViewItem.xml:

<com.marcusjacobsson.vault.widgets.CheckableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:background="@drawable/grid_item_background"
    android:orientation="vertical"
    android:padding="5dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:ellipsize="end"
        android:gravity="center"
        android:singleLine="true"
        android:textSize="12sp" />

</com.marcusjacobsson.vault.widgets.CheckableLayout>

CheckableLayout.java:

public class CheckableLayout extends LinearLayout implements Checkable {
    private boolean mChecked;
    private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};

    public CheckableLayout(Context context) {
        super(context);
    }

    public CheckableLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CheckableLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        }
        return drawableState;
    }

    @Override
    public void setChecked(boolean b) {
        if (b != mChecked) {
            mChecked = b;
            refreshDrawableState();
        }
    }

    public boolean isChecked() {
        return mChecked;
    }

    public void toggle() {
        setChecked(!mChecked);
    }
}

CheckableLayout的背景选择器(背景根据CheckableLayout的状态改变颜色):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" >
        <!-- This applies when the item is checked. -->
        <shape android:shape="rectangle"  >
            <solid android:color="#000" />
        </shape>
    </item>

    <item>
        <!-- This applies when the item is not checked. -->
        <shape android:shape="rectangle"  >
            <solid android:color="#FFF" />
        </shape>
    </item>
</selector>

最后,GridView位于ChoosePhotosFragment布局中:

<GridView
        android:id="@+id/gvChoosePhotos"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:clickable="true"
        android:columnWidth="100dp"
        android:drawSelectorOnTop="true"
        android:focusable="true"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="5dp" />

问题陈述和问题

如上所述,当我检查/点击GridView中的某个项目时,我希望MultiChoiceModeActionBar重叠。目前情况并非如此。根本不调用MultiChoiceMode(没有System.out条消息被打印到日志中,并且视觉上不存在任何动作模式。

我尝试了以下但没有成功:

  • 将GridViewItem.xml中的ImageViewTextView设置为 clickable="false"checkable="false"
  • GridView.CHOICE_MODE_MULTIPLE更改为 GridView.CHOICE_MODE_MULTIPLE_MODAL(这不仅没有用, 但也阻止GridView项目改变背景,就好像 他们不再改变状态)

我无法弄清楚出了什么问题,所以我的问题很简单;我的代码有什么问题?

1 个答案:

答案 0 :(得分:0)

我仍在寻找这个问题的答案,但我已经使用the contextual action mode实施了一个临时解决方法。与MultiChoiceListener的区别在于我使用GridView.OnItemClickListener处理项目的检查/取消选中,而不是使用onItemCheckedStateChanged提供的MultiChoiceListener方法。