Programing

초기 텍스트가 "Select One"인 Android Spinner를 만드는 방법은 무엇입니까?

lottogame 2020. 10. 4. 10:18
반응형

초기 텍스트가 "Select One"인 Android Spinner를 만드는 방법은 무엇입니까?


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

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"항목이 표시됩니다. 항목에 "하나 선택"이라는 새 항목을 추가 할 수 있지만 드롭 다운 목록에 "하나 선택"도 첫 번째 항목으로 표시됩니다.

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


다음은 Spinner보기 를 재정의하는 일반적인 솔루션입니다 . setAdapter()초기 위치를 -1로 설정하도록 재정의 하고 제공된 SpinnerAdapter프록시하여 0보다 작은 위치에 대한 프롬프트 문자열을 표시합니다.

이것은 Android 1.5 ~ 4.2에서 테스트되었지만 구매자는주의하십시오! 이 솔루션은 리플렉션에 의존하여 private 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);
        }
    }
}

당신이 할 수있는 일은 SpinnerAdapterSpinner가 아무것도 선택하지 않은 상태로 표시하도록 처음에는 '옵션 선택 ...'보기를 제공하는 것으로 장식하는 것 입니다.

다음은 Android 2.3 및 4.0 용으로 테스트 된 작업 예제입니다 (호환성 라이브러리에서 아무것도 사용하지 않으므로 잠시 괜찮습니다). 데코레이터이기 때문에 기존 코드를 쉽게 개조 할 수 있어야하며 CursorLoaders에서도 잘 작동합니다 . ( cursorAdapter물론 래핑 된 커서를 스왑 ...)

뷰 재사용을 조금 더 어렵게 만드는 Android 버그가 있습니다. (따라서 setTag또는 다른 것을 사용하여 convertView올바른지 확인해야 합니다.) Spinner는 여러보기 유형을 지원하지 않습니다 .

코드 노트 : 생성자 2 개

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

예를 들어 회색으로 표시되는 것과 같이 프롬프트처럼 보이도록 레이아웃을 정의합니다.

선택된 초기 항목이 없습니다.

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

표준 프롬프트 사용

또는 프롬프트와 동적 (프롬프트도 없었을 수 있음) :

프롬프트 및 선택된 행 없음

위 예에서의 사용법

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...]" />

NothingSelectedSpinnerAdapter.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.
    }

}

Button대신 a 사용했습니다 . a 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로 사용하고 있습니다. 이렇게하면 경고 대화 상자를 만들 때 더 나은 모양을 만드는 데 도움이됩니다.

내 Button의 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();
}

그리고 그게 다야!


이 질문에 많은 답변이 있지만 가장 간단하고 쉬운 방법을 찾았습니다.

이 솔루션 은 API 레벨과 독립적이며 모든 API 레벨에서 작동합니다 .

아이디어는 스피너의 마지막 항목을 기본 항목으로 설정하는 것입니다 ..ie

spinner.setSelection(lastIndex);//index starts from 0.so if spinner has 5 item the lastIndex is 4

마지막 색인의 항목은 "국가 선택"과 같은 스피너의 제목이어야합니다.

그리고 스피너를 채우는 동안 항목 수를 1 개 줄입니다. 즉 // Count는 1에서 총 항목까지 시작됩니다.

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

따라서 코드 흐름은 다음과 같습니다.

List<String> objects = new ArrayList<String>();
objects.add("India");
objects.add("Pakistan");
objects.add("China");
// add hint as last item
objects.add("Select Country");

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());

HintAdapter.java

public class HintAdapter extends ArrayAdapter<Objects> {

    public HintAdapter(Context theContext, List<Object> objects, int theLayoutResId) {
        super(theContext, theLayoutResId, 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;
    }
}

스피너 제목

스피너 제목

스피너 항목

스피너 항목


먼저 클래스 prompt속성에 관심이있을 수 있습니다 Spinner. 아래 그림을 참조하십시오. "Choose a Planet"은를 사용하여 XML에서 설정할 수있는 프롬프트입니다 android:prompt="".

여기에 이미지 설명 입력

Spinner두 개의 어댑터를 내부적으로 유지할 수있는 subclassing을 제안하려고했습니다 . "하나 선택"옵션이있는 어댑터 하나 와 실제 옵션이 있는 다른 실제 어댑터가있는 OnClickListener경우 선택 대화 상자가 표시되기 전에 를 사용 하여 어댑터를 전환합니다. 그러나 그 아이디어를 구현 한 후 OnClick위젯 자체에 대한 이벤트를 받을 수 없다는 결론에 도달 했습니다.

스피너를 다른 뷰로 감싸고 뷰의 클릭을 가로 챈 다음 CustomSpinner어댑터를 전환 하라고 지시 수 있지만 끔찍한 해킹처럼 보입니다.

"하나 선택"을 표시해야합니까?


이 코드는 테스트를 거쳐 Android 4.4에서 작동합니다.

여기에 이미지 설명 입력

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]을 변경 한 다음 onItemSelected에서 이름을 "One"으로 변경하면됩니다.

고급 솔루션은 아니지만 작동합니다 .D


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 위에 TextView를 배치하십시오. TextView를 숨기는 TextView에 클릭 리스너를 설정하여 Spinner를 표시하고 spinner.performClick ()을 호출합니다.


스피너에 대해 빈 선택으로 동일한 문제가 발생했으며 더 나은 해결책을 찾았습니다. 이 간단한 코드를 살펴보십시오.

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

여기서 spinneradapter는 arrayadapter에 대한 작은 사용자 정의입니다. 다음과 같이 보입니다.

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;

onCreate :

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");

이제 스피너가 비어 있고 비어있는 경우 대화 상자를 열지 않도록 코드를 작성할 수 있습니다. 아니면 뒤로 물러 설 수 있습니다. 그러나 런타임 중에 함수 또는 다른 목록으로 채 웁니다.


나는 다음과 같이 시도했다. 버튼을 잡고 클릭 이벤트를 제공하십시오. 버튼 배경을 변경하면 스피너처럼 보입니다.

전역 변수 alertdialog 및 기본값으로 선언합니다.

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

이게 내 방법이야:

List<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
list.add("[Select one]");
final int listsize = list.size() - 1;
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list) {
 @Override
public int getCount() {
    return(listsize); // Truncate the list
}
};
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);

mySpinner.setSelection(listsize); // Hidden item to appear in the spinner

목록 맨 위에 요소를 추가하는 범용 솔루션에 대한 iosched 앱을 살펴보십시오. 특히, 당신은에서 CursorAdapter, 모양 사용하는 경우 TracksAdapter.java 상단에 별도의 항목을 처리 할 수있는 목록 수를 관리 할 수있는 "setHasAllItem"방법과 관련된 코드를 제공하기 위해 그 정의를 확장합니다.

사용자 정의 어댑터를 사용하여 텍스트를 "하나 선택"또는 해당 상위 항목에 표시 할 다른 내용으로 설정할 수 있습니다.


내 main.xml에 스피너가 있으며 ID는 @+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) { }
});

클래스에서 구현할 필요가 없습니다.


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

그래서 힌트 항목을 목록의 시작 부분에 넣었습니다. 드롭 다운 목록에서 첫 번째 항목을 숨 깁니다.

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 일 때 @Override getDropDownView ()에서 아래 레이아웃을 설정하여 첫 번째 힌트 행을 숨 깁니다.

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에 "1 개 선택"이라고 말한 더미 항목을 만든 다음 저장할 때 선택 항목이 0이 아닌지 확인하는 것입니다.


이것이 버튼 스피너의 마지막 "올인"예제입니다.

에서 activity_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>

에서 MyFormActivity.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 덕분에


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

목록에 기본값을 추가 한 다음 다음을 사용하여 모든 컬렉션을 추가 할 수 있습니다. 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);

복잡성이 회복되기를 바랍니다. 즐거운 코딩 되세요!


를 확장 할 때 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);

이제 spinner가 객체를 이해할 수 없기 때문에 spinner에 문자열을 제공해야합니다. 따라서 다음과 같은 문자열 항목으로 새 배열 목록을 만듭니다.->

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

이제 itemStringArrayList두 개의 문자열 항목 이있는 배열 목록이 있습니다. 그리고 첫 번째 항목으로 "항목 선택"텍스트를 표시해야합니다. 그래서 우리는 새로운 문자열을 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 메서드를 재정 의하여 설정할 수 있습니다. 따라서이 방법으로 예상되는 스피너를 얻을 수 있습니다.


세 가지 선택 사항 만 있으면 RadioButtons와 함께 RadioGroup을 사용하고 처음에는 모두 선택 취소 할 수 있습니다.


이전에 제출 한 답변 중 어느 것도이 문제를 해결하려는 방식으로 작동하지 않았습니다. 나에게 이상적인 솔루션은 스피너가 처음 표시 될 때 "하나 선택"(또는 초기 텍스트)을 제공하는 것입니다. 사용자가 스피너를 탭할 때 초기 텍스트가 표시되는 드롭 다운의 일부가되어서는 안됩니다.

내 특정 상황을 더욱 복잡하게 만들기 위해 내 스피너 데이터가 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);
    }
}
}

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

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

활동은 다음과 같습니다.

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

    }

}

참고 : 예, 이것이 적용된 테마에 따라 다르며 Theme.Holo를 사용하는 경우 모양이 약간 다를 수 있음을 알고 있습니다. 그러나 Theme.Black과 같은 레거시 테마 중 하나를 사용하는 경우 사용하는 것이 좋습니다.


이 문제에 직면하는 경우 항목은 데이터베이스 커서에서 채워집니다이 때 ,

SO 답변 에서 찾은 가장 간단한 솔루션 :

커서 어댑터 쿼리에서 UNION을 사용 하고 실제로 DB에 추가하지 않고 id = -1 인 추가 항목을 쿼리 결과에 추가합니다.

다음과 같이 :

db.rawQuery ( "SELECT iWorkerId as _id, nvLastName as name FROM Worker w UNION SELECT -1 as _id, ''as name", null);

선택한 항목이 -1이면 기본값입니다. 그렇지 않으면 테이블의 레코드입니다.


진부한 해결책처럼 보이지만 일반적으로 스피너 앞에 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를 숨 깁니다. 분명히 TextView의 배경색은 Spinner와 동일해야합니다. Android 4.0에서 작동합니다. 이전 버전을 모릅니다.

예. Spinner가 처음에 setOnItemSelectedListener를 호출하기 때문에 textview를 숨기는 것이 약간 까다로울 수 있지만 다음과 같이 할 수 있습니다.

    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) {
        }

    });

나를 위해 그것은 이와 같이 작동했습니다. 전체가 아닌 일부 옵션의 텍스트 만 변경하는 개선 사항이 있습니다.

먼저 스피너의 이름을 가져 와서 사용자 정의보기로 arrayadapter를 만들지 만 지금은 중요하지 않습니다. 키는 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);
    }

여기에 간단한 것이 있습니다

    private boolean isFirst = true;
private void setAdapter() {
    final ArrayList<String> spinnerArray = new ArrayList<String>();     
    spinnerArray.add("Select your option");
    spinnerArray.add("Option 1");
    spinnerArray.add("Option 2");
    spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            TextView tv = (TextView)selectedItemView;
            String res = tv.getText().toString().trim();
            if (res.equals("Option 1")) {
            //do Something
        } else if (res.equals("Option 2")) {
            //do Something else
        }
        }

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

    });

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.my_spinner_style,spinnerArray) {
         public View getView(int position, View convertView, ViewGroup parent) {
             View v = super.getView(position, convertView, parent);
             int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, getResources().getDisplayMetrics());                  
             ((TextView) v).setTypeface(tf2);
             ((TextView) v).getLayoutParams().height = height;
             ((TextView) v).setGravity(Gravity.CENTER);
             ((TextView) v).setTextSize(TypedValue.COMPLEX_UNIT_SP, 19);
             ((TextView) v).setTextColor(Color.WHITE);
             return v;
         }

         public View getDropDownView(int position, View convertView,
                 ViewGroup parent) {
             if (isFirst) {
                 isFirst = false;
                 spinnerArray.remove(0);
             }
             View v = super.getDropDownView(position, convertView, parent);                  
             ((TextView) v).setTextColor(Color.argb(255, 70, 70, 70));
             ((TextView) v).setTypeface(tf2);
             ((TextView) v).setGravity(Gravity.CENTER);
             return v;
         }
     };
     spin.setAdapter(adapter);
}

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

반응형