ViewPager
- ViewPager主要用來左右滑動。(類似圖片輪播)
- ViewPager用適配器來連接“視圖”和“數據”。(大家在使用時可以聯想下listview的使用方法,原理是類似的)
- 官方推薦ViewPager與Fragment一起使用,並且有專門的適配器(FragmentPagerAdapter)。
- ViewPager提供了預加載機制
- 只要滑動過程中不處於第一個條目或者最後一個條目,都是左右各預加載一個條目
- 滑動後,跟當前顯示的條目不相鄰,銷燬掉這個條目
ViewPager用法和listview有點相似,在xml中進行設置,設置適配器,設置條目監聽事件
代碼:
1. 在XML中設置節點
2. 在oncreate中實例化
3. 設置適配器
private PagerAdapter myAdapter = new PagerAdapter() {
/**
* 返回ViewPager中的頁面的總個數
*/
@Override
public int getCount() {
return FAKE_COUNT;
}
/**
* 判斷instantiateItem返回的key(view)與一個頁面視圖是否代表的同一個視圖
* @param view
* @param object
*
* @return 如果對應的是同一個View,返回True,否則返回False
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;//官方推薦寫法
}
/**
* 初始化位置爲position的頁面,並返回當前頁面
* @param container
* @param position 頁面索引
* 做了兩件事:
* 第一:將指定position的視圖添加到conatiner中
* 第二:返回當前View
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(view);
return view;
}
/**
* 當位置爲position的頁面不再使用時,銷燬它。
* 操作:從當前container中刪除指定位置(position)的頁面
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
};
案例:
先來看一下效果圖
以下是代碼實現,具體思路已經寫在代碼中,這裏就不再贅述,相信大家看代碼就會懂的
/**
* 循環廣告Demo
* 思路:
* 我們需要在viewpager上展示5張圖片,
* 但是我們需要循環滑動,所以需要告訴Viewpager一個虛假的個數,eg:100,那麼現在我們可以右滑100下了。
* 當滑倒第6個頁面時,這個是空白,所以此時可以把第一屏的內容給第6屏,即從最後一屏循環滑動到了第一屏,
* 此時我們就實現了向右循環。
* 同理,當第一屏向前滑動時,我們同樣可以返回最後一屏的View。
* 但是這裏有一個問題,第一屏沒辦法向前滑動,因爲第一屏的位置是0,ViewPager不能滑動到-1的位置!
* 如果在ViewPager將要滑動到0時,這個時候我們迅速將其切換到第6屏會怎麼樣?
* 由於第6屏的內容實際上就是第1屏的內容,因此界面上感受不到任何變化,
* 但是這個時候ViewPager當前屏幕的下標已經從0變爲5了,這意味着ViewPager可以向前滑動了。
* OK 下來就是實現了
*/
public class MainActivity extends AppCompatActivity {
private int[] imageResIds = {R.mipmap.ic_9, R.mipmap.ic_8, R.mipmap.ic_7, R.mipmap.ic_6, R.mipmap.ic_5};
private ViewPager mViewPager;
private LinearLayout ll_content;
private boolean isTouch = false;//手指是否觸摸
private int FAKE_SIZE = 100;//隨便給的虛假大小,但是不能太大,有可能會發生ANR
private int TRUE_SIZE = 5;//真實頁面個數
//設置自動循環,有多種實現方式,handler,timer,thread.. 這裏我們用Timer實現
private Timer mTimer = new Timer();
private TimerTask mTimerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isTouch) {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
}
}
});
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mViewPager = (ViewPager) findViewById(R.id.vp);
ll_content = (LinearLayout) findViewById(R.id.ll_content);
initData();
}
private void initData() {
mViewPager.setAdapter(mAdapter);
ImageView point = null;
for (int i = 0; i < imageResIds.length; i++) {
//設置小點
point = new ImageView(this);
point.setImageResource(R.mipmap.black);
ll_content.addView(point);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) point.getLayoutParams();
params.leftMargin = 8;//設置間距
point.setLayoutParams(params);
}
//設置第一個小點爲白色
((ImageView) ll_content.getChildAt(0)).setImageResource(R.mipmap.white);
//當頁面改變時回調
mViewPager.addOnPageChangeListener(mPageChangeListener);
//添加觸摸監聽
mViewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
isTouch = true;
break;
case MotionEvent.ACTION_UP:
isTouch = false;
break;
}
return false;
}
});
//設置自動循環 //安排指定的任務從指定的延遲後開始進行重複的固定延遲執行。
mTimer.schedule(mTimerTask, 3000, 3000);
}
//記錄上一個點
int prePos = 0;
//設置頁面改變監聽
private ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
position %= TRUE_SIZE;
//設置前一個點爲黑的
((ImageView) ll_content.getChildAt(prePos)).setImageResource(R.mipmap.black);
//設置小點顏色
ImageView point = (ImageView) ll_content.getChildAt(position);
point.setImageResource(R.mipmap.white);
prePos = position;
super.onPageSelected(position);
}
};
private PagerAdapter mAdapter = new PagerAdapter() {
@Override
public int getCount() {
return FAKE_SIZE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
position %= TRUE_SIZE;//利用取模來實現不斷向後循環
ImageView mImageView = new ImageView(MainActivity.this);
mImageView.setImageResource(imageResIds[position]);
container.addView(mImageView);
return mImageView;
}
@Override
public void finishUpdate(ViewGroup container) {
super.finishUpdate(container);
int position = mViewPager.getCurrentItem();
if (position == 0) {
position = TRUE_SIZE;
mViewPager.setCurrentItem(position);
} else if (position == FAKE_SIZE - 1) {
position = TRUE_SIZE - 1;
mViewPager.setCurrentItem(position);
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
};
@Override
protected void onDestroy() {
mViewPager.removeOnPageChangeListener(mPageChangeListener);
mTimer.cancel();
super.onDestroy();
}
}