programing tip

객관식 Android Spinner

itbloger 2020. 12. 27. 10:25
반응형

객관식 Android Spinner


여러 항목을 선택할 수있는 스피너 (예 : 확인란이있는 스피너)를 어떻게 만듭니 까?


MultiSpinner의 사용자 지정 구현을 작성했습니다. 일반 스피너와 비슷해 보이지만 라디오 버튼 대신 확인란이 있습니다. 선택한 값은 쉼표로 나눈 스피너에 표시됩니다. 기본적으로 모든 값이 선택됩니다. 시도 해봐:

package cz.destil.settleup.gui;

public class MultiSpinner extends Spinner implements
        OnMultiChoiceClickListener, OnCancelListener {

    private List<String> items;
    private boolean[] selected;
    private String defaultText;
    private MultiSpinnerListener listener;

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

    public MultiSpinner(Context arg0, AttributeSet arg1) {
        super(arg0, arg1);
    }

    public MultiSpinner(Context arg0, AttributeSet arg1, int arg2) {
        super(arg0, arg1, arg2);
    }

    @Override
    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
        if (isChecked)
            selected[which] = true;
        else
            selected[which] = false;
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        // refresh text on spinner
        StringBuffer spinnerBuffer = new StringBuffer();
        boolean someUnselected = false;
        for (int i = 0; i < items.size(); i++) {
            if (selected[i] == true) {
                spinnerBuffer.append(items.get(i));
                spinnerBuffer.append(", ");
            } else {
                someUnselected = true;
            }
        }
        String spinnerText;
        if (someUnselected) {
            spinnerText = spinnerBuffer.toString();
            if (spinnerText.length() > 2)
                spinnerText = spinnerText.substring(0, spinnerText.length() - 2);
        } else {
            spinnerText = defaultText;
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
                android.R.layout.simple_spinner_item,
                new String[] { spinnerText });
        setAdapter(adapter);
        listener.onItemsSelected(selected);
    }

    @Override
    public boolean performClick() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setMultiChoiceItems(
                items.toArray(new CharSequence[items.size()]), selected, this);
        builder.setPositiveButton(android.R.string.ok,
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
        builder.setOnCancelListener(this);
        builder.show();
        return true;
    }

    public void setItems(List<String> items, String allText,
            MultiSpinnerListener listener) {
        this.items = items;
        this.defaultText = allText;
        this.listener = listener;

        // all selected by default
        selected = new boolean[items.size()];
        for (int i = 0; i < selected.length; i++)
            selected[i] = true;

        // all text on the spinner
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
                android.R.layout.simple_spinner_item, new String[] { allText });
        setAdapter(adapter);
    }

    public interface MultiSpinnerListener {
        public void onItemsSelected(boolean[] selected);
    }
}

다음과 같이 XML에서 사용합니다.

<cz.destil.settleup.gui.MultiSpinner android:id="@+id/multi_spinner" />

그리고 다음과 같이 Java로 데이터를 전달합니다.

MultiSpinner multiSpinner = (MultiSpinner) findViewById(R.id.multi_spinner);
multiSpinner.setItems(items, getString(R.string.for_all), this);

또한 리스너를 구현해야합니다. 리스너는 동일한 길이의 배열을 반환하며, 선택되지 않은 상태로 선택되었음을 표시하려면 true 또는 false입니다.

public void onItemsSelected(boolean[] selected);

나는 스피너처럼 xml에서 "android : entries"를 사용할 수있는 @Destil의 MultiSpinner의 대체 버전을 보여주고 싶습니다. (당신의 영감을주는 코드에 감사드립니다) xml에서 "android : entries"를 사용할 수 있습니다.

처음에는 "choose one"과 같은 기본 텍스트를 표시하지 않지만 ArrayAdapter생성자에서 추가 설정하여 쉽게 얻을 수 있습니다 .

MultiSpinner.java

package com.example.helloworld;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

/**
 * Inspired by: http://stackoverflow.com/a/6022474/1521064
 */
public class MultiSpinner extends Spinner {

    private CharSequence[] entries;
    private boolean[] selected;
    private MultiSpinnerListener listener;

    public MultiSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiSpinner);
        entries = a.getTextArray(R.styleable.MultiSpinner_android_entries);
        if (entries != null) {
            selected = new boolean[entries.length]; // false-filled by default
        }
        a.recycle();
    }

    private OnMultiChoiceClickListener mOnMultiChoiceClickListener = new OnMultiChoiceClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
            selected[which] = isChecked;
        }
    };

    private DialogInterface.OnClickListener mOnClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // build new spinner text & delimiter management
            StringBuffer spinnerBuffer = new StringBuffer();
            for (int i = 0; i < entries.length; i++) {
                if (selected[i]) {
                    spinnerBuffer.append(entries[i]);
                    spinnerBuffer.append(", ");
                }
            }

            // Remove trailing comma
            if (spinnerBuffer.length() > 2) {
                spinnerBuffer.setLength(spinnerBuffer.length() - 2);
            }

            // display new text
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
                    android.R.layout.simple_spinner_item,
                    new String[] { spinnerBuffer.toString() });
            setAdapter(adapter);

            if (listener != null) {
                listener.onItemsSelected(selected);
            }

            // hide dialog
            dialog.dismiss();
        }
    };

    @Override
    public boolean performClick() {
        new AlertDialog.Builder(getContext())
                .setMultiChoiceItems(entries, selected, mOnMultiChoiceClickListener)
                .setPositiveButton(android.R.string.ok, mOnClickListener)
                .show();
        return true;
    }

    public void setMultiSpinnerListener(MultiSpinnerListener listener) {
        this.listener = listener;
    }

    public interface MultiSpinnerListener {
        public void onItemsSelected(boolean[] selected);
    }
}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MultiSpinner">
        <attr name="android:entries" />
    </declare-styleable>
</resources>

layout_main_activity.xml

<com.example.helloworld.MultiSpinner
    android:id="@+id/multispinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:entries="@array/multispinner_entries" />

내가 아는 Spinner한 객관식 모드가 없습니다. 대신 ImageButton오른쪽에 드로어 블 아래쪽 화살표를 만들고 설정할 있으며 클릭 이벤트 Dialog에서 여러 확인란이있는 항목을 열 수 있습니다 .

여기를 참조하십시오 : Android 다중 선택 대화 상자


게시물 주셔서 감사합니다! 훌륭한 솔루션. 사용자가 기본적으로 모든 항목을 true로 선택하는 대신 이미 선택한 항목을 설정할 수 있도록 클래스 (메서드 setItems)를 약간 변경했습니다.

public void setItems(
    List<String> items,
    List<String> itemValues, 
    String selectedList,
    String allText,
    MultiSpinnerListener listener) {
        this.items = items;
        this.defaultText = allText;
        this.listener = listener;

        String spinnerText = allText;

        // Set false by default
        selected = new boolean[itemValues.size()];
        for (int j = 0; j < itemValues.size(); j++)
            selected[j] = false;

        if (selectedList != null) {
            spinnerText = "";
            // Extract selected items
            String[] selectedItems = selectedList.trim().split(",");

            // Set selected items to true
            for (int i = 0; i < selectedItems.length; i++)
                for (int j = 0; j < itemValues.size(); j++)
                    if (selectedItems[i].trim().equals(itemValues.get(j))) {
                        selected[j] = true;
                        spinnerText += (spinnerText.equals("")?"":", ") + items.get(j);
                        break;
                }
    }

        // Text for the spinner
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
            android.R.layout.simple_spinner_item, new String[] { spinnerText });
        setAdapter(adapter);
}

참조 URL : https://stackoverflow.com/questions/5015686/android-spinner-with-multiple-choice

반응형