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

안드로이드 프레임 워크에 익숙하지 않은 사람들을 위해 https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView 에서 자세히 설명합니다 .


2
죄송합니다, MyClass item = items.get (position)은 오류를 해결하고 변수를 불일치시킵니다.
Sumit M Asok

1
예를 들어 누군가가 adapter.clear () 또는 adapter.add (...)를 사용하여 내부 항목 목록을 변경하는 경우와 같이 쉽게 오류가 발생할 수 있으므로 위 코드에서 items 필드를 제거했습니다.
prostynick

1
textViewResourceId위에서 사용하지 않는다고 가정하면 정확 합니까?
gerrytan

8
viewHolder는 어디에서 왔습니까?
Gerry

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
가장 간단한 해결책이지만 이것은 (IMHO) 좋은 생각이 아닙니다. 세 가지 이유 : 현지화가 필요한 경우 리팩터링해야합니다. 이것은 하나의 어댑터가있는 경우에만 작동하며에 대한 두 개의 다른 어댑터 MyClass가있는 경우 리팩터링해야합니다. 마지막으로 프레젠테이션 논리를 모델에 연결하는 것은 일반적으로 좋지 않습니다. 모델은 모델이 사용자에게 어떻게 표시되는지 인식하지 않아야합니다.
fernandohur

2
유형의 모델 클래스가 있도록 @fernandohur 우려의 일부 주소로 간단하게 ... ArrayAdapter와의 전용 뷰 클래스를 만들 수 있습니다 MyClass라는 전용 클래스를 추가 할 필요 MyClassView하여 기본 모델을 래핑 (및 제공 toString( )구현
월마트

이 답변은 2011 년부터 왔으며 @fernandohur에 동의합니다.이를 처리하는 더 좋은 방법이 있습니다.

많은 사람들이 각 클래스가 객체의 이름을 나타내는 것보다 기여를하기 때문에 이것이 좋은 대답이라고 생각합니다.
존 프레디 트루 히요 오르테가

이것이 정답입니다. 인쇄 된 이름을 바인딩하기 위해 어댑터를 재정의하는 것은 잘못된 코딩입니다.
L.Grillo

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로 요점을 만들었습니다.

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


1
코드를 많이 좋아했지만 android.content.res.Resources $ NotFoundException : Resource ID # 0x0과 충돌하는 이유를 알아내는 데 시간이 걸렸습니다. super (.., 0, ..)의 일반 어댑터 ​​호출에서 0은 실제로 존재하지 않는 레이아웃 자원이므로 다른 것으로 변경해야합니다. 또한 요점은 404
Ev0oD

결국 나는 많은 변화를 겪었습니다. 드롭 다운 메뉴의 레이아웃이 표시된 항목의 레이아웃과 다릅니다. drawText는 클릭 한 항목이 아닌 스피너 헤더에서만 호출되었습니다.
Ev0oD

일반 어댑터로 유효해야합니다. 문제를 해결할 수 있습니까?
cesards

그래, 나는 그것을 작동시켰다. 나는 당신이 내가 원하는 것과 조금 다른 것에 대한 해결책을 제공한다는 것을 깨달았지만, 당신의 코드를 시작점으로 사용하고 내가 원하는 것을 나에게 해준 방식으로 수정할 수있었습니다. 이 코드 조각에 감사드립니다.
Ev0oD

기본적으로 제공해야합니다.
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.