programing

첫 글자 "Select One"으로 안드로이드 스피너를 만드는 방법은?

powerit 2023. 6. 27. 22:37
반응형

첫 글자 "Select One"으로 안드로이드 스피너를 만드는 방법은?

처음에 (사용자가 아직 선택하지 않은 경우) "Select One(하나 선택)" 텍스트를 표시하는 Spinner를 사용하려고 합니다.사용자가 스피너를 클릭하면 항목 목록이 표시되고 옵션 중 하나를 선택합니다.사용자가 선택한 후 선택한 항목이 "Select One(하나 선택)" 대신 Spinner(회전판)에 표시됩니다.

스피너를 만들 코드는 다음과 같습니다.

String[] items = new String[] {"One", "Two", "Three"};
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

이 코드를 사용하면 처음에 "One" 항목이 표시됩니다.항목에 "Select One(하나 선택)"이라는 새 항목을 추가하면 드롭다운 목록에 "Select One(하나 선택)"도 첫 번째 항목으로 표시됩니다. 이는 제가 원하는 항목이 아닙니다.

이 문제를 어떻게 해결할 수 있습니까?

당신이 할 수 있는 것은 당신의 것을 장식하는 것입니다.SpinnerAdapterSelect Option(선택 옵션)'을 선택하면 선택하지 않은 에 봅니다.아무것도 선택하지 않은 상태에서 스피너가 표시되도록 처음에 봅니다.

.0용으로 라이브러리에서 은 문제가 에 기존 수정할 수 다음 Android 2.3 및 4.0 ▁fine▁here▁2▁with▁and▁android다음▁tested▁it(다▁works▁for▁code▁2사▁example▁it▁be문것은않없것당▁4▁android 데코레이터이므로 기존 코드를 쉽게 개조할 수 있어야 하며 다음과 함께 작동합니다.CursorLoader (. (분부에커맞춥다니서를또▁on▁(▁s랩다▁the맞춥니▁wrappedap.cursorAdapter

Android 버그로 인해 보기를 다시 사용하기가 조금 어렵습니다.(그래서 당신은 그것을 사용해야 합니다.setTag아니면 당신을 확실히 하기 위한 다른 무언가.convertView맞습니다.)Spinner는 다중 뷰 유형을 지원하지 않습니다.

코드 노트: 생성자 2개

이렇게 하면 표준 프롬프트를 사용하거나 자신의 '선택한 항목 없음'을 첫 번째 행 또는 둘 다 또는 없음으로 정의할 수 있습니다.(참고: 일부 테마에서는 대화 상자 대신 스피너에 대한 드롭다운이 표시됩니다.드롭다운에 일반적으로 프롬프트가 표시되지 않음)

레이아웃을 프롬프트처럼 '모양'으로 정의합니다(예: 회색으로 표시됨).

Initial nothing selected

표준 프롬프트 사용(아무 것도 선택하지 않음):

With a standard prompt

또는 프롬프트와 동적인 것(프롬프트가 없을 수도 있음)을 사용하여:

Prompt and nothing selected row

위 예제의 사용

Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setPrompt("Select your favorite Planet!");

spinner.setAdapter(
      new NothingSelectedSpinnerAdapter(
            adapter,
            R.layout.contact_spinner_row_nothing_selected,
            // R.layout.contact_spinner_nothing_selected_dropdown, // Optional
            this));

contact_spinner_row_nothing_selected.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:textSize="18sp"
    android:textColor="#808080"
    android:text="[Select a Planet...]" />

선택한 SpinnerAdapter.java 없음

import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;

/**
 * Decorator Adapter to allow a Spinner to show a 'Nothing Selected...' initially
 * displayed instead of the first choice in the Adapter.
 */
public class NothingSelectedSpinnerAdapter implements SpinnerAdapter, ListAdapter {

    protected static final int EXTRA = 1;
    protected SpinnerAdapter adapter;
    protected Context context;
    protected int nothingSelectedLayout;
    protected int nothingSelectedDropdownLayout;
    protected LayoutInflater layoutInflater;

    /**
     * Use this constructor to have NO 'Select One...' item, instead use
     * the standard prompt or nothing at all.
     * @param spinnerAdapter wrapped Adapter.
     * @param nothingSelectedLayout layout for nothing selected, perhaps
     * you want text grayed out like a prompt...
     * @param context
     */
    public NothingSelectedSpinnerAdapter(
      SpinnerAdapter spinnerAdapter,
      int nothingSelectedLayout, Context context) {

        this(spinnerAdapter, nothingSelectedLayout, -1, context);
    }

    /**
     * Use this constructor to Define your 'Select One...' layout as the first
     * row in the returned choices.
     * If you do this, you probably don't want a prompt on your spinner or it'll
     * have two 'Select' rows.
     * @param spinnerAdapter wrapped Adapter. Should probably return false for isEnabled(0)
     * @param nothingSelectedLayout layout for nothing selected, perhaps you want
     * text grayed out like a prompt...
     * @param nothingSelectedDropdownLayout layout for your 'Select an Item...' in
     * the dropdown.
     * @param context
     */
    public NothingSelectedSpinnerAdapter(SpinnerAdapter spinnerAdapter,
            int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context) {
        this.adapter = spinnerAdapter;
        this.context = context;
        this.nothingSelectedLayout = nothingSelectedLayout;
        this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout;
        layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public final View getView(int position, View convertView, ViewGroup parent) {
        // This provides the View for the Selected Item in the Spinner, not
        // the dropdown (unless dropdownView is not set).
        if (position == 0) {
            return getNothingSelectedView(parent);
        }
        return adapter.getView(position - EXTRA, null, parent); // Could re-use
                                                 // the convertView if possible.
    }

    /**
     * View to show in Spinner with Nothing Selected
     * Override this to do something dynamic... e.g. "37 Options Found"
     * @param parent
     * @return
     */
    protected View getNothingSelectedView(ViewGroup parent) {
        return layoutInflater.inflate(nothingSelectedLayout, parent, false);
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        // Android BUG! http://code.google.com/p/android/issues/detail?id=17128 -
        // Spinner does not support multiple view types
        if (position == 0) {
            return nothingSelectedDropdownLayout == -1 ?
              new View(context) :
              getNothingSelectedDropdownView(parent);
        }

        // Could re-use the convertView if possible, use setTag...
        return adapter.getDropDownView(position - EXTRA, null, parent);
    }

    /**
     * Override this to do something dynamic... For example, "Pick your favorite
     * of these 37".
     * @param parent
     * @return
     */
    protected View getNothingSelectedDropdownView(ViewGroup parent) {
        return layoutInflater.inflate(nothingSelectedDropdownLayout, parent, false);
    }

    @Override
    public int getCount() {
        int count = adapter.getCount();
        return count == 0 ? 0 : count + EXTRA;
    }

    @Override
    public Object getItem(int position) {
        return position == 0 ? null : adapter.getItem(position - EXTRA);
    }

    @Override
    public int getItemViewType(int position) {
        return 0;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public long getItemId(int position) {
        return position >= EXTRA ? adapter.getItemId(position - EXTRA) : position - EXTRA;
    }

    @Override
    public boolean hasStableIds() {
        return adapter.hasStableIds();
    }

    @Override
    public boolean isEmpty() {
        return adapter.isEmpty();
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        adapter.registerDataSetObserver(observer);
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        adapter.unregisterDataSetObserver(observer);
    }

    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }

    @Override
    public boolean isEnabled(int position) {
        return position != 0; // Don't allow the 'nothing selected'
                                             // item to be picked.
    }

}

다음은 다음과 같은 일반적인 솔루션입니다.Spinner 기보보다 합니다. 그것은 무시합니다.setAdapter()초기 위치를 -1로 설정하고 제공된 위치를 프록시합니다.SpinnerAdapter0보다 에 대한 합니다.

이것은 Android 1.5에서 4.2까지 테스트되었지만 구매자는 주의해야 합니다!이 솔루션은 반영에 의존하여 사설 기관을 호출하기 때문입니다.AdapterView.setNextSelectedPositionInt()그리고.AdapterView.setSelectedPositionInt()향후 OS 업데이트에서 작동하는 것이 보장되지 않습니다.그럴 것 같지만, 결코 장담할 수 없습니다.

보통은 이런 것을 용납하지 않겠지만, 이 질문은 충분히 여러 번 제기되었고 제가 제 해결책을 게시할 것이라고 생각했던 충분히 합리적인 요청인 것 같습니다.

/**
 * A modified Spinner that doesn't automatically select the first entry in the list.
 *
 * Shows the prompt if nothing is selected.
 *
 * Limitations: does not display prompt if the entry list is empty.
 */
public class NoDefaultSpinner extends Spinner {

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

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

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

    @Override
    public void setAdapter(SpinnerAdapter orig ) {
        final SpinnerAdapter adapter = newProxy(orig);

        super.setAdapter(adapter);

        try {
            final Method m = AdapterView.class.getDeclaredMethod(
                               "setNextSelectedPositionInt",int.class);
            m.setAccessible(true);
            m.invoke(this,-1);

            final Method n = AdapterView.class.getDeclaredMethod(
                               "setSelectedPositionInt",int.class);
            n.setAccessible(true);
            n.invoke(this,-1);
        } 
        catch( Exception e ) {
            throw new RuntimeException(e);
        }
    }

    protected SpinnerAdapter newProxy(SpinnerAdapter obj) {
        return (SpinnerAdapter) java.lang.reflect.Proxy.newProxyInstance(
                obj.getClass().getClassLoader(),
                new Class[]{SpinnerAdapter.class},
                new SpinnerAdapterProxy(obj));
    }



    /**
     * Intercepts getView() to display the prompt if position < 0
     */
    protected class SpinnerAdapterProxy implements InvocationHandler {

        protected SpinnerAdapter obj;
        protected Method getView;


        protected SpinnerAdapterProxy(SpinnerAdapter obj) {
            this.obj = obj;
            try {
                this.getView = SpinnerAdapter.class.getMethod(
                                 "getView",int.class,View.class,ViewGroup.class);
            } 
            catch( Exception e ) {
                throw new RuntimeException(e);
            }
        }

        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
            try {
                return m.equals(getView) && 
                       (Integer)(args[0])<0 ? 
                         getView((Integer)args[0],(View)args[1],(ViewGroup)args[2]) : 
                         m.invoke(obj, args);
            } 
            catch (InvocationTargetException e) {
                throw e.getTargetException();
            } 
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        protected View getView(int position, View convertView, ViewGroup parent) 
          throws IllegalAccessException {

            if( position<0 ) {
                final TextView v = 
                  (TextView) ((LayoutInflater)getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE)).inflate(
                      android.R.layout.simple_spinner_item,parent,false);
                v.setText(getPrompt());
                return v;
            }
            return obj.getView(position,convertView,parent);
        }
    }
}

결국 사용하게 되었습니다.Button대신.그러는 동안에Button가 아닙니다.Spinner사용자 지정하기 쉬운 동작입니다.

먼저 평소와 같이 어댑터를 만듭니다.

String[] items = new String[] {"One", "Two", "Three"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_spinner_dropdown_item, items);

는 사용중다니를 .simple_spinner_dropdown_item레이아웃 ID로 지정합니다.이렇게 하면 경고 대화 상자를 만들 때 모양이 더 좋아집니다.

내 단추의 onClick 핸들러에는 다음이 있습니다.

public void onClick(View w) {
  new AlertDialog.Builder(this)
  .setTitle("the prompt")
  .setAdapter(adapter, new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {

      // TODO: user specific action

      dialog.dismiss();
    }
  }).create().show();
}

그게 다야!

은 먼저, 관있것다을입니심이에 이 있을 수 .promptSpinnerclass. "a Planet에서 래스클로 할 수 입니다. 아래 그림을 참조하십시오. "Choose a Planet"은 XML에서 설정할 수 있는 프롬프트입니다.android:prompt="".

enter image description here

저는 하위 분류를 제안하려고 했습니다.Spinner내부적으로 두 개의 어댑터를 유지 관리할 수 있습니다.하나는 "하나 선택" 옵션이 있는 어댑터이고 다른 하나는 실제 옵션이 있는 실제 어댑터입니다. 그런 다음OnClickListener선택 대화 상자가 표시되기 전에 어댑터를 전환합니다.하지만, 그 아이디어를 구현하려고 노력한 결과, 저는 당신이 받을 수 없는 결론에 도달했습니다.OnClick위젯 자체에 대한 이벤트입니다.

에게 말할 수 있습니다.CustomSpinner어댑터를 바꾸려고 했지만, 끔찍한 해킹인 것 같습니다.

"Select One"을 표시해야 합니까?

이 코드는 Android 4.4에서 테스트되었으며 작동합니다.

enter image description here

Spinner spinner = (Spinner) activity.findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, android.R.layout.simple_spinner_dropdown_item) {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                View v = super.getView(position, convertView, parent);
                if (position == getCount()) {
                    ((TextView)v.findViewById(android.R.id.text1)).setText("");
                    ((TextView)v.findViewById(android.R.id.text1)).setHint(getItem(getCount())); //"Hint to be displayed"
                }

                return v;
            }       

            @Override
            public int getCount() {
                return super.getCount()-1; // you dont display last item. It is used as hint.
            }

        };

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        adapter.add("Daily");
        adapter.add("Two Days");
        adapter.add("Weekly");
        adapter.add("Monthly");
        adapter.add("Three Months");
        adapter.add("HINT_TEXT_HERE"); //This is the text that will be displayed as hint.


        spinner.setAdapter(adapter);
        spinner.setSelection(adapter.getCount()); //set the hint the default selection so it appears on launch.
        spinner.setOnItemSelectedListener(this);

이 솔루션을 찾았습니다.

String[] items = new String[] {"Select One", "Two", "Three"};
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
        items[0] = "One";
        selectedItem = items[position];
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {
    }
});

"Select One(하나 선택)"으로 배열 [0]을 변경한 다음 onItem(온Item)에서 변경하기만 하면 됩니다.선택한 경우 이름을 "하나"로 변경합니다.

고급 솔루션은 아니지만 효과가 있습니다.D

여기에는 많은 답이 있지만 아무도 간단한 해결책을 제안하지 않은 것이 놀랍습니다.스피너 위에 텍스트 보기를 배치합니다.TextView가 Spinner를 표시하고 Spinner.performClick()을 호출하는 TextView를 숨깁니다.

Spinner에 힌트를 설정하는 기본 API는 없습니다.추가하려면 안전 반사 구현이 아닌 작은 해결책이 필요합니다.

List<Object> objects = new ArrayList<Object>();
objects.add(firstItem);
objects.add(secondItem);
// add hint as last item
objects.add(hint);

HintAdapter adapter = new HintAdapter(context, objects, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

Spinner spinnerFilmType = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(adapter);

// show hint
spinner.setSelection(adapter.getCount());

어댑터 소스:

public class HintAdapter
        extends ArrayAdapter<Objects> {

    public HintAdapter(Context theContext, List<Object> objects) {
        super(theContext, android.R.id.text1, android.R.id.text1, objects);
    }

    public HintAdapter(Context theContext, List<Object> objects, int theLayoutResId) {
        super(theContext, theLayoutResId, android.R.id.text1, objects);
    }

    @Override
    public int getCount() {
        // don't display last item. It is used as hint.
        int count = super.getCount();
        return count > 0 ? count - 1 : count;
    }
}

원본

저는 스피너에 대해서도 같은 문제를 얻었고, 빈 선택으로 더 나은 해결책을 찾았습니다.이 간단한 코드를 보세요.

Spinner lCreditOrDebit = (Spinner)lCardPayView.findViewById(R.id.CARD_TYPE);
spinneradapter lAdapter = 
  new spinneradapter(
    BillPayScreen.this, 
    ndroid.R.layout.simple_spinner_item,getResources().getStringArray(R.array.creditordebit));
lAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
lCreditOrDebit.setAdapter(lAdapter);

여기서 스피너 어댑터는 어레이 어댑터에 대한 소규모 사용자 지정입니다.다음과 같이 표시됩니다.

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

public class spinneradapter extends ArrayAdapter<String>{
    private Context m_cContext;
    public spinneradapter(Context context,int textViewResourceId, String[] objects) {
        super(context, textViewResourceId, objects);
        this.m_cContext = context;
    }

    boolean firsttime = true;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(firsttime){
            firsttime = false;
            //Just return some empty view
            return new ImageView(m_cContext);
        }
        //Let the array adapter take care of it this time.
        return super.getView(position, convertView, parent);
    }
}

텍스트 보기로 변경하고 다음을 사용할 수 있습니다.

android:style="@android:style/Widget.DeviceDefault.Light.Spinner"

합니다.android:text소유물.

XML 파일:

<Spinner android:id="@+id/locationSpinner"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:prompt="@string/select_location" />

활동:

private Spinner featuresSelection;
private ArrayAdapter<CharSequence> featuresAdapter;
private List<CharSequence> featuresList;

작성 시:

featuresList = new ArrayList<CharSequence>();
featuresAdapter = new ArrayAdapter<CharSequence>(this,
  android.R.layout.simple_spinner_item, featuresList);
featuresAdapter.setDropDownViewResource(
  android.R.layout.simple_spinner_dropdown_item);
featuresSelection = ((Spinner) yourActivity.this
  .findViewById(R.id.locationSpinner));
featuresSelection.setAdapter(featuresAdapter);
featuresSelection.setOnItemSelectedListener(
  new MyOnItemSelectedListener());

일부 기능(어댑터에 프로그래밍 방식으로 추가)>

featuresAdapter.add("some string");

이제 빈 스피너가 있고 빈 경우 대화 상자를 열지 않는 코드를 작성할 수 있습니다.아니면 다시 누를 수도 있습니다.그러나 실행 시간 동안 함수 또는 다른 목록으로 채우기도 합니다.

또한 기본값을 표시하는 간단한 트릭이 있습니다.

목에기본추후사다용모여하추수있다컬습을 사용하여 모든 할 수 .list.addAll(yourCollection);

샘플 실행 가능한 코드는 다음과 같습니다.

List<FuelName> fuelList = new ArrayList<FuelName>();
                    fuelList.add(new FuelName(0,"Select One"));
                    fuelList.addAll(response.body());
                    ArrayAdapter adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, fuelList);
                    //fuelName.setPrompt("Select Fuel");
                    fuelName.setAdapter(adapter);

는 "main.xml"입니다.@+id/spinner1

이것은 내 OnCreate 기능에 내가 쓰는 것입니다.

spinner1 = (Spinner)this.findViewById(R.id.spinner1);
final String[] groupes = new String[] {"A", "B", "C", "D", "E", "F", "G", "H"};
ArrayAdapter<CharSequence> featuresAdapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_spinner_item, new ArrayList<CharSequence>());
featuresAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(featuresAdapter);
for (String s : groupes) featuresAdapter.add(s);

spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
     public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
         // Here go your instructions when the user chose something
         Toast.makeText(getBaseContext(), groupes[position], 0).show();
     }
     public void onNothingSelected(AdapterView<?> arg0) { }
});

그것은 수업에서 어떤 구현도 필요하지 않습니다.

저는 다음과 같이 노력했습니다.버튼을 클릭하여 클릭 이벤트를 제공합니다.버튼 배경을 변경하여 스피너로 보입니다.

글로벌 변수 경고 대화 상자 및 기본값으로 선언합니다.

AlertDialog d;
static int default_value = 0;
final Button btn = (Button) findViewById(R.id.button1);
btn .setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v)
{
    //c.show();
    final CharSequence str[] = {"Android","Black Berry","Iphone"};
        AlertDialog.Builder builder =
          new AlertDialog.Builder(TestGalleryActivity.this).setSingleChoiceItems(
            str, default_value,new  DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int position)
            {
                Toast.makeText(TestGalleryActivity.this,
                               "" + position,
                               Toast.LENGTH_SHORT).show();
                default_value = position;
                btn.setText(str[position]);
                if(d.isShowing())
                    d.dismiss();
            }
        }).setTitle("Select Any");
        d = builder.create();
        d.show();
    }
});

목록의 맨 위에 요소를 추가하는 범용 솔루션은 iosched 앱을 참조하십시오.특히 CursorAdapter를 사용하는 경우 TracksAdapter.java를 보면 "setHasAllItem" 메서드와 관련 코드를 제공하여 맨 위에 있는 추가 항목을 처리할 수 있습니다.

사용자 지정 어댑터를 사용하여 텍스트를 "하나 선택"으로 설정하거나 맨 위 항목에서 원하는 내용을 지정할 수 있습니다.

대부분 어댑터 끝에 항목을 추가하여 작동하고 있으며 드롭다운 목록에 마지막 항목을 표시하지 않습니다.저에게 큰 문제는 스피너 드롭다운 목록이 목록의 맨 아래부터 시작된다는 것이었습니다.따라서 사용자는 스피너를 처음 터치한 후 첫 번째 항목 대신 마지막 항목을 볼 수 있습니다(표시할 항목이 많은 경우).

그래서 힌트 항목을 목록 맨 앞에 놓고 첫 번째 항목은 드롭다운 목록에서 숨깁니다.

private void loadSpinner(){

    HintArrayAdapter hintAdapter = new HintArrayAdapter<String>(context, 0);

    hintAdapter.add("Hint to be displayed");
    hintAdapter.add("Item 1");
    hintAdapter.add("Item 2");
            .
            .
    hintAdapter.add("Item 30");

    spinner1.setAdapter(hintAdapter);

    //spinner1.setSelection(0); //display hint. Actually you can ignore it, because the default is already 0
    //spinner1.setSelection(0, false); //use this if don't want to onItemClick called for the hint

    spinner1.setOnItemSelectedListener(yourListener);
}

private class HintArrayAdapter<T> extends ArrayAdapter<T> {

    Context mContext;

    public HintArrayAdapter(Context context, int resource) {
        super(context, resource);
        this.mContext = context
    }

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
        TextView texview = (TextView) view.findViewById(android.R.id.text1);

        if(position == 0) {
            texview.setText("");
            texview.setHint(getItem(position).toString()); //"Hint to be displayed"
        } else {
            texview.setText(getItem(position).toString());
        }

        return view;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View view;

        if(position == 0){
            view = inflater.inflate(R.layout.spinner_hint_list_item_layout, parent, false); // Hide first row
        } else {
            view = inflater.inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
            TextView texview = (TextView) view.findViewById(android.R.id.text1);
            texview.setText(getItem(position).toString());
        } 

        return view;
    }
}

위치가 0인 경우 아래 레이아웃을 @OverridegetDropDownView()에 설정하여 첫 번째 힌트 행을 숨깁니다.

R.layout.spinner_hint_list_item_layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

</LinearLayout>

제 생각에 가장 쉬운 방법은 색인 0에 "하나 선택"이라고 말하는 더미 항목을 만든 다음 저장할 때 선택이 0이 아닌지 확인하는 것입니다.

이것이 버튼 스피너를 위한 마지막 "올인" 예입니다.

inactivity_my_form.xml

    <Button
        android:id="@+id/btnSpinnerPlanets"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="left|center_vertical"
        android:singleLine="true"
        android:text="@string/selectAPlanet"
        android:textSize="10sp"
        android:background="@android:drawable/btn_dropdown">
    </Button>

strings.xml에서

<string name="selectAPlanet">Select planet&#8230;</string>

<string-array name="planets__entries">
    <item>The Sun with a name very long so long long long long longThe Sun with a name very long so long long long long longThe Sun with a name very long so long long long long long</item>
    <item>Mercury</item>
    <item>Venus</item>
    <item>Earth</item>
    <item>Mars</item>
    <item>Jupiter</item>
    <item>Saturn</item>
    <item>Uranus</item>
    <item>Neptune</item>
</string-array>

양식 활동.java

public class MyFormActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ((Button) findViewById(R.id.btnSpinnerPlanets)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final String[] items = view.getResources().getStringArray(R.array.planets__entries);
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(MyFormActivity.this, android.R.layout.simple_spinner_dropdown_item, items);
                new AlertDialog.Builder(MyFormActivity.this).setTitle("the prompt").setAdapter(adapter, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((Button) findViewById(R.id.btnSpinnerPlanets)).setText(items[which]);
                        dialog.dismiss();
                    }
                }).create().show();
            }
        });     

    }

}   

마침내 나는 첫 번째 항목 선택 가능한 버튼 스피너 없이 구성 가능한 글꼴 크기를 얻었습니다!!!HRJ 덕분에

제가 찾은 가장 좋은 해결책은 사실 스피너를 사용하는 것이 아니라 오토 컴플리트를 사용하는 것입니다.텍스트 보기.기본적으로 입력할 때 제안을 표시하기 위해 Spinner가 부착된 EditText이지만, 올바른 구성으로 OP가 원하는 대로 정확히 동작할 수 있습니다.

XML:

<com.google.android.material.textfield.TextInputLayout
                android:id="@+id/item"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            <androidx.appcompat.widget.AppCompatAutoCompleteTextView
                    android:id="@+id/input"
                    android:hint="Select one"
                    style="@style/AutoCompleteTextViewDropDown"/>
        </com.google.android.material.textfield.TextInputLayout>

스타일:

<style name="AutoCompleteTextViewDropDown">
    <item name="android:clickable">false</item>
    <item name="android:cursorVisible">false</item>
    <item name="android:focusable">false</item>
    <item name="android:focusableInTouchMode">false</item>
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
</style>

어댑터의 경우 기본 어레이 어댑터를 사용하거나 확장하여 직접 만들지만 어댑터 측에서 추가 사용자 지정이 필요하지 않습니다.어댑터를 자동 완성으로 설정합니다.텍스트 보기.

를 할 때SpinnerAdapter당신은 두 개를 오버라이드합니다.View -생산방법,getView(int, View, ViewGroup)그리고.getDropDownView(int, View, ViewGroup)첫 번째 것이 공급합니다.View에된입에 Spinner그 자체; 두 번째 공급.View(이름에서 알 수 있듯이) 드롭다운 목록에 있습니다.다음을 재정의할 수 있습니다.getView(...)을 선택할 까지, 은 그서래, 이선될때, 은표됩니를 표시합니다.TextView후 된 것을 합니다.TextView그에 상응하는

public class PromptingAdapter extends SpinnerAdapter {

    //... various code ...

    private boolean selectionmade = false;

    //call this method from the OnItemSelectedListener for your Spinner
    public setSelectionState(boolean b) {
        selectionmade = b;
    }

    @Override
    public View getView(int position, View recycle, ViewGroup container) {
        if(selectionmade) {
            //your existing code to supply a View for the Spinner
            //you could even put "return getDropDownView(position, recycle, container);"
        }
        else {
            View output;
            if(recycle instanceof TextView) {
                 output = recycle;
            }
            else {
                 output = new TextView();
                 //and layout stuff
            }
            output.setText(R.string.please_select_one);
            //put a string "please_select_one" in res/values/strings.xml
            return output;
        }
    }

//...
}

Xamarin을 사용하는 사람들을 위해, 위의 Aaronvargas의 답변에 해당하는 C#이 있습니다.

using Android.Content;
using Android.Database;
using Android.Views;
using Android.Widget;
using Java.Lang;

namespace MyNamespace.Droid
{ 
  public class NothingSelectedSpinnerAdapter : BaseAdapter, ISpinnerAdapter, IListAdapter
  {
    protected static readonly int EXTRA = 1;
    protected ISpinnerAdapter adapter;
    protected Context context;
    protected int nothingSelectedLayout;
    protected int nothingSelectedDropdownLayout;
    protected LayoutInflater layoutInflater;

    public NothingSelectedSpinnerAdapter(ISpinnerAdapter spinnerAdapter, int nothingSelectedLayout, Context context) : this(spinnerAdapter, nothingSelectedLayout, -1, context)
    {
    }

    public NothingSelectedSpinnerAdapter(ISpinnerAdapter spinnerAdapter, int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context)
    {
      this.adapter = spinnerAdapter;
      this.context = context;
      this.nothingSelectedLayout = nothingSelectedLayout;
      this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout;
      layoutInflater = LayoutInflater.From(context);
    }

    protected View GetNothingSelectedView(ViewGroup parent)
    {
      return layoutInflater.Inflate(nothingSelectedLayout, parent, false);
    }

    protected View GetNothingSelectedDropdownView(ViewGroup parent)
    {
      return layoutInflater.Inflate(nothingSelectedDropdownLayout, parent, false);
    }

    public override Object GetItem(int position)
    {
      return position == 0 ? null : adapter.GetItem(position - EXTRA);
    }

    public override long GetItemId(int position)
    {
      return position >= EXTRA ? adapter.GetItemId(position - EXTRA) : position - EXTRA;
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
      // This provides the View for the Selected Item in the Spinner, not
      // the dropdown (unless dropdownView is not set).
      if (position == 0)
      {
        return GetNothingSelectedView(parent);
      }

      // Could re-use the convertView if possible.
      return this.adapter.GetView(position - EXTRA, null, parent);
    }

    public override int Count
    {
      get
      {
        int count = this.adapter.Count;
        return count == 0 ? 0 : count + EXTRA;
      }
    }

    public override View GetDropDownView(int position, View convertView, ViewGroup parent)
    {
      // Android BUG! http://code.google.com/p/android/issues/detail?id=17128 -
      // Spinner does not support multiple view types
      if (position == 0)
      {
        return nothingSelectedDropdownLayout == -1 ?
          new View(context) :
          GetNothingSelectedDropdownView(parent);
      }

      // Could re-use the convertView if possible, use setTag...
      return adapter.GetDropDownView(position - EXTRA, null, parent);
    }

    public override int GetItemViewType(int position)
    {
      return 0;
    }

    public override int ViewTypeCount => 1;

    public override bool HasStableIds => this.adapter.HasStableIds;

    public override bool IsEmpty => this.adapter.IsEmpty;

    public override void RegisterDataSetObserver(DataSetObserver observer)
    {
      adapter.RegisterDataSetObserver(observer);
    }

    public override void UnregisterDataSetObserver(DataSetObserver observer)
    {
      adapter.UnregisterDataSetObserver(observer);
    }

    public override bool AreAllItemsEnabled()
    {
      return false;
    }

    public override bool IsEnabled(int position)
    {
      return position > 0;
    }
  }
}

저는 또한 아래 코드를 사용하여 이 문제를 해결했습니다.예를 들어 항목 목록이 있다고 가정합니다.

ArrayList<Item> itemsArrayList = new ArrayList<Item>();
Item item1 = new Item();
item1.setId(1);
item1.setData("First Element");
Item item2 = new Item();
item2.setId(2);
Item2.setData("Second Element");
itemsArrayList.add(item1);
itemsArrayList.add(item2);

이제 스피너는 물체를 이해할 수 없기 때문에 스피너에게 줄을 제공해야 합니다.그래서 우리는 다음과 같은 문자열 항목으로 새로운 배열 목록을 만들 것입니다 ->

ArrayList<String> itemStringArrayList = new ArrayList<String>();
for(Item item : itemsArrayList) {
    itemStringArrayList.add(item.getData());
}

, 이제 이제우는이 .itemStringArrayList두 개의 문자열 항목이 있는 배열 목록입니다.그리고 "Select Item" 텍스트를 첫 번째 항목으로 표시해야 합니다.는 서래우새문삽합입니다야해을에 .itemStringArrayList.

itemStringArrayList.add("Select Item");

이제 우리는 배열 목록을 가지고 있습니다.itemsArrayList드롭다운에서 두 가지 요소를 보여드리겠습니다.하지만 여기 조건은... 가아선않지그으때면하택도무우것리.Select Item활성화되지 않을 첫 번째 요소로 나타납니다.

그래서 우리는 이런 기능을 구현할 수 있습니다.Android 스피너에 배열 목록 항목을 로드해야 하는 경우.그래서 당신은 어댑터를 사용해야 할 것입니다.그래서 여기서 저는 그것을 사용할 것입니다.ArrayAdapter우리는 커스텀 어댑터도 사용할 수 있습니다.

ArrayAdapter<String> itemsArrayAdapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.spinner_item, itemsArrayList){
        @Override
        public boolean isEnabled(int position) {
            if(position == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        @Override
        public View getDropDownView(int position, View convertView,
                                    ViewGroup parent) {
            View view = super.getDropDownView(position, convertView, parent);
            TextView tv = (TextView) view;
            if(position == 0){
                // Set the hint text color gray
                tv.setTextColor(Color.GRAY);
            }
            else {
                tv.setTextColor(Color.BLACK);
            }
            return view;
        }
    };

itemsArrayAdapter.setDropDownViewResource(R.layout.spinner_item);
your_spinner_name.setAdapter(itemsArrayAdapter);

맞춤형 스피너 레이아웃을 사용하고 있습니다. R.layout.spinner_item

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textStyle="italic"
    android:fontFamily="sans-serif-medium"
    />

스피너의 첫 번째 텍스트를 비활성화해야 합니다.그래서 위치 0에 대해서는 텍스트를 비활성화합니다.또한 getDropDownView 메서드를 무시하여 색상을 설정할 수 있습니다.이 방법으로 우리는 예상되는 스피너를 얻을 것입니다.

저는 어제 같은 문제에 직면하여 Array Adapter에 숨겨진 항목을 추가하거나 반사를 사용하고 싶지 않았습니다. 반사는 잘 작동하지만 좀 지저분합니다.

많은 게시물을 읽고 주변을 둘러본 후 확장하여 해결책을 찾았습니다.ArrayAdapter 그고재의정리를 합니다.getView방법.

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * A SpinnerAdapter which does not show the value of the initial selection initially,
 * but an initialText.
 * To use the spinner with initial selection instead call notifyDataSetChanged().
 */
public class SpinnerAdapterWithInitialText<T> extends ArrayAdapter<T> {

    private Context context;
    private int resource;

    private boolean initialTextWasShown = false;
    private String initialText = "Please select";

    /**
     * Constructor
     *
     * @param context The current context.
     * @param resource The resource ID for a layout file containing a TextView to use when
     *                 instantiating views.
     * @param objects The objects to represent in the ListView.
     */
    public SpinnerAdapterWithInitialText(@NonNull Context context, int resource, @NonNull T[] objects) {
        super(context, resource, objects);
        this.context = context;
        this.resource = resource;
    }

    /**
     * Returns whether the user has selected a spinner item, or if still the initial text is shown.
     * @param spinner The spinner the SpinnerAdapterWithInitialText is assigned to.
     * @return true if the user has selected a spinner item, false if not.
     */
    public boolean selectionMade(Spinner spinner) {
        return !((TextView)spinner.getSelectedView()).getText().toString().equals(initialText);
    }

    /**
     * Returns a TextView with the initialText the first time getView is called.
     * So the Spinner has an initialText which does not represent the selected item.
     * To use the spinner with initial selection instead call notifyDataSetChanged(),
     * after assigning the SpinnerAdapterWithInitialText.
     */
    @Override
    public View getView(int position, View recycle, ViewGroup container) {
        if(initialTextWasShown) {
            return super.getView(position, recycle, container);
        } else {
            initialTextWasShown = true;
            LayoutInflater inflater = LayoutInflater.from(context);
            final View view = inflater.inflate(resource, container, false);

            ((TextView) view).setText(initialText);

            return view;
        }
    }
}

할 때 한 후 드안이스를초항선기의 를 호출하는 입니다.T[] objects.SpinnerAdapterWithInitialText를 반환합니다.TextViewinitialText처음으로 전화를 걸었을 때.다른 시간에는 전화가 걸려옵니다.super.getView은 느어쪽이입니다.getViewArrayAdapter이는 Spinner를 정상적으로 사용하는 경우 호출됩니다.

initialText, 전화 걸기selectionMade어댑터가 할당된 스피너를 넘겨줍니다.

가볍고 사용자 지정 가능한 라이브러리를 통해 다음과 같은 답변을 확인할 수 있습니다.

https://stackoverflow.com/a/73085435/6694920

<com.innowisegroup.hintedspinner.HintedSpinner
android:id="@+id/hintedSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
app:hintTextSize="24sp"
app:hintTextColor="@color/red"
app:hint="Custom hint"
app:withDivider="true"
app:dividerColor="@color/dark_green"
app:arrowDrawable="@drawable/example_arrow_4"
app:arrowTint="@color/colorAccent"
app:popupBackground="@color/light_blue"
app:items="@array/text" />

접힌 스피너:

확장 스피너:

enter image description here

라디오 단추가 있는 라디오 그룹을 사용하면 세 가지 옵션만 선택할 수 있습니다. 처음에는 모두 선택 해제할 수 있습니다.

이전에 제출된 답변 중 제가 이 문제를 해결하고자 하는 방식으로 제대로 작동한 답변은 없었습니다.나에게 이상적인 솔루션은 스피너가 처음 표시될 때 "Select One"(또는 초기 텍스트)을 제공할 것입니다.사용자가 스피너를 탭할 때 초기 텍스트는 표시되는 드롭다운 부분이 아니어야 합니다.

제 특정 상황을 더욱 복잡하게 만들기 위해, 제 스피너 데이터는 LoaderManager 콜백을 통해 로드되는 커서에서 옵니다.

상당한 실험 끝에 저는 다음과 같은 해결책을 생각해냈습니다.

public class MyFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>{

private static final String SPINNER_INIT_VALUE = "Select A Widget";
private Spinner mSpinner;
private int mSpinnerPosition;
private boolean mSpinnerDropDownShowing = false;
private View mSpinnerDropDown;

private MyCursorAdapter mCursorAdapter;

...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
...

mCursorAdapter = new MyCursorAdapter(getActivity());

mSpinner = (Spinner) rootView.findViewById(R.id.theSpinner);
mSpinner.setOnTouchListener(mSpinnerTouchListener);
mSpinner.setAdapter(mCursorAdapter);

...
}

//Capture the touch events to toggle the spinner's dropdown visibility
private OnTouchListener mSpinnerTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if(mSpinnerDropDown != null && mSpinnerDropDownShowing == false){
            mSpinnerDropDownShowing = true;
            mSpinnerDropDown.setVisibility(View.VISIBLE);
        }
        return false;
    }
};

//Capture the click event on the spinner drop down items
protected OnClickListener spinnerItemClick = new OnClickListener(){

    @Override
    public void onClick(View view) {
        String widget = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();

        if(!widget.equals(SPINNER_INIT_VALUE)){
            if(mCursorAdapter != null){
                Cursor cursor = mCursorAdapter.getCursor();
                if(cursor.moveToFirst()){
                    while(!cursor.isAfterLast()){
                        if(widget.equals(cursor.getString(WidgetQuery.WIDGET_NAME))){

                            ...

                            //Set the spinner to the correct item
                            mSpinnerPosition = cursor.getPosition() + 1;
                            mSpinner.setSelection(mSpinnerPosition);
                            break;
                        }
                        cursor.moveToNext();
                    }
                }
            }
        }

        //Hide the drop down. Not the most elegent solution but it is the only way I could hide/dismiss the drop down
        mSpinnerDropDown = view.getRootView();
        mSpinnerDropDownShowing = false;
        mSpinnerDropDown.setVisibility(View.GONE);
    }
};

private class MyCursorAdapter extends CursorAdapter {

    private final int DISPLACEMENT = 1;
    private final int DEFAULT_ITEM_ID = Integer.MAX_VALUE;

    private Activity mActivity;

    public MyCursorAdapter(Activity activity) {
            super(activity, null, false);
            mActivity = activity;
    }

    //When loading the regular views, inject the defualt item
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(position == 0){
            if(convertView == null){
                convertView = mActivity.getLayoutInflater().inflate(R.layout.list_item_widget, parent, false);
            }
            return getDefaultItem(convertView);
        }
        return super.getView(position - DISPLACEMENT, convertView, parent);
    }

    //When loading the drop down views, set the onClickListener for each view
    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent){
        View view = super.getDropDownView(position, convertView, parent);
        view.setOnClickListener(spinnerItemClick);
        return view;
    }

    //The special default item that is being injected
    private View getDefaultItem(View convertView){
        TextView text = (TextView) convertView.findViewById(android.R.id.text1);
        text.setText(SPINNER_INIT_VALUE);
        return convertView;
    }

    @Override
    public long getItemId(int position) {
        if (position == 0) {
            return DEFAULT_ITEM_ID;
        }
        return super.getItemId(position - DISPLACEMENT);
    }

    @Override
    public boolean isEnabled(int position) {
        return position == 0 ? true : super.isEnabled(position - DISPLACEMENT);
    }

    @Override
    public int getViewTypeCount() {
        return super.getViewTypeCount() + DISPLACEMENT;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return super.getViewTypeCount();
        }

        return super.getItemViewType(position - DISPLACEMENT);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return mActivity.getLayoutInflater().inflate(R.layout.list_item_widget, parent, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor){

        if(cursor.isAfterLast()){
            return;
        }

        TextView text = (TextView) view.findViewById(android.R.id.text1);
        String WidgetName = cursor.getString(WidgetQuery.WIDGET_NAME);
        text.setText(WidgetName);
    }
}
}

저는 스피너 대신 버튼을 사용하여 처리합니다.GitHub에 샘플 프로젝트가 있습니다.

프로젝트에서 저는 스피너와 버튼을 모두 표시하여 둘이 실제로 동일하게 보인다는 것을 보여주고 있습니다.초기 텍스트를 원하는 대로 설정할 수 있는 단추만 제외합니다.

활동 내용은 다음과 같습니다.

package com.stevebergamini.spinnerbutton;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Spinner;

public class MainActivity extends Activity {

    Spinner spinner1;
    Button button1;
    AlertDialog ad;
    String[] countries;

    int selected = -1;

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

        spinner1 = (Spinner) findViewById(R.id.spinner1);
        button1 = (Button) findViewById(R.id.button1);

        countries = getResources().getStringArray(R.array.country_names);

        //  You can also use an adapter for the allert dialog if you'd like
        //  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, countries);        

        ad = new AlertDialog.Builder(MainActivity.this).setSingleChoiceItems(countries, selected,  
                new  DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            button1.setText(countries[which]);
                            selected = which;
                            ad.dismiss();

                        }}).setTitle(R.string.select_country).create(); 


        button1.setOnClickListener( new OnClickListener(){

            @Override
            public void onClick(View v) {
                ad.getListView().setSelection(selected);
                ad.show();              
            }});

    }

}

참고: 예, 적용된 테마에 따라 다르며 테마를 사용할 경우 모양이 약간 달라집니다.Holo. 단, 테마와 같은 기존 테마 중 하나를 사용하는 경우.블랙, 가도 돼요

진부한 해결책인 것 같지만, 저는 보통 스피너 앞에 TextView를 붙입니다.전체 Xml은 다음과 같습니다.(얘들아, 날 쏘지 마, 너희 중 몇몇은 이런 결혼을 좋아하지 않는다는 걸 알아):

<FrameLayout
    android:id="@+id/selectTypesLinear"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <Spinner
        android:id="@+id/spinnerExercises"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/exercise_spinner_entries"
        android:prompt="@string/exercise_spinner_prompt"
     />                         
    <TextView
        android:id="@+id/spinnerSelectText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Hey! Select this guy!"
        android:gravity="center"
        android:background="#FF000000" />


</FrameLayout>

그런 다음 항목을 선택할 때 텍스트 보기를 숨깁니다.TextView의 배경색은 Spinner와 동일해야 합니다.Android 4.0에서 작동합니다.이전 버전에서는 알 수 없습니다.

예. Spinner가 처음에 OnItemSelectedListener를 호출하기 때문에 텍스트 보기를 숨기는 것은 약간 까다로울 수 있지만 다음과 같은 방법으로 수행할 수 있습니다.

    Boolean controlTouched;

    exerciseSpinner.setOnTouchListener(new OnTouchListener() {


        @Override
        public boolean onTouch(View v, MotionEvent event) {
            controlTouched = true; // I touched it but but not yet selected an Item.
            return false;
        }

    });
    exerciseSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                int arg2, long arg3) {
            if (controlTouched) { // Are you sure that I touched it with my fingers and not someone else  ?
                spinnerSelText.setVisibility(View.GONE);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }

    });

저에게는 이런 식으로 작동했습니다.일부 옵션의 텍스트만 변경할 수 있으며 일부 옵션의 텍스트만 변경할 수 있습니다.

먼저 스피너의 이름을 사용하여 사용자 정의 보기를 사용하여 어레이 어댑터를 만들지만, 지금은 중요하지 않습니다. 키는 getView를 재정의하고 내부에서 변경해야 하는 값을 변경하는 것입니다.제 경우는 첫 번째 것뿐이고, 나머지는 원본을 남깁니다.

public void rellenarSpinnerCompeticiones(){
        spinnerArrayCompeticiones = new ArrayList<String>();
        for(Competicion c: ((Controlador)getApplication()).getCompeticiones()){
            spinnerArrayCompeticiones.add(c.getNombre());
        }
        //ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this,R.layout.spinner_item_competicion,spinnerArrayCompeticiones);
        ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item_competicion, spinnerArrayCompeticiones){
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                final View v = vi.inflate(R.layout.spinner_item_competicion, null);
                final TextView t = (TextView)v.findViewById(R.id.tvCompeticion);
                if(spinnerCompeticion.getSelectedItemPosition()>0){
                    t.setText(spinnerArrayCompeticiones.get(spinnerCompeticion.getSelectedItemPosition()));
                }else{
                    t.setText("Competiciones");
                }
                return v;
            }
        };
        spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerCompeticion.setAdapter(spinnerArrayAdapter);
    }

답변 중 하나를 참조하십시오. https://stackoverflow.com/a/23005376/1312796

작은 버그를 수정하기 위해 코드를 추가했습니다.데이터가 검색되지 않은 곳에서..프롬프트 텍스트를 표시하는 방법...!

여기 내 트릭이 있습니다...저랑 잘 어울려요!

Spinner를 Relative_layout에 넣고 Spinner의 어댑터가 로드되거나 비어 있을 때마다 Textview를 Spinner와 정렬하고 Textview(SHOW/HIDE)의 가시성으로 재생합니다.다음과 같이:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="20dp"
android:background="#ededed"
android:orientation="vertical">



    <TextView
        android:id="@+id/txt_prompt_from"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:textColor="@color/gray"
        android:textSize="16sp"
        android:layout_alignStart="@+id/sp_from"
        android:text="From"
        android:visibility="gone"/>

    <Spinner
        android:id="@+id/sp_from"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        />

코드는 다음과 같습니다.

  txt__from = (TextView) rootView.findViewById(R.id.txt_prompt_from);

스피너 어댑터가 로드된 후 빈 후에 이 메서드를 호출합니다.

setPromptTextViewVisibility (); //True or fales 

public void setPromptTextViewVisibility (boolean visible )
{
    if (visible)
    {
        txt_from.setVisibility(View.VISIBLE);
    }
    else
    {
        txt_from.setVisibility(View.INVISIBLE);
    }

}

언급URL : https://stackoverflow.com/questions/867518/how-to-make-an-android-spinner-with-initial-text-select-one

반응형