0

我有一个在旋转横幅上显示图像的 3DCarouselAdapter 代码。如何在此代码中添加意图方法以单击图像并转到活动页面?

public abstract class  CarouselAdapter <T extends Adapter> extends ViewGroup {
  public static final int ITEM_VIEW_TYPE_IGNORE = -1;
  public static final int ITEM_VIEW_TYPE_HEADER_OR_FOOTER = -2;

  /**
   * The position of the first child displayed
   */
  @ViewDebug.ExportedProperty
  int mFirstPosition = 0;
  int mSpecificTop;

  /**
   * Position from which to start looking for mSyncRowId
   */
  int mSyncPosition;
  long mSyncRowId = INVALID_ROW_ID;
  long mSyncHeight;
  boolean mNeedSync = false;
  int mSyncMode;

  /**
   * Our height after the last layout
   */
  private int mLayoutHeight;

  /**
   * Sync based on the selected child
   */
  static final int SYNC_SELECTED_POSITION = 0;

  /**
   * Sync based on the first child displayed
   */
  static final int SYNC_FIRST_POSITION = 1;

  /**
   * Maximum amount of time to spend in {@link #findSyncPosition()}
   */
  static final int SYNC_MAX_DURATION_MILLIS = 100;

  /**
   * Indicates that this view is currently being laid out.
   */
  boolean mInLayout = false;

  /**
   * The listener that receives notifications when an item is selected.
   */
  OnItemSelectedListener mOnItemSelectedListener;

  /**
   * The listener that receives notifications when an item is clicked.
   */
  OnItemClickListener mOnItemClickListener;

  /**
   * The listener that receives notifications when an item is long clicked.
   */
  OnItemLongClickListener mOnItemLongClickListener;

  /**
   * True if the data has changed since the last layout
   */
  boolean mDataChanged;

  /**
   * The position within the adapter's data set of the item to select
   * during the next layout.
   */
  @ViewDebug.ExportedProperty    
  int mNextSelectedPosition = INVALID_POSITION;

  /**
   * The item id of the item to select during the next layout.
   */
  long mNextSelectedRowId = INVALID_ROW_ID;

  /**
   * The position within the adapter's data set of the currently selected item.
   */
  @ViewDebug.ExportedProperty    
  int mSelectedPosition = INVALID_POSITION;

  /**
   * The item id of the currently selected item.
   */
  long mSelectedRowId = INVALID_ROW_ID;

  /**
   * View to show if there are no items to show.
   */
  private View mEmptyView;

  /**
   * The number of items in the current adapter.
   */
  @ViewDebug.ExportedProperty
  int mItemCount;

  /**
   * The number of items in the adapter before a data changed event occured.
   */
  int mOldItemCount;

  /**
   * Represents an invalid position. All valid positions are in the range 0 to 1  less     than the
   * number of items in the current adapter.
   */
  public static final int INVALID_POSITION = -1;

  /**
   * Represents an empty or invalid row id
   */
  public static final long INVALID_ROW_ID = Long.MIN_VALUE;

  /**
   * The last selected position we used when notifying
   */
  int mOldSelectedPosition = INVALID_POSITION;

  /**
   * The id of the last selected position we used when notifying
   */
  long mOldSelectedRowId = INVALID_ROW_ID;

  private boolean mDesiredFocusableState;
  private boolean mDesiredFocusableInTouchModeState;

  private SelectionNotifier mSelectionNotifier;
  /**
   * When set to true, calls to requestLayout() will not propagate up the parent hierarchy.
   * This is used to layout the children during a layout pass.
   */
  boolean mBlockLayoutRequests = false;


  public CarouselAdapter(Context context) {
      super(context);
  }

  public CarouselAdapter(Context context, AttributeSet attrs) {
      super(context, attrs);
  }

  public CarouselAdapter(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
  }

  /**
   * Interface definition for a callback to be invoked when an item in this
   * CarouselAdapter has been clicked.
   */
  public interface OnItemClickListener {

      /**
       * Callback method to be invoked when an item in this CarouselAdapter has
       * been clicked.
       * <p>
       * Implementers can call getItemAtPosition(position) if they need
       * to access the data associated with the selected item.
       *
       * @param parent The CarouselAdapter where the click happened.
       * @param view The view within the CarouselAdapter that was clicked (this
       *            will be a view provided by the adapter)
       * @param position The position of the view in the adapter.
       * @param id The row id of the item that was clicked.
       */
      void onItemClick(CarouselAdapter<?> parent, View view, int position, long id);
  }

  /**
   * Register a callback to be invoked when an item in this CarouselAdapter has
   * been clicked.
   *
   * @param listener The callback that will be invoked.
   */
  public void setOnItemClickListener(OnItemClickListener listener) {
      mOnItemClickListener = listener;
  }

  /**
   * @return The callback to be invoked with an item in this CarouselAdapter has
   *         been clicked, or null id no callback has been set.
   */
  public final OnItemClickListener getOnItemClickListener() {
      return mOnItemClickListener;
  }

  /**
   * Call the OnItemClickListener, if it is defined.
   *
   * @param view The view within the CarouselAdapter that was clicked.
   * @param position The position of the view in the adapter.
   * @param id The row id of the item that was clicked.
   * @return True if there was an assigned OnItemClickListener that was
   *         called, false otherwise is returned.
   */
  public boolean performItemClick(View view, int position, long id) {
      if (mOnItemClickListener != null) {
          playSoundEffect(SoundEffectConstants.CLICK);
          mOnItemClickListener.onItemClick(this, view, position, id);
          return true;
      }

      return false;
  }

  /**
   * Interface definition for a callback to be invoked when an item in this
   * view has been clicked and held.
   */
  public interface OnItemLongClickListener {
      /**
       * Callback method to be invoked when an item in this view has been
       * clicked and held.
       *
       * Implementers can call getItemAtPosition(position) if they need to access
       * the data associated with the selected item.
       *
       * @param parent The AbsListView where the click happened
       * @param view The view within the AbsListView that was clicked
       * @param position The position of the view in the list
       * @param id The row id of the item that was clicked
       *
       * @return true if the callback consumed the long click, false otherwise
       */
      boolean onItemLongClick(CarouselAdapter<?> parent, View view, int position, long id);
  }


  /**
   * Register a callback to be invoked when an item in this CarouselAdapter has
   * been clicked and held
   *
   * @param listener The callback that will run
   */
  public void setOnItemLongClickListener(OnItemLongClickListener listener) {
      if (!isLongClickable()) {
          setLongClickable(true);
      }
      mOnItemLongClickListener = listener;
  }

  /**
   * @return The callback to be invoked with an item in this CarouselAdapter has
   *         been clicked and held, or null id no callback as been set.
   */
  public final OnItemLongClickListener getOnItemLongClickListener() {
      return mOnItemLongClickListener;
  }

  /**
   * Interface definition for a callback to be invoked when
   * an item in this view has been selected.
   */
  public interface OnItemSelectedListener {
      /**
       * Callback method to be invoked when an item in this view has been
       * selected.
       *
       * Impelmenters can call getItemAtPosition(position) if they need to access the
       * data associated with the selected item.
       *
       * @param parent The CarouselAdapter where the selection happened
       * @param view The view within the CarouselAdapter that was clicked
       * @param position The position of the view in the adapter
       * @param id The row id of the item that is selected
       */
      void onItemSelected(CarouselAdapter<?> parent, View view, int position, long id);

      void onNothingSelected(CarouselAdapter<?> parent);
  }


  /**
   * Register a callback to be invoked when an item in this CarouselAdapter has
   * been selected.
   *
   * @param listener The callback that will run
   */
  public void setOnItemSelectedListener(OnItemSelectedListener listener) {
      mOnItemSelectedListener = listener;
  }

  public final OnItemSelectedListener getOnItemSelectedListener() {
      return mOnItemSelectedListener;
  }

  /**
   * Extra menu information provided to the
   * {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo) }
   * callback when a context menu is brought up for this CarouselAdapter.
   *
   */
  public static class AdapterContextMenuInfo implements ContextMenu.ContextMenuInfo {

      public AdapterContextMenuInfo(View targetView, int position, long id) {
          this.targetView = targetView;
          this.position = position;
          this.id = id;
      }

      public View targetView;
      public int position;
      public long id;
  }

  /**
   * Returns the adapter currently associated with this widget.
   *
   * @return The adapter used to provide this view's content.
   */
  public abstract T getAdapter();

  /**
   * Sets the adapter that provides the data and the views to represent the data
   * in this widget.
   *
   * @param adapter The adapter to use to create this view's content.
   */
  public abstract void setAdapter(T adapter);

  /**
   * This method is not supported and throws an UnsupportedOperationException when called.
   *
   * @param child Ignored.
   *
   * @throws UnsupportedOperationException Every time this method is invoked.
   */
  @Override
  public void addView(View child) {
      throw new UnsupportedOperationException("addView(View) is not supported in CarouselAdapter");
  }

  /**
   * This method is not supported and throws an UnsupportedOperationException when called.
   *
   * @param child Ignored.
   * @param index Ignored.
   *
   * @throws UnsupportedOperationException Every time this method is invoked.
   */
  @Override
  public void addView(View child, int index) {
      throw new UnsupportedOperationException("addView(View, int) is not supported in CarouselAdapter");
  }

  @Override
  public void addView(View child, LayoutParams params) {
      throw new UnsupportedOperationException("addView(View, LayoutParams) "
              + "is not supported in CarouselAdapter");
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
      throw new UnsupportedOperationException("addView(View, int, LayoutParams) "
              + "is not supported in CarouselAdapter");
  }

  /**
   * This method is not supported and throws an UnsupportedOperationException when called.
   *
   * @param child Ignored.
   *
   * @throws UnsupportedOperationException Every time this method is invoked.
   */
  @Override
  public void removeView(View child) {
      throw new UnsupportedOperationException("removeView(View) is not supported in CarouselAdapter");
  }

  /**
   * This method is not supported and throws an UnsupportedOperationException when called.
   *
   * @param index Ignored.
   *
   * @throws UnsupportedOperationException Every time this method is invoked.
   */
  @Override
  public void removeViewAt(int index) {
      throw new UnsupportedOperationException("removeViewAt(int) is not supported in CarouselAdapter");
  }

  /**
   * This method is not supported and throws an UnsupportedOperationException when called.
   *
   * @throws UnsupportedOperationException Every time this method is invoked.
   */
  @Override
  public void removeAllViews() {
      throw new UnsupportedOperationException("removeAllViews() is not supported in CarouselAdapter");
  }

  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
      mLayoutHeight = getHeight();
  }

  /**
   * Return the position of the currently selected item within the adapter's data set
   *
   * @return int Position (starting at 0), or {@link #INVALID_POSITION} if there is nothing selected.
   */
  @ViewDebug.CapturedViewProperty
  public int getSelectedItemPosition() {
      return mNextSelectedPosition;
  }

  /**
   * @return The id corresponding to the currently selected item, or {@link #INVALID_ROW_ID}
   * if nothing is selected.
   */
  @ViewDebug.CapturedViewProperty
  public long getSelectedItemId() {
      return mNextSelectedRowId;
  }

  /**
   * @return The view corresponding to the currently selected item, or null
   * if nothing is selected
   */
  public abstract View getSelectedView();

  /**
   * @return The data corresponding to the currently selected item, or
   * null if there is nothing selected.
   */
  public Object getSelectedItem() {
      T adapter = getAdapter();
      int selection = getSelectedItemPosition();
      if (adapter != null && adapter.getCount() > 0 && selection >= 0) {
          return adapter.getItem(selection);
      } else {
          return null;
      }
  }

  /**
   * @return The number of items owned by the Adapter associated with this
   *         CarouselAdapter. (This is the number of data items, which may be
   *         larger than the number of visible view.)
   */
  @ViewDebug.CapturedViewProperty
  public int getCount() {
      return mItemCount;
  }

  public int getPositionForView(View view) {
      View listItem = view;
      try {
          View v;
          while (!(v = (View) listItem.getParent()).equals(this)) {
              listItem = v;
          }
      } catch (ClassCastException e) {
          // We made it up to the window without find this list view
          return INVALID_POSITION;
      }

      // Search the children for the list item
      final int childCount = getChildCount();
      for (int i = 0; i < childCount; i++) {
          if (getChildAt(i).equals(listItem)) {
              return mFirstPosition + i;
          }
      }

      // Child not found!
      return INVALID_POSITION;
  }

  /**
   * Returns the position within the adapter's data set for the first item
   * displayed on screen.
   *
   * @return The position within the adapter's data set
   */
  public int getFirstVisiblePosition() {
      return mFirstPosition;
  }

  /**
   * Returns the position within the adapter's data set for the last item
   * displayed on screen.
   *
   * @return The position within the adapter's data set
   */
  public int getLastVisiblePosition() {
      return mFirstPosition + getChildCount() - 1;
  }

  /**
   * Sets the currently selected item. To support accessibility subclasses that
   * override this method must invoke the overriden super method first.
   *
   * @param position Index (starting at 0) of the data item to be selected.
   */
  public abstract void setSelection(int position);

  /**
   * Sets the view to show if the adapter is empty
   */
  public void setEmptyView(View emptyView) {
      mEmptyView = emptyView;

      final T adapter = getAdapter();
      final boolean empty = ((adapter == null) || adapter.isEmpty());
      updateEmptyStatus(empty);
  }

  public View getEmptyView() {
      return mEmptyView;
  }

  boolean isInFilterMode() {
      return false;
  }

  @Override
  public void setFocusable(boolean focusable) {
      final T adapter = getAdapter();
      final boolean empty = adapter == null || adapter.getCount() == 0;

      mDesiredFocusableState = focusable;
      if (!focusable) {
          mDesiredFocusableInTouchModeState = false;
      }

      super.setFocusable(focusable && (!empty || isInFilterMode()));
  }

  @Override
  public void setFocusableInTouchMode(boolean focusable) {
      final T adapter = getAdapter();
      final boolean empty = adapter == null || adapter.getCount() == 0;

      mDesiredFocusableInTouchModeState = focusable;
      if (focusable) {
          mDesiredFocusableState = true;
      }

      super.setFocusableInTouchMode(focusable && (!empty || isInFilterMode()));
  }

  void checkFocus() {
      final T adapter = getAdapter();
      final boolean empty = adapter == null || adapter.getCount() == 0;
      final boolean focusable = !empty || isInFilterMode();
      // The order in which we set focusable in touch mode/focusable may matter
      // for the client, see View.setFocusableInTouchMode() comments for more
      // details
      super.setFocusableInTouchMode(focusable && mDesiredFocusableInTouchModeState);
      super.setFocusable(focusable && mDesiredFocusableState);
      if (mEmptyView != null) {
          updateEmptyStatus((adapter == null) || adapter.isEmpty());
      }
  }

  private void updateEmptyStatus(boolean empty) {
      if (isInFilterMode()) {
          empty = false;
      }

      if (empty) {
          if (mEmptyView != null) {
              mEmptyView.setVisibility(View.VISIBLE);
              setVisibility(View.GONE);
          } else {
              // If the caller just removed our empty view, make sure the list view is visible
              setVisibility(View.VISIBLE);
          }

          if (mDataChanged) {           
              this.onLayout(false, getLeft(), getTop(), getRight(), getBottom()); 
          }
      } else {
          if (mEmptyView != null) mEmptyView.setVisibility(View.GONE);
          setVisibility(View.VISIBLE);
      }
  }

  /**
   * Gets the data associated with the specified position in the list.
   *
   * @param position Which data to get
   * @return The data associated with the specified position in the list
   */
  public Object getItemAtPosition(int position) {
      T adapter = getAdapter();
      return (adapter == null || position < 0) ? null : adapter.getItem(position);
  }

  public long getItemIdAtPosition(int position) {
      T adapter = getAdapter();
      return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position);
  }

  @Override
  public void setOnClickListener(OnClickListener l) {
      throw new RuntimeException("Don't call setOnClickListener for an CarouselAdapter. "
              + "You probably want setOnItemClickListener instead");
  }

  /**
   * Override to prevent freezing of any views created by the adapter.
   */
  @Override
  protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
      dispatchFreezeSelfOnly(container);
  }

  /**
   * Override to prevent thawing of any views created by the adapter.
   */
  @Override
  protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
      dispatchThawSelfOnly(container);
  }

  class AdapterDataSetObserver extends DataSetObserver {

      private Parcelable mInstanceState = null;

      @Override
      public void onChanged() {
          mDataChanged = true;
          mOldItemCount = mItemCount;
          mItemCount = getAdapter().getCount();

          // Detect the case where a cursor that was previously invalidated has
          // been repopulated with new data.
          if (CarouselAdapter.this.getAdapter().hasStableIds() && mInstanceState != null
                  && mOldItemCount == 0 && mItemCount > 0) {
              CarouselAdapter.this.onRestoreInstanceState(mInstanceState);
              mInstanceState = null;
          } else {
              rememberSyncState();
          }
          checkFocus();
          requestLayout();
      }

      @Override
      public void onInvalidated() {
          mDataChanged = true;

          if (CarouselAdapter.this.getAdapter().hasStableIds()) {
              // Remember the current state for the case where our hosting activity is being
              // stopped and later restarted
              mInstanceState = CarouselAdapter.this.onSaveInstanceState();
          }

          // Data is invalid so we should reset our state
          mOldItemCount = mItemCount;
          mItemCount = 0;
          mSelectedPosition = INVALID_POSITION;
          mSelectedRowId = INVALID_ROW_ID;
          mNextSelectedPosition = INVALID_POSITION;
          mNextSelectedRowId = INVALID_ROW_ID;
          mNeedSync = false;
          checkSelectionChanged();

          checkFocus();
          requestLayout();
      }

      public void clearSavedState() {
          mInstanceState = null;
      }
  }

  private class SelectionNotifier extends Handler implements Runnable {
      public void run() {
          if (mDataChanged) {
              // Data has changed between when this SelectionNotifier
              // was posted and now. We need to wait until the CarouselAdapter
              // has been synched to the new data.
              post(this);
          } else {
              fireOnSelected();
          }
      }
  }

  void selectionChanged() {
      if (mOnItemSelectedListener != null) {
          if (mInLayout || mBlockLayoutRequests) {
              // If we are in a layout traversal, defer notification
              // by posting. This ensures that the view tree is
              // in a consistent state and is able to accomodate
              // new layout or invalidate requests.
              if (mSelectionNotifier == null) {
                  mSelectionNotifier = new SelectionNotifier();
              }
              mSelectionNotifier.post(mSelectionNotifier);
          } else {
              fireOnSelected();
          }
      }

      // we fire selection events here not in View
      if (mSelectedPosition != ListView.INVALID_POSITION && isShown() && !isInTouchMode()) {
          sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
      }
  }

  private void fireOnSelected() {
      if (mOnItemSelectedListener == null)
          return;

      int selection = this.getSelectedItemPosition();
      if (selection >= 0) {
          View v = getSelectedView();
          mOnItemSelectedListener.onItemSelected(this, v, selection,
                  getAdapter().getItemId(selection));
      } else {
          mOnItemSelectedListener.onNothingSelected(this);
      }
  }

  @Override
  public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
      if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
          event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
      }

      // we send selection events only from CarouselAdapter to avoid
      // generation of such event for each child
      View selectedView = getSelectedView();
      if (selectedView != null) {
          populated = selectedView.dispatchPopulateAccessibilityEvent(event);
      }

      if (!populated) {
          if (selectedView != null) {
              event.setEnabled(selectedView.isEnabled());
          }
          event.setItemCount(getCount());
          event.setCurrentItemIndex(getSelectedItemPosition());
      }

      return populated;
  }

  @Override
  protected boolean canAnimate() {
      return super.canAnimate() && mItemCount > 0;
  }

  void handleDataChanged() {
      final int count = mItemCount;
      boolean found = false;

      if (count > 0) {

          int newPos;

          // Find the row we are supposed to sync to
          if (mNeedSync) {
              // Update this first, since setNextSelectedPositionInt inspects
              // it
              mNeedSync = false;

              // See if we can find a position in the new data with the same
              // id as the old selection
              newPos = findSyncPosition();
              if (newPos >= 0) {
                  // Verify that new selection is selectable
                  int selectablePos = lookForSelectablePosition(newPos, true);
                  if (selectablePos == newPos) {
                      // Same row id is selected
                      setNextSelectedPositionInt(newPos);
                      found = true;
                  }
              }
          }
          if (!found) {
              // Try to use the same position if we can't find matching data
              newPos = getSelectedItemPosition();

              // Pin position to the available range
              if (newPos >= count) {
                  newPos = count - 1;
              }
              if (newPos < 0) {
                  newPos = 0;
              }

              // Make sure we select something selectable -- first look down
              int selectablePos = lookForSelectablePosition(newPos, true);
              if (selectablePos < 0) {
                  // Looking down didn't work -- try looking up
                  selectablePos = lookForSelectablePosition(newPos, false);
              }
              if (selectablePos >= 0) {
                  setNextSelectedPositionInt(selectablePos);
                  checkSelectionChanged();
                  found = true;
              }
          }
      }
  }

  void checkSelectionChanged() {
      if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) {
          selectionChanged();
          mOldSelectedPosition = mSelectedPosition;
          mOldSelectedRowId = mSelectedRowId;
      }
  }
}
4

1 回答 1

1

开始一个意图setOnItemClickListener

像这样 :

    Carousel carousel = (Carousel)findViewById(R.id.category_carousel);
            carousel.setOnItemClickListener(new OnItemClickListener(){

                @Override
                public void onItemClick(CarouselAdapter<?> parent, View view,
                        int position, long id) {                
                Intent intent = new Intent(this,newActivity.class);     
startActivity(intent);      
                }
            });
于 2012-08-13T09:52:08.110 回答