今天离职,除了交接,自己时间还是挺多的。
其实 公司对我还是挺好的。自己努力, 希望以后可以做到感恩。
离职后自己还有写事情要做,简单先写一篇blog,记录下。
无论好不好,自己先记录下吧。可能以后看现在的文章比较傻逼,当然,如果感觉自己文章傻逼的时候,也就是自己提高的时候。:-)
BaseAdapter我们都用得比较多。通常只要实现几个接口
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null;
}
就可以做对应的实现了,无论是list,还是gridview什么的
在看 源码实现之前,首先要了解 适配器模式 和 观察者模式
适配器模式, 主要是将各种类型适配,达到比较统一的接口实现。
比如,原来用竹筷子的人,现在只有铁筷子,或者叉子什么的。
或者 head First里面的, 给让火烈鸟 叫,飞 一样。
观察者模式, 主要是负责通知,注册,删除,更新,容器中的数据。
让观察者可以容易控制被观察者。
例如java设计模式中的警察抓小偷, 或者head First中的发报纸说明, 猎头说明一样
自己具体的理解,可以见
【观察者的文章】
我们看看BaseAdapter的代码
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
/**
* Common base class of common implementation for an {@link Adapter} that can be
* used in both {@link ListView} (by implementing the specialized
* {@link ListAdapter} interface} and {@link Spinner} (by implementing the
* specialized {@link SpinnerAdapter} interface.
*/
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public boolean hasStableIds() {
return false;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
/**
* Notifies the attached View that the underlying data has been changed
* and it should refresh itself.
*/
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
return true;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}
public int getItemViewType(int position) {
return 0;
}
public int getViewTypeCount() {
return 1;
}
public boolean isEmpty() {
return getCount() == 0;
}
}
分别实现了 ListAdapter 和 SpinnerAdapter
public interface ListAdapter extends Adapter {
/**
* Are all items in this ListAdapter enabled?
* If yes it means all items are selectable and clickable.
*
* @return True if all items are enabled
*/
public boolean areAllItemsEnabled();
/**
* Returns true if the item at the specified position is not a separator.
* (A separator is a non-selectable, non-clickable item).
*
* The result is unspecified if position is invalid. An {@link ArrayIndexOutOfBoundsException}
* should be thrown in that case for fast failure.
*
* @param position Index of the item
* @return True if the item is not a separator
*/
boolean isEnabled(int position);
}
public interface SpinnerAdapter extends Adapter {
/**
* <p>Get a {@link android.view.View} that displays in the drop down popup
* the data at the specified position in the data set.</p>
*
* @param position index of the item whose view we want.
* @param convertView the old view to reuse, if possible. Note: You should
* check that this view is non-null and of an appropriate type before
* using. If it is not possible to convert this view to display the
* correct data, this method can create a new view.
* @param parent the parent that this view will eventually be attached to
* @return a {@link android.view.View} corresponding to the data at the
* specified position.
*/
public View getDropDownView(int position, View convertView, ViewGroup parent);
}
分别的实现也很简单
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
return true;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}
我们再来看看对应的View组件ListView对应setAdapter的代码
public void setAdapter(ListAdapter adapter) {
if (null != mAdapter) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();
mRecycler.clear();
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
if (mAdapter != null) {
mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
mOldItemCount = mItemCount;
mItemCount = mAdapter.getCount();
checkFocus();
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());
int position;
if (mStackFromBottom) {
position = lookForSelectablePosition(mItemCount - 1, false);
} else {
position = lookForSelectablePosition(0, true);
}
setSelectedPositionInt(position);
setNextSelectedPositionInt(position);
if (mItemCount == 0) {
// Nothing selected
checkSelectionChanged();
}
if (mChoiceMode != CHOICE_MODE_NONE &&
mAdapter.hasStableIds() &&
mCheckedIdStates == null) {
mCheckedIdStates = new LongSparseArray<Boolean>();
}
} else {
mAreAllItemsSelectable = true;
checkFocus();
// Nothing selected
checkSelectionChanged();
}
if (mCheckStates != null) {
mCheckStates.clear();
}
if (mCheckedIdStates != null) {
mCheckedIdStates.clear();
}
requestLayout();
}
会unregister原来监听的对象,清理对应list的header和footer,
和对应的一些复杂操作。。。