2012-01-24 1 views
1

Я использовал это некоторое время, и я не уверен, нашел ли я эту технику в примере или просто попробовал кучу вещей, пока это, наконец, не сработало. Мой вопрос заключается в том, как делает эта строка кода,Почему создается экземпляр нового пользовательского обработчика в пользовательском ArrayAdapter?

new ObjectInterfaceHandler(position, o, v); 

на самом деле сделать это, где эта точка зрения Прослушивания для спины вызова от ListReadyObject.

package com.scs.stuff; 

import java.util.ArrayList; 

import android.content.Context; 
import android.os.Handler; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class ListReadyObjectAdapter extends ArrayAdapter<ListReadyObject> { 

    public ListReadyObjectAdapter(Context context, int textViewResourceId, 
      ArrayList<ListReadyObject> lro) { 
     super(context, textViewResourceId, lro); 

    } 

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

     LinearLayout v; 
     v = new LinearLayout(getContext()); 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     vi.inflate(R.layout.list_row, v, true); 

     ListReadyObject o = getItem(position); 

     if (o != null) { 

      TextView tt = (TextView) v.findViewById(R.id.toptext); 
      TextView bt = (TextView) v.findViewById(R.id.bottomtext); 

      if (tt != null) { 
       tt.setText(o.getDisplayText()); 
      } 

      if (o.isLiving()) { 
       if (bt != null) { 
        // set default text to be shown 
        // until the status thread completes 
        bt.setText("---"); 
       } 
       // start a background thread to update Display State 
       o.updateStatus(); 
       // why does this work 
       new ObjectInterfaceHandler(position, o, v); 

      } else { 
       if (bt != null) { 
        bt.setText("Not Living"); 
       } 
      } 
     } 
     return v; 
    } 

    // provides a way for the Object to call back to the list without 
    // blocking the UI 
    public class ObjectInterfaceHandler implements ListReadyObjectStatusListener { 
     int position; 
     ListReadyObject o; 
     View v; 

     private final Handler handler = new Handler(); 

     public ObjectInterfaceHandler(int position, ListReadyObject o, View v) { 
      this.position = position; 
      this.o = o; 
      this.v = v; 
      // register to observe an update from the Object 
      o.registerObserver(this); 
     } 
     @Override 
     public void objectInterfaceUpdate() { 
      // called from the Object's observer pattern 
      handler.post(updateBottomText); 
     } 
     // runnable to put the update on the UI Thread 
     private Runnable updateBottomText = new Runnable() { 
      @Override 
      public void run() { 
       TextView bt = (TextView) v.findViewById(R.id.bottomtext); 
       if (bt != null) { 
        bt.setText(o.getStatusText()); 
       } 
      } 
     }; 
    } 
} 

ListReadyObject интерфейс:

package com.scs.stuff; 

public interface ListReadyObject { 

    public void registerObserver(ListReadyObjectStatusListener o); 

    public void removeObserver(ListReadyObjectStatusListener o); 

    public void notifyObservers(); 

    public String getDisplayText(); 

    public String getStatusText(); 

    public boolean isLiving(); 

    public void updateStatus(); 

} 

ListReadyObjectStatusListener интерфейс:

package com.scs.stuff; 

public interface ListReadyObjectStatusListener { 

    public void objectInterfaceUpdate(); 

} 

ответ

1

Это не (непосредственно) делают вид прослушивания обратных вызовов.

Здесь вы видите ListReadyObject получить передается в конструктор ObjectInterfaceHandler:

ListReadyObject o = getItem(position); 
... 
new ObjectInterfaceHandler(position, o, v); 

В этом конструкторе вы найдете это:

o.registerObserver(this); 

Так ObjectInterfaceHandler на самом деле один слушает ListReadyObject. Затем, когда он получает уведомление о обновлении:

@Override 
public void objectInterfaceUpdate() { 
    // called from the Object's observer pattern 
    handler.post(updateBottomText); 
} 

Он отправляет сообщение на свой собственный обработчик для вызова Runnable который обновляет вид:

private Runnable updateBottomText = new Runnable() { 
    @Override 
    public void run() { 
     TextView bt = (TextView) v.findViewById(R.id.bottomtext); 
     if (bt != null) { 
      bt.setText(o.getStatusText()); 
     } 
    } 
}; 

Это очень общий шаблон называется Observer Pattern.

+0

Так как у меня нет ссылки на ObjectInterfaceHandler, где в памяти он живет? Я создаю экземпляр для каждого представления в ListView. – tunneling

+0

Как и любой другой объект, он живет в куче. Это не сбор мусора, потому что реализация «ListReadyObject» сохраняет ссылку на нее, когда она регистрирует ее как наблюдателя (если она не разбита). – kabuko

0

Я новичок в Android, и я получаю только половину кода, но единственное, о чем я могу думать, это то, что вызывается что-то в конструкторе ObjectInterfaceHandler, которое имеет значение для продолжения кода , Так как вы только создать экземпляр (вы не держите каких-либо ссылок на него), единственное различие может быть код конструктора:

o.registerObserver(this); 

Параметр ListReadyObject принимает ссылку на ObjectInterfaceHandler здесь.