Listview NumberPickerВ этом примере мы создали список, в котором, каждый элемент состоит из текста и NumberPicker. В качестве адаптера для списка был использован EfficientAdapter из примеров API Demos: list14.java.

NumberPicker был полностью перенесен из исходников андроида.

Замечание: не используйте рефлексию для доступа к NumberPicker. Лучше перенести полностью все исходники из андроид в свой проект.

1. Разметка основного окна:

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

    <ListView android:id="@+id/list"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"></ListView>
</LinearLayout>

2. Создаем разметку для элемента списка:

<?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:paddingLeft="10dp"
    android:paddingRight="5dp">
    <TextView android:id="@+id/text"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:layout_weight="1"
        android:textSize="16sp"
        android:gravity="center_vertical" />

    <ru.androidteam.listviewnumberpicker.NumberPicker
        android:id="@+id/nPicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

3. Для хранения данных списка будем использовать ArrayList<ItemData>, где ItemData:

public class ItemData {
    String text;
    int number;

    public ItemData(String text, int number) {
        this.text = text;
        this.number = number;
     }
}

4. Адаптер, как уже писал выше, основан на примере из API Demos:

    private class EfficientAdapter extends BaseAdapter {
        private LayoutInflater mInflater;
        private ArrayList<ItemData> mItems;

        public EfficientAdapter(Context context, ArrayList<ItemData> items) {
            // Cache the LayoutInflate to avoid asking for a new one each time.
            mInflater = LayoutInflater.from(context);
            mItems = items;
        }

        public int getCount() {
            return mItems.size();
        }

        public ItemData getItem(int position) {
            return mItems.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;

            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.list_item, null);

                holder = new ViewHolder();
                holder.text = (TextView) convertView.findViewById(R.id.text);
                holder.nPicker = (NumberPicker) convertView.findViewById(R.id.nPicker);
                holder.nPicker.setOnChangeListener(numberPickerOnChangedListener);
               
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            // сохраняем каждый раз позицию текущего элемента в tag view объект
            // мы будем использовать его для обновления данных при изменении NubmberPicker
            holder.nPicker.setTag(position);
           
            ItemData data = mItems.get(position);

            holder.text.setText(data.text);
            holder.nPicker.setCurrent(data.number);
           
            return convertView;
        }

        class ViewHolder {
            TextView text;
            NumberPicker nPicker;
        }
    }

5. Обработчик изменений NumberPicker.

Так как у нас все данные находятся в массиве, то при изменении числа в NumberPicker нам нужно обновлять его и у нас. Сделать это можно через NumberPicker.OnChangedListener:

NumberPicker.OnChangedListener numberPickerOnChangedListener = new NumberPicker.OnChangedListener() {
    @Override
    public void onChanged(NumberPicker picker, int oldVal, int newVal) {
        // получаем позицию из tag объекта NumberPicker
        int position = (Integer) picker.getTag();
        ItemData item = adapter.getItem(position);
        item.number = newVal;
    }
};

6. И последнее, создаем несколько тестовых данных, инициализируем адаптер и устанавливаем его в ListView:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ArrayList<ItemData> items = new ArrayList<ItemData>();
    items.add(new ItemData("Первый", 44));
    items.add(new ItemData("Второй", 4));
    items.add(new ItemData("Дерево", 26));
    items.add(new ItemData("Еще что то", 56));
    items.add(new ItemData("Стол", 6));
    items.add(new ItemData("Кружка", 33));
       
    list = (ListView) findViewById(R.id.list);
    adapter = new EfficientAdapter(getApplicationContext(), items);
    list.setAdapter(adapter);
}

Исходный код: ListView_NumberPicker.zip

Замечание: Возможно при импорте проекта в Eclipse нужно будет сделать Project -> Clean…, выбрать проект (поставить галочку слева) и нажать OK