深入理解ListView (1)— 一天一点源码

AdapterView - 一天一点源码

前言:深入理解ListView (1)— 一天一点源码_第1张图片

由图可知,ListView继承至AbsListView,AbsListView又继承至AdapterView(还实现了TextWatcher方法,往后再说)。
计划从AdapterView开始对ListView进行理解,了解ListView的实现机制。

1、说明

/**
 * An AdapterView is a view whose children are determined by an {@link Adapter}.
 */

public abstract class AdapterView<T extends Adapter> extends ViewGroup {...}

AdapterView是一个带有一个Adapter子类泛型的抽象类,继承自ViewGroup。

2、方法


public AdapterView(Context context) {
    this(context, null);
}

public AdapterView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public AdapterView(Context context, AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
}

public AdapterView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);

    // If not explicitly specified this view is important for accessibility.
    if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
    }
}

AdapterView的5个构造方法。


public interface OnItemClickListener {
    void onItemClick(AdapterView parent, View view, int position, long    id);
}

public void setOnItemClickListener(@Nullable OnItemClickListener listener) {
    mOnItemClickListener = listener;
}

@Nullable
public final OnItemClickListener getOnItemClickListener() {
    return mOnItemClickListener;
}

定义了item点击监听接口,实现点击监听的方法,以及获得Item的当前监听器对象的方法


public boolean performItemClick(View view, int position, long id) {
    final boolean result;
    if (mOnItemClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
        mOnItemClickListener.onItemClick(this, view, position, id);
        result = true;
    } else {
        result = false;
    }

    if (view != null) {
        view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
    }
    return result;
}

如果点击监听被定义,实现点击事务。


    boolean onItemLongClick(AdapterView parent, View view, int position, long id);
}


public void setOnItemLongClickListener(OnItemLongClickListener listener) {
    if (!isLongClickable()) {
        setLongClickable(true);
    }
    mOnItemLongClickListener = listener;
}

定义长按点击事件的方法


public interface OnItemSelectedListener {
       void onItemSelected(AdapterView parent, View view, int position, long id);


    void onNothingSelected(AdapterView parent);
}

public void setOnItemSelectedListener(@Nullable OnItemSelectedListener listener) {
    mOnItemSelectedListener = listener;
}

@Nullable
public final OnItemSelectedListener getOnItemSelectedListener() {
    return mOnItemSelectedListener;
}

定义Item选择监听的接口,Item被选择的监听方法,以及获得当前Item监听器的对象的方法。


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

重写父类方法,设置当前AdapterView的监听。


@Override
public void addView(View child) {
    throw new UnsupportedOperationException("addView(View) is not supported in AdapterView");
}

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

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

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

addView继承自ViewGroup,不支持调用,调用是抛出异常。


@Override
public CharSequence getAccessibilityClassName() {
    return AdapterView.class.getName();
}

返回AdapterView的类名。


public abstract T getAdapter();

返回AdapterView的适配器adapter。


public abstract void setAdapter(T adapter);

设置AdapterView的适配器adapter。

@Override
public void removeView(View child) {
    throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView");
}

@Override
public void removeViewAt(int index) {
    throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView");
}

@Override
public void removeAllViews() {
    throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView");
}

重写的ViewGroup的remove方法,依次为移除指定视图,移除指定位置的视图,移除所有视图等。不可被调用,调用抛出异常。

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

重写的ViewGroup的方法,获得当前高度。

public long getSelectedItemId() {
    return mNextSelectedRowId;
}

获得选中子控件的Id。

public abstract View getSelectedView();

获得选中的视图。

public Object getSelectedItem() {
    T adapter = getAdapter();
    int selection = getSelectedItemPosition();
    if (adapter != null && adapter.getCount() > 0 && selection >= 0) {
        return adapter.getItem(selection);
    } else {
        return null;
    }
}

获得被选中的Item的对象。

public int getCount() {
    return mItemCount;
}

获得Item的数量。

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

    if (listItem != null) {
        // 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;
}

传入一个视图,返回传入视图的位置。

public int getFirstVisiblePosition() {
    return mFirstPosition;
}

返回适配器设置的屏幕上可显示第一个Item的位置。

public int getLastVisiblePosition() {
    return mFirstPosition + getChildCount() - 1;
}

返回适配器设置的屏幕上可显示的最后一个Item的位置。

public abstract void setSelection(int position);

设置当前选择条目。

public void setEmptyView(View emptyView) {
    mEmptyView = emptyView;

    // If not explicitly specified this view is important for accessibility.
    if (emptyView != null
            && emptyView.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
        emptyView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
    }

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

设置空视图。

public View getEmptyView() {
    return mEmptyView;
}

获得当前AdapterView的空视图对象。

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

        // We are now GONE, so pending layouts will not be dispatched.
        // Force one here to make sure that the state of the list matches
        // the state of the adapter.
        if (mDataChanged) {           
            this.onLayout(false, mLeft, mTop, mRight, mBottom); 
        }
    } else {
        if (mEmptyView != null) mEmptyView.setVisibility(View.GONE);
        setVisibility(View.VISIBLE);
    }
}

设置空视图的可见状态。

public Object getItemAtPosition(int position) {
    T adapter = getAdapter();
    return (adapter == null || position < 0) ? null : adapter.getItem(position);
}

传入一个Item位置,获得Adapter中Item对应的数据

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

传入Item的位置,获得Adapter中Item对应的位置


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 (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
                && mOldItemCount == 0 && mItemCount > 0) {
            AdapterView.this.onRestoreInstanceState(mInstanceState);
            mInstanceState = null;
        } else {
            rememberSyncState();
        }
        checkFocus();
        requestLayout();
    }

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

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

        // Data is invalid so we should reset our state
        mOldItemCount = mItemCount;
        mItemCount = 0;
        mSelectedPosition = INVALID_POSITI结结结结结结
N;
        mSelectedRowId = INVALID_ROW_ID;
        mNextSelectedPosition = INVALID_POSITION;

      mNextSelectedRowId = INVALID_ROW_ID;
        mNeedSync = false;

        checkFocus();
        requestLayout();
    }


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

定义内部类,为AdapterView设置观察者,通过重写的onChange,onInvalidated,clearSavedState,对Adapter的状态及参数进行观察,实时做出相应改变。

总结

以上并不是AdapterView的全部源码,只是将我觉得重要的源码,以及一些在ListView中有体现的源码进行了阅读。
粗略感觉AdapterView已实现了Listview的大部分基础功能。
AdapterView中定义了设置ListView中item监听的各种方法,以及设置Adapter,内部内继承观察者类,对数据进行监控…等等。
一点一点的理解,逐步了解ListView的实现机制。

你可能感兴趣的:(一天一点源代码)