3

GridViewにラジオグループを実装して、グリッドの要素から1つのアイテムのみを選択できるようにします。

助けてください。

4

3 に答える 3

11

グリッドからの要素の選択を制限する目的は、次のように実行できます。

1.グリッド要素の作成。

<LinearLayout
    android:id="@+id/item_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" 
      android:gravity="center">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <RadioButton
        android:id="@+id/radiobtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Image" />


</LinearLayout>

2.アダプタをカスタマイズするgetView()メソッドでこのxmlを膨らませます。

public class MyAdapter extends BaseAdapter {

    Context mCtx;
    int[] mImg;
    LayoutInflater layoutInflater;
    RadioGroup rgp;
    private RadioButton mSelectedRB;
    private int mSelectedPosition = -1;

    public MyAdapter(Context context, int[] img) {
        this.mCtx = context;
        this.mImg = img;
        rgp = new RadioGroup(context);
        layoutInflater = (LayoutInflater) mCtx
                .getSystemService(LAYOUT_INFLATER_SERVICE);

    }

    @Override
    public int getCount() {

        return mImg.length;
    }

    @Override
    public Object getItem(int position) {

        return null;
    }

    @Override
    public long getItemId(int position) {

        return 0;
    }

    @Override
    public View getView(final int position, View convertView,
            ViewGroup parent) {
        View view = convertView;
        Holder holder;

        if (view == null) {
            view = layoutInflater.inflate(R.layout.element, null);
            holder = new Holder();
            holder.image = (ImageView) view.findViewById(R.id.imageView);
            holder.radioButton = (RadioButton) view
                    .findViewById(R.id.radiobtn);
            view.setTag(holder);

        } else {

            holder = (Holder) view.getTag();
        }

        holder.radioButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                if ((position != mSelectedPosition && mSelectedRB != null)) {
                    mSelectedRB.setChecked(false);
                }

                mSelectedPosition = position;
                mSelectedRB = (RadioButton) v;
            }
        });

        if (mSelectedPosition != position) {
            holder.radioButton.setChecked(false);
        } else {
            holder.radioButton.setChecked(true);
            if (mSelectedRB != null && holder.radioButton != mSelectedRB) {
                mSelectedRB = holder.radioButton;
            }
        }

        return view;
    }

}

private class Holder {

    ImageView image;
    RadioButton radioButton;

}
于 2012-10-11T11:03:39.237 に答える
1

これに対する別のアプローチRadioButtonは、追加のXML属性(などgroup)を持つ独自のサブクラスを作成することです。これは、ボタンが属するグループを(文字列として)指定します。次に、サブクラスで、特定のグループ内で1つのラジオボタンのみが選択されていることを確認します。

これは次のように実行できます。

res/values/attrs.xmlまず、次のようなファイルを作成します。

<resources>
  <declare-styleable name="GroupedRadioButton">
    <attr name="group" format="string"/>
  </declare-styleable>
</resources>

次に、サブクラスを作成しますGroupedRadioButton

public class GroupedRadioButton extends RadioButton {

  public GroupedRadioButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    processAttributes(context, attrs);
    setOnClickListener(internalListener, true);
  }

  ...
}

肉付けされたら(以下を参照)、レイアウトファイルで次のようにこの新しいクラスを使用できます。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:custom="http://schemas.android.com/apk/res/com.example.app"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >

<com.example.app.GroupedRadioButton
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Option 1"
    custom:group="group1" />

<com.example.app.GroupedRadioButton
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Option 2"
    custom:group="group1" />

<com.example.app.GroupedRadioButton
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Option 3"
    custom:group="group1" />

<com.example.app.GroupedRadioButton
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Option A"
    custom:group="group2" />

<com.example.app.GroupedRadioButton
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Option B"
    custom:group="group2" />

...

ラジオボタンは、レイアウトのどこにでも配置できます(例:)GridViewxmlns:customカスタム属性を使用しているため、タグが必要であることに注意してください。

上記のレイアウトでは、オプション1、2、および3が相互に排他的になり、オプションAとBが相互に排他的になります。

GroupedRadioButtonこれは、各グループ内で現在選択されているものを(静的に)追跡することによって実現されます。

public class GroupedRadioButton extends RadioButton {

  private static Map<String, WeakReference<GroupedRadioButton>> buttonMap;

  static {
    buttonMap = new HashMap<String, WeakReference<GroupedRadioButton>>();
  }

  ...
}

ここでは、ボタンへの強い参照を保持しないように注意する必要があります。そうしないと、ボタンがガベージコレクションされることはありません。

上記processAttributes()のコンストラクターで指定されたメソッドは、指定したXMLから属性を掘り出し、groupこれをインスタンスデータとして設定します。

private void processAttributes(Context context, AttributeSet attrs) {
  TypedArray attributes = context.obtainStyledAttributes(attrs,
    R.styleable.GroupedRadioButton);
    int attributeCount = attributes.getIndexCount();
    for (int i = 0; i < attributeCount; ++i) {
      int attr = attributes.getIndex(i);
      switch (attr) {
      case R.styleable.GroupedRadioButton_group:
        this.groupName = attributes.getString(attr);
        break;
    }
  }
  attributes.recycle();
}

OnClickListenerこのクラスのメインを定義します。

private OnClickListener internalListener = new OnClickListener() {

  @Override
  public void onClick(View view) {
    processButtonClick(view);
  }
};

呼び出す:

private void processButtonClick(View view) {
  if (!(view instanceof GroupedRadioButton))
    return;

  GroupedRadioButton clickedButton = (GroupedRadioButton) view;
  String groupName = clickedButton.groupName;
  WeakReference<GroupedRadioButton> selectedButtonReference = buttonMap.get(groupName);
  GroupedRadioButton selectedButton = selectedButtonReference == null ? null : selectedButtonReference.get();
  if (selectedButton != clickedButton) {
    if (selectedButton != null)
      selectedButton.setChecked(false);
    clickedButton.setChecked(true);
    buttonMap.put(groupName, new WeakReference<GroupedRadioButton>(clickedButton));
  }
  if (externalListener != null)
    externalListener.onClick(view);
}

これは2つのことを行います。新しいボタンを選択する前に、古いグループボタンの選択を解除します(古いボタンと新しいボタンが異なると仮定します)。次に、クラスのユーザーが独自の「クリック時」機能を追加できるように、提供さonClick()れているを呼び出します。externalListener

コンストラクターでのsetOnClickListener()呼び出しは、次のように独自のメソッドを呼び出します。

private void setOnClickListener(OnClickListener listener, boolean internal) {
  if (internal)
    super.setOnClickListener(internalListener);
  else
    this.externalListener = listener;
}

これによりinternalListener、が公式OnClickListenerに設定され、外部リスナーに適切なインスタンスデータが設定されます。その後、View.setOnClickListener()メソッドは次のようにオーバーライドできます。

@Override
public void setOnClickListener(OnClickListener listener) {
  setOnClickListener(listener, false);
}

この回答が長かったことをお詫びしますが、あなたや他の人が同じことをしようとしているのに役立つことを願っています。RadioGroupもちろん、その子に再帰的に適用すれば、まったく必要ありません!

于 2013-09-23T19:06:02.040 に答える
0

グリッドの要素を選択するときは、ラジオグループに含める他の要素が選択されていないこと、および選択が解除されていることを確認してください...

于 2012-10-08T12:37:13.560 に答える