編輯:關於Android編程
看一段簡單的代碼,在一個pager裡面顯示兩個TextView
Listitems = new ArrayList (); adapter = new MyPagerAdapter();
TextView tv = new TextView(getActivity()); tv.setText(第一頁); items.add(tv); tv = new TextView(getActivity()); tv.setText(第二頁); items.add(tv); pager.setAdapter(adapter);
Adapter代碼
class MyPagerAdapter extends PagerAdapter{
@Override
public Object instantiateItem(ViewGroup container, int position) {
View layout = items.get(position);
container.addView(layout);
return layout;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
View layout = items.get(position);
container.removeView(layout);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public int getCount() {
return items.size();
}
@Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return super.getItemPosition(object);
}
}
代碼運行正常,左右滑動都OK。
好,現在需求來了,我需要把“第一頁”和“第二頁”干掉,再重新添加兩個TextView,分別是“第三頁”和“第四頁”,於是按常理寫了如下代碼
items.clear(); TextView tv = new TextView(getActivity()); tv.setText(第三頁); items.add(tv); tv = new TextView(getActivity()); tv.setText(第四頁); items.add(tv); adapter.notifyDataSetChanged();我們在使用ListView的時候,改變數據源的數據,然後通知adpater去更新,就可以正常顯示,可是在ViewPager這不好使,上面代碼執行後,沒有任何變化
那我們想是不是ViewPager需要清一下原有的試圖呢,好,再加一句
pager.removeAllViews();再次運行,可好,一片空白,啥也沒了,真干淨!
蒙了吧,到底什麼原因,就是getItemPosition,讓我看看當ViewPager的Adapter發生變化時,到底干了啥,Adapter執行notifyDataSetChanged時,會觸發ViewPager的dataSetChanged方法,下面是源碼,:
void dataSetChanged() {
// This method only gets called if our observer is attached, so mAdapter is non-null.
final int adapterCount = mAdapter.getCount();
mExpectedAdapterCount = adapterCount;
boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1 &&
mItems.size() < adapterCount;
int newCurrItem = mCurItem;
boolean isUpdating = false;
for (int i = 0; i < mItems.size(); i++) {
final ItemInfo ii = mItems.get(i);
final int newPos = mAdapter.getItemPosition(ii.object);
//看這句話,如果是PagerAdapter.POSITION_UNCHANGED標志,直接返回,不做任何處理
if (newPos == PagerAdapter.POSITION_UNCHANGED) {
continue;
}
//只有返回PagerAdapter.POSITION_NONE標志時,才會對內部視圖進行調整
if (newPos == PagerAdapter.POSITION_NONE) {
//先從數據源中清除
mItems.remove(i);
i--;
if (!isUpdating) {
mAdapter.startUpdate(this);
isUpdating = true;
}
//在調用Adapter的destroyItem,去銷毀視圖
mAdapter.destroyItem(this, ii.position, ii.object);
needPopulate = true;
if (mCurItem == ii.position) {
// Keep the current item in the valid range
newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1));
needPopulate = true;
}
continue;
}
if (ii.position != newPos) {
if (ii.position == mCurItem) {
// Our current item changed position. Follow it.
newCurrItem = newPos;
}
ii.position = newPos;
needPopulate = true;
}
}
if (isUpdating) {
mAdapter.finishUpdate(this);
}
Collections.sort(mItems, COMPARATOR);
if (needPopulate) {
// Reset our known page widths; populate will recompute them.
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.isDecor) {
lp.widthFactor = 0.f;
}
}
setCurrentItemInternal(newCurrItem, false, true);
requestLayout();
}
}
PagerAdapter.POSITION_UNCHANGED,這個標記決定著視圖是否被重新創建,Apdapter默認的代碼如下
public int getItemPosition(Object object) {
return POSITION_UNCHANGED;
}
默認返回POSITION_UNCHANGED,所以如果你不對Adapter的getItemPosition進行重寫的畫,就會出現無法更改內部視圖效果的問題。下面對從PagerAdapter繼承的代碼進行改造,加上對getItemPosition的修改,讓他直接返回POSITION_NONE,POSITION_NONE每次數據發生變化,都會引起視圖的重建,比較消耗內存,所以不需要變化內部視圖時,避免使用。
@Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
如果返回了POSITION_NONE,但是沒有pager.removeAllViews(),那麼“第一頁”和“第二頁”沒有消失,“第三頁”和“第四頁”也上去了,分別和前兩頁重合了,看圖
如果返回了POSITION_UNCHANGED,但是沒有pager.removeAllViews(),那麼看不到任何變化。
Android開發 Activity和Fragment詳解
1.Activity的生命周期1)多個Activity組成Activity棧,當前活動位於棧頂。我們先來看看各種Activity基類的類圖:當Activity類定義出來之
Android 高仿微信轉賬金錢輸入框規則
微信轉賬輸入框規則(可能不全)1、小數點後兩位2、起始輸入小數點,顯示0.3、刪除到第一個位置是小數點的時候,第一個位置為0 ,避免出現小數點在第一個位置的情況修改這個朋
深入淺析Android坐標系統
1 背景去年有很多人私信告訴我讓說說自定義控件,其實通觀網絡上的很多博客都在講各種自定義控件,但是大多數都是授之以魚,卻很少有較為系統性授之於漁的文章,同時由
[Android學習筆記]Adapter如何進行視圖與數據綁定資料
Android開發中視圖和數據的綁定離不開Adapt系列的類,在呈現給用戶的界面友好美觀和內容豐富的應用中視圖為骨,內容為肉,Ad