SimpleAdapter 사용자 정의

Simple Adapter, 이름과 같이 간단한 어댑터는 간단하지만, 정적 데이터의 귀속 같은 간단한 응용을 위해 설계되었을 뿐, 예를 들어 모든 ListItem에 단추를 추가하고 응답 이벤트를 추가하는 등 사용자 정의 공간이 있습니다.먼저 SDK doc을 직접 번역하여 Simple Adapter의 정의를 살펴보십시오.
            ,          XML         。      Map   List(  ArrayList)     。 ArrayList        List    。Maps        。       XML           ,  Map               。            ,  ,     SimpleAdapter.ViewBinder,       ViewBinder setViewValue(android.view.View, Object, String)    。  setViewValue     true,         ,              。      false,            :

4
  • View가 Checkable(예: CheckBox)을 구현한 경우 바인딩 값은 부울 유형입니다
  • TextView.원하는 바인딩 값은 setViewText(TextView, String)를 호출하여 바인딩하는 문자열 유형입니다

  • 4
  • ImageView, 기대 귀속값은 자원 id 또는 문자열로 setViewImage(ImageView, int) 또는 setViewImage(ImageView, String)를 호출하여 데이터를 귀속시킨다
  •                    IllegalStateException。

    먼저 구조 함수를 살펴보자.
      
    public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

    매개 변수
    context SimpleAdapter와 연관된 View의 운영 환경
    데이터는 하나의 맵으로 구성된 List입니다.목록의 항목마다 목록의 한 줄에 대응하고, 맵마다from 매개 변수에 지정된 키가 모두 포함되어야 한다
    목록 항목을 정의하는 레이아웃 파일의 자원 ID입니다.레이아웃 파일에는 to에 정의된 ID가 적어도 포함되어야 합니다.
    Map 맵에 추가할 키 이름
    to는 연결된 데이터의 보기 ID를 from 매개 변수와 대응합니다. 이것들은 모두 TextView일 것입니다
    예를 들면 다음과 같습니다.
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ListView lv = (ListView) findViewById(R.id.listView1);
    String[] from = { "Text", "Button" };
    int[] to = { R.id.text, R.id.button };
    List<Map<String, ?>> list = new ArrayList<Map<String, ?>>();
    for (int i = 0; i < 10; i++) {
    Map<String, String> m = new HashMap<String, String>();
    m.put("Text", "Text" + i);
    m.put("Button", "Button" + i);
    list.add(m);
    }
    SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.listitem, from, to);
    lv.setAdapter(adapter);
    }

    listitem.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="horizontal" >

    <TextView android:layout_width="wrap_content" android:id="@+id/text" android:layout_height="wrap_content" android:layout_weight="1" />

    <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" />

    </LinearLayout>

    Simple Adapter의 구조 함수에 귀속할 데이터를 지정합니다:list,list는 Map으로 구성된 Array List입니다.Map의 역할은 바로 뒤에 있는from과 연결되며 to 매개 변수가 정의한 데이터는 어떻게 귀속되는지입니다. 위의 예에서
    String[] from = { "Text", "Button" };
    int[] to = { R.id.text, R.id.button };

    for 순환에서 모든 맵이put에 두 개의 키 값이 들어왔다. 키 이름은from에서 정의한 것과 일일이 대응한다. 이것은ListView의 모든 항목에 대해 to 파라미터에 정의된 자원 ID를 순서대로 찾고 이 자원 ID가 to 파라미터 수조에 있는 위치에 따라from 참수에 대응하는 위치의 값을 찾아 이 값을 키로 한다.list의 해당 항목 (Map) 에서 이 값을 키로 꺼내서 이 키에 대응하는 값을 자원 ID에 대응하는 보기에 연결합니다.
    위의 예에서 모든ListItem은 하나의 TextView와 하나의 Button을 포함하지만 프로그램이 실행된 후에 단추를 클릭할 수 있지만 ListItem은 클릭할 수 없고 모든Button과 관련된 응답 이벤트가 없다. ListItem이 클릭할 수 없는 것은 단추가ListItem의 초점을 차지하여listitem에 있기 때문이다.xml일 뿐입니다. 파일에 LinearLayout에 속성을 추가하면 문제를 해결할 수 있습니다.
        android:descendantFocusability="blocksDescendants"

    다음 질문은 바로 Button의 응답 이벤트입니다.
    Simple Adaper의 원본 코드를 내려가면 데이터의 귀속은bindView라는 함수를 통과할 수 있음을 발견할 수 있습니다
       private void bindView(int position, View view) {
    final Map dataSet = mData.get(position);
    if (dataSet == null) {
    return;
    }

    final ViewBinder binder = mViewBinder;
    final String[] from = mFrom;
    final int[] to = mTo;
    final int count = to.length;

    for (int i = 0; i < count; i++) {
    final View v = view.findViewById(to[i]);
    if (v != null) {
    final Object data = http://www.cnblogs.com/angeldevil/archive/2012/04/05/dataSet.get(from[i]);
    String text = data =http://www.cnblogs.com/angeldevil/archive/2012/04/05/= null ? "" : data.toString();
    if (text == null) {
    text = "";
    }

    boolean bound = false;
    if (binder != null) {
    bound = binder.setViewValue(v, data, text);
    }

    if (!bound) {
    if (v instanceof Checkable) {
    if (data instanceof Boolean) {
    ((Checkable) v).setChecked((Boolean) data);
    } else if (v instanceof TextView) {
    // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text);
    } else {
    throw new IllegalStateException(v.getClass().getName() +
    " should be bound to a Boolean, not a " +
    (data =http://www.cnblogs.com/angeldevil/archive/2012/04/05/= null ? "<unknown type>" : data.getClass()));
    }
    } else if (v instanceof TextView) {
    // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text);
    } else if (v instanceof ImageView) {
    if (data instanceof Integer) {
    setViewImage((ImageView) v, (Integer) data);
    } else {
    setViewImage((ImageView) v, text);
    }
    } else {
    throw new IllegalStateException(v.getClass().getName() + " is not a " +
    " view that can be bounds by this SimpleAdapter");
    }
    }
    }
    }
    }

    그 절차는 대체로, 먼저 SimpleAdapter가 SimpleAdapter를 지정했는지 확인하는 것이다.ViewBinder, 지정하면 setViewValue 방법을 호출합니다. SimpleAdapter.ViewBinder는 하나의 인터페이스이고 이 방법밖에 없다. 만약에 ViewBinder가true로 돌아오면 우리가 이View에 대한 데이터 연결을 완성했음을 표시하고 시스템의 기본적인 실현을 호출하지 않는다. 물론 우리는 ViewBinder를 설정하여 일부 기능을 추가한 후false로 돌아가서 시스템에 데이터를 연결할 수 있다. 예를 들어 단추에 응답 이벤트를 추가하는 등이다.단추의 문자는 기본적으로 귀속됩니다.bindView의 실현을 보면 시작할 때 말한 귀속 순서를 알 수 있습니다: Checkable,TextView,ImageView.
    ListItem에 대한 사용자 정의는SimpleAdapter에 ViewBinder를 설정함으로써 이루어집니다
            SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {

    @Override
    public boolean setViewValue(View view, Object data, String textRepresentation) {
    if (view instanceof Button) {
    final View button = view;
    // button.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher)); view.setOnClickListener(new OnClickListener() {
    LinearLayout listItem = (LinearLayout) button.getParent();
    TextView tv = (TextView) listItem.findViewById(R.id.text);

    @Override
    public void onClick(View v) {
    Toast.makeText(AdapterDemoActivity.this, tv.getText(), Toast.LENGTH_SHORT).show();
    }
    });
    return false;
    }
    return false;
    }
    };
    adapter.setViewBinder(binder);

    시스템은 모든view에binder의setViewValue를 호출합니다. (이 예는 R.id.text와 R.id.button, TextView와 Button) 우리는 이view가 Button인지 먼저 검사합니다. 만약 그렇다면 클릭 이벤트와 관련됩니다. getParent () 함수를 통해parentView를 가져와서view의 형제view를 찾을 수 있습니다.예를 들어 이 예에서 실현된 것은 Button을 누르면 이 Button이 있는ListItem의 TextView에 있는 텍스트를 출력하는 것이다.
    setViewValue에서 우리의 실현을 완전히 사용자 정의할 수 있습니다. 예를 들어 Button 뒤에 TextView를 추가하면 물론 어떤 View를 추가할 수 있지만, 이렇게 하는 것은 아무런 의미가 없습니다. 만약 당신이 이렇게 해야 할 때SimpleAdater를 사용하지 않고 BaseAdapter를 사용해야 합니다.
            SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {

    @Override
    public boolean setViewValue(View view, Object data, String textRepresentation) {
    if (view instanceof Button) {
    final View button = view;
    LinearLayout listItem = (LinearLayout) button.getParent();
    TextView textView = new TextView(AdapterDemoActivity.this);
    textView.setText("AA");
    listItem.addView(textView,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    return false;
    }
    return false;
    }
    };
    adapter.setViewBinder(binder);

    좋은 웹페이지 즐겨찾기