public void detach() {
      adapter.setDataNeededListener(null);
      adapter.setOnErrorListener(null);
      loader.setOnErrorListener(null);

      loader = null;
      adapter = null;
    }
  private void onListItemClick(ListView listView, View v, int position) {
    @SuppressWarnings("unchecked")
    T graphObject = (T) listView.getItemAtPosition(position);
    String id = adapter.getIdOfGraphObject(graphObject);
    selectionStrategy.toggleSelection(id);
    adapter.notifyDataSetChanged();

    if (onSelectionChangedListener != null) {
      onSelectionChangedListener.onSelectionChanged(PickerFragment.this);
    }
  }
 private void reprioritizeDownloads() {
   int lastVisibleItem = listView.getLastVisiblePosition();
   if (lastVisibleItem >= 0) {
     int firstVisibleItem = listView.getFirstVisiblePosition();
     adapter.prioritizeViewRange(
         firstVisibleItem, lastVisibleItem, PROFILE_PICTURE_PREFETCH_BUFFER);
   }
 }
  private void clearResults() {
    if (adapter != null) {
      boolean wasSelection = !selectionStrategy.isEmpty();
      boolean wasData = !adapter.isEmpty();

      loadingStrategy.clearResults();
      selectionStrategy.clear();
      adapter.notifyDataSetChanged();

      // Tell anyone who cares the data and selection has changed, if they have.
      if (wasData && onDataChangedListener != null) {
        onDataChangedListener.onDataChanged(PickerFragment.this);
      }
      if (wasSelection && onSelectionChangedListener != null) {
        onSelectionChangedListener.onSelectionChanged(PickerFragment.this);
      }
    }
  }
 void setSelectionStrategy(SelectionStrategy selectionStrategy) {
   if (selectionStrategy != this.selectionStrategy) {
     this.selectionStrategy = selectionStrategy;
     if (adapter != null) {
       // Adapter should cause a re-render.
       adapter.notifyDataSetChanged();
     }
   }
 }
  void updateAdapter(SimpleGraphObjectCursor<T> data) {
    if (adapter != null) {
      // As we fetch additional results and add them to the table, we do not
      // want the items displayed jumping around seemingly at random, frustrating the user's
      // attempts at scrolling, etc. Since results may be added anywhere in
      // the table, we choose to try to keep the first visible row in a fixed
      // position (from the user's perspective). We try to keep it positioned at
      // the same offset from the top of the screen so adding new items seems
      // smoother, as opposed to having it "snap" to a multiple of row height

      // We use the second row, to give context above and below it and avoid
      // cases where the first row is only barely visible, thus providing little context.
      // The exception is where the very first row is visible, in which case we use that.
      View view = listView.getChildAt(1);
      int anchorPosition = listView.getFirstVisiblePosition();
      if (anchorPosition > 0) {
        anchorPosition++;
      }
      GraphObjectAdapter.SectionAndItem<T> anchorItem = adapter.getSectionAndItem(anchorPosition);
      final int top =
          (view != null
                  && anchorItem.getType() != GraphObjectAdapter.SectionAndItem.Type.ACTIVITY_CIRCLE)
              ? view.getTop()
              : 0;

      // Now actually add the results.
      boolean dataChanged = adapter.changeCursor(data);

      if (view != null && anchorItem != null) {
        // Put the item back in the same spot it was.
        final int newPositionOfItem =
            adapter.getPosition(anchorItem.sectionKey, anchorItem.graphObject);
        if (newPositionOfItem != -1) {
          listView.setSelectionFromTop(newPositionOfItem, top);
        }
      }

      if (dataChanged && onDataChangedListener != null) {
        onDataChangedListener.onDataChanged(PickerFragment.this);
      }
    }
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    adapter = createAdapter();
    adapter.setFilter(
        new GraphObjectAdapter.Filter<T>() {
          @Override
          public boolean includeItem(T graphObject) {
            return filterIncludesItem(graphObject);
          }
        });
  }
 protected void onLoadReset(GraphObjectPagingLoader<T> loader) {
   adapter.changeCursor(null);
 }
 public boolean isDataPresentOrLoading() {
   return !adapter.isEmpty() || loader.isLoading();
 }
 void layoutActivityCircle() {
   // If we've got no data, make the activity circle full-opacity. Otherwise we'll dim it to avoid
   //  cluttering the UI.
   float alpha = (!adapter.isEmpty()) ? .25f : 1.0f;
   setAlpha(activityCircle, alpha);
 }
 List<T> getSelectedGraphObjects() {
   return adapter.getGraphObjectsById(selectionStrategy.getSelectedIds());
 }