Android Spinner привязка данных с использованием списка массивов - PullRequest
14 голосов
/ 03 июля 2011

У меня есть список массивов, подобный этому:

private ArrayList<Locations> Artist_Result = new ArrayList<Location>();

Этот класс Location имеет два свойства: id и location.

Мне нужно привязать ArrayList кпрядильщикЯ пробовал это так:

Spinner s = (Spinner) findViewById(R.id.SpinnerSpcial);
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, Artist_Result);
s.setAdapter(adapter);

Однако, он показывает шестнадцатеричное значение объекта.Поэтому я думаю, что должен установить отображение текста и значения для этого контроллера счетчика.

Ответы [ 5 ]

38 голосов
/ 03 июля 2011

ArrayAdapter пытается отобразить ваши Location -объекты в виде строк (что приводит к шестнадцатеричным значениям), вызывая Object.toString() -метод . Реализация по умолчанию возвращает:

[...] строка, состоящая из имени класса , из которого объект это экземпляр, символ знака `@ 'и неподписанный шестнадцатеричное представление хеш-кода объекта.

Чтобы ArrayAdadpter показал что-то действительно полезное в списке предметов, вы можете переопределить toString() -метод, чтобы вернуть что-то значимое:

@Override
public String toString(){
  return "Something meaningful here...";
}

Еще один способ сделать это - , расширить BaseAdapter и внедрить SpinnerAdapter для создания собственного адаптера, который знает, что элементы в вашем ArrayList являются объектами и как использовать свойства этих объектов.

[Исправлено] Пример реализации

Я немного поиграл, и мне удалось заставить что-то работать:

public class Main extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Create and display a Spinner:
        Spinner s = new Spinner(this);
        AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
        );
        this.setContentView(s, params);
        // fill the ArrayList:
        List<Guy> guys = new ArrayList<Guy>();
        guys.add(new Guy("Lukas", 18));
        guys.add(new Guy("Steve", 20));
        guys.add(new Guy("Forest", 50));
        MyAdapter adapter = new MyAdapter(guys);
        // apply the Adapter:
        s.setAdapter(adapter);
        // onClickListener:
        s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            /**
             * Called when a new item was selected (in the Spinner)
             */
            public void onItemSelected(AdapterView<?> parent,
                                       View view, int pos, long id) {
                Guy g = (Guy) parent.getItemAtPosition(pos);
                Toast.makeText(
                        getApplicationContext(),
                        g.getName()+" is "+g.getAge()+" years old.",
                        Toast.LENGTH_LONG
                ).show();
            }

            public void onNothingSelected(AdapterView parent) {
                // Do nothing.
            }
        });
    }

    /**
     * This is your own Adapter implementation which displays
     * the ArrayList of "Guy"-Objects.
     */
    private class MyAdapter extends BaseAdapter implements SpinnerAdapter {

        /**
         * The internal data (the ArrayList with the Objects).
         */
        private final List<Guy> data;

        public MyAdapter(List<Guy> data){
            this.data = data;
        }

        /**
         * Returns the Size of the ArrayList
         */
        @Override
        public int getCount() {
            return data.size();
        }

        /**
         * Returns one Element of the ArrayList
         * at the specified position.
         */
        @Override
        public Object getItem(int position) {
            return data.get(position);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }
        /**
         * Returns the View that is shown when a element was
         * selected.
         */
        @Override
        public View getView(int position, View recycle, ViewGroup parent) {
            TextView text;
            if (recycle != null){
                // Re-use the recycled view here!
                text = (TextView) recycle;
            } else {
                // No recycled view, inflate the "original" from the platform:
                text = (TextView) getLayoutInflater().inflate(
                        android.R.layout.simple_dropdown_item_1line, parent, false
                );
            }
            text.setTextColor(Color.BLACK);
            text.setText(data.get(position).name);
            return text;
        }


    }

    /**
     * A simple class which holds some information-fields
     * about some Guys.
     */
    private class Guy{
        private final String name;
        private final int age;

        public Guy(String name, int age){
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }
}

Я полностью прокомментировал код, если у вас есть какие-либо вопросы, не стесняйтесь их задавать.

8 голосов
/ 16 января 2014

простейшее решение

После изучения различных решений для SO, я обнаружил, что следующее является самым простым и чистым решением для заполнения Spinner пользовательским Objects. Вот полная реализация:

Location.java

public class Location{
    public int id;
    public String location;

    @Override
    public String toString() {
        return this.location;            // What to display in the Spinner list.
    }
}    

Рез / макет / spinner.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="14sp"
    android:textColor="#FFFFFF"
    android:spinnerMode="dialog" />

Рез / макет / your_activity_view.xml

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

    <Spinner
        android:id="@+id/location" />

</LinearLayout>

В вашей деятельности

// In this case, it's a List of Locations, but it can be a List of anything.
List<Location> locations = Location.all();                  

ArrayAdapter locationAdapter = new ArrayAdapter(this, R.layout.spinner, locations);

Spinner locationSpinner = (Spinner) findViewById(R.id.location);
locationSpinner.setAdapter(locationAdapter);



// And to get the actual Location object that was selected, you can do this.
Location location = (Location) ( (Spinner) findViewById(R.id.location) ).getSelectedItem();
6 голосов
/ 11 июля 2011

Благодаря ответу Лукаса выше (ниже?) Я смог начать с этого, но моя проблема заключалась в том, что его реализация getDropDownView сделала выпадающие элементы простым текстом - так что без отступов и без красивого зеленого цветапереключатель, который вы получаете при использовании android.R.layout.simple_spinner_dropdown_item.

. Таким же образом, как описано выше, за исключением метода getDropDownView:

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) 
{
  if (convertView == null)
  {
    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = vi.inflate(android.R.layout.simple_spinner_dropdown_item, null);
  }

  TextView textView = (TextView) convertView.findViewById(android.R.id.text1);
  textView.setText(items.get(position).getName());

  return convertView;
}
3 голосов
/ 30 августа 2013

Ну, я не буду путать с более подробной информацией.

Просто создайте ArrayList и привяжите свои значения следующим образом.

ArrayList tExp = new ArrayList();
for(int i=1;i<=50;i++)
{
    tExp.add(i);
}

Предполагая, что у вас уже есть элемент управления вращением в макете, скажем, с идентификатором spinner1.Добавьте этот код ниже.

Spinner sp = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> adp1=new ArrayAdapter<String>this,android.R.layout.simple_list_item_1,tExp);
adp1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adp1);

Весь приведенный выше код относится к вашей функции onCreate.

2 голосов
/ 11 июля 2012

Спасибо, Лукас, ты мне очень помог. Я хотел бы улучшить ваш ответ. Если вы просто хотите получить доступ к выбранному элементу позже, вы можете использовать это:

Spinner spn   = (Spinner) this.findViewById(R.id.spinner);
Guy     oGuy  = (Guy)     spn.getSelectedItem();

Так что вам не нужно использовать setOnItemSelectedListener () в вашей инициализации:)

...