ArrayAdapter <myClass>の使用方法


129
ArrayList<MyClass> myList = new ArrayList<MyClass>();

ListView listView = (ListView) findViewById(R.id.list);

ArrayAdapter<MyClass> adapter = new ArrayAdapter<MyClass>(this, R.layout.row,
    to, myList.);
listView.setAdapter(adapter);

クラス:MyClass

class MyClass {
    public String reason;
    public long long_val;
}

レイアウトでrow.xmlを作成しましたが、ArrayAdapterを使用してListViewにreasonとlong_valの両方を表示する方法がわかりません。

回答:


155

クラスにカスタムアダプターを実装します。

public class MyClassAdapter extends ArrayAdapter<MyClass> {

    private static class ViewHolder {
        private TextView itemView;
    }

    public MyClassAdapter(Context context, int textViewResourceId, ArrayList<MyClass> items) {
        super(context, textViewResourceId, items);
    }

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

        if (convertView == null) {
            convertView = LayoutInflater.from(this.getContext())
            .inflate(R.layout.listview_association, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.itemView = (TextView) convertView.findViewById(R.id.ItemView);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        MyClass item = getItem(position);
        if (item!= null) {
            // My layout has only one TextView
                // do whatever you want with your string and long
            viewHolder.itemView.setText(String.format("%s %d", item.reason, item.long_val));
        }

        return convertView;
    }
}

Androidフレームワークにあまり詳しくない方は、https//github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListViewで詳しく説明しています


2
申し訳ありませんが、MyClass item = items.get(position)はエラーを解決し、私が変数を不一致にします。
Sumit M Asok 2010

1
上記のコードからitemsフィールドを削除しました。たとえば、
adapter.clear

1
textViewResourceId上記で使用されていないと想定しても正しいですか?
gerrytan 2013

8
viewHolderはどこから来たのですか?
ジェリー

2
R.layout.listview_associationとは何ですか?それはあなたのカスタムレイアウトですか?android.R.layout.simple_list_item_1に置き換えることはできますか?
Donato

76

http://developer.android.com/reference/android/widget/ArrayAdapter.htmltoString()に従って、メソッドをMyClassに追加するだけです。

ただし、TextViewは参照されますが、配列内の各オブジェクトのtoString()で埋められます。カスタムオブジェクトのリストまたは配列を追加できます。オブジェクトのtoString()メソッドをオーバーライドして、リスト内のアイテムに表示されるテキストを決定します。

class MyClass {

 @Override
 public String toString() {
  return "Hello, world.";
 }
}

20
最も簡単な解決策ですが、これは(私見)あまり良い考えではありません。3つの理由:ローカリゼーションが必要な場合は、リファクタリングする必要があります。これは、1つのアダプターがある場合にのみ機能し、2つの異なるアダプターがMyClassある場合は、リファクタリングする必要があります。最後に、プレゼンテーションロジックをモデルに関連付けることは、一般的に悪い考えです。モデルは、ユーザーにどのように提示されるかを認識してはなりません。
fernandohur 2014年

2
@fernandohurの懸念のいくつかに対処するには、単にArrayAdapterの専用ビュークラスを作成できます...したがって、タイプのモデルクラスでは、基礎となるモデルをラップするとMyClass呼ばれる専用クラスを追加する必要がありますMyClassView(そしてtoString( )実装を提供します
wal

この回答は2011年からのものであり、@ fernandohurに同意します-これを処理するためのより良い方法があります。

多くの場合、各クラスにはオブジェクトの名前を表すよりも属性があるので、これは良い答えだと思います。
Jhon Fredy Trujillo Ortega

これは受け入れられる答えになるはずです。印刷された名前をバインドするためだけにアダプターをオーバーライドすることは、不適切なコーディングです。
L.Grillo 2018

22

これが最善のアプローチだと思います。汎用のArrayAdapterクラスを使用して独自のオブジェクトアダプターを拡張する方法は、次のように簡単です。

public abstract class GenericArrayAdapter<T> extends ArrayAdapter<T> {

  // Vars
  private LayoutInflater mInflater;

  public GenericArrayAdapter(Context context, ArrayList<T> objects) {
    super(context, 0, objects);
    init(context);
  }

  // Headers
  public abstract void drawText(TextView textView, T object);

  private void init(Context context) {
    this.mInflater = LayoutInflater.from(context);
  }

  @Override public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder vh;
    if (convertView == null) {
      convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
      vh = new ViewHolder(convertView);
      convertView.setTag(vh);
    } else {
      vh = (ViewHolder) convertView.getTag();
    }

    drawText(vh.textView, getItem(position));

    return convertView;
  }

  static class ViewHolder {

    TextView textView;

    private ViewHolder(View rootView) {
      textView = (TextView) rootView.findViewById(android.R.id.text1);
    }
  }
}

そしてここにあなたのアダプター(例):

public class SizeArrayAdapter extends GenericArrayAdapter<Size> {

  public SizeArrayAdapter(Context context, ArrayList<Size> objects) {
    super(context, objects);
  }

  @Override public void drawText(TextView textView, Size object) {
    textView.setText(object.getName());
  }

}

そして最後に、それを初期化する方法:

ArrayList<Size> sizes = getArguments().getParcelableArrayList(Constants.ARG_PRODUCT_SIZES);
SizeArrayAdapter sizeArrayAdapter = new SizeArrayAdapter(getActivity(), sizes);
listView.setAdapter(sizeArrayAdapter);

TextViewレイアウトの重力カスタマイズ可能なArrayAdapterを使用してGistを作成しました。

https://gist.github.com/m3n0R/8822803


1
私はあなたのコードが本当に好きだったが、なぜそれがandroid.content.res.Resources $ NotFoundException:Resource ID#0x0でクラッシュしていたのかを理解するのにしばらく時間がかかりました。super(..、0、..)のジェネリックアダプターコールで、0は実際には存在しないレイアウトリソースであるため、別のものに変更する必要があります。また、要点は404
Ev0oDです。

最後に、私は多くのことを変更することになった-ドロップダウンメニューのレイアウトが示された項目のレイアウトとは異なった、のDrawTextだけ..スピナーヘッダ上ではなく、クリックした上で、その項目に呼ばれていた
Ev0oD

これは、汎用アダプターとして有効でなければなりません。問題を解決できますか?
2015年

ええ、私はそれを機能させました。あなたが私が望んでいたものとは少し違う何かのためのソリューションを提供していることに気づきましたが、私はあなたのコードを出発点として使用し、それが私のためにしたい方法で修正を加えることができました。このコードの一部をありがとう。
Ev0oD 2015年

これはデフォルトで提供されます。
Goddard

6

ArrayAdapterをサブクラス化し、メソッドgetView ()をオーバーライドして、表示するコンテンツを含む独自のビューを返します。


5

母クラスの拡張に煩わされたくない場合に、ArrayAdapterを使用する方法の簡単でわかりにくい例を次に示します。

class MyClass extends Activity {
    private ArrayAdapter<String> mAdapter = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mAdapter = new ArrayAdapter<String>(getApplicationContext(),
            android.R.layout.simple_dropdown_item_1line, android.R.id.text1);

        final ListView list = (ListView) findViewById(R.id.list);
        list.setAdapter(mAdapter);

        //Add Some Items in your list:
        for (int i = 1; i <= 10; i++) {
            mAdapter.add("Item " + i);
        }

        // And if you want selection feedback:
        list.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //Do whatever you want with the selected item
                Log.d(TAG, mAdapter.getItem(position) + " has been selected!");
            }
        });
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.