編輯:關於Android編程
這個案例網上也很多, 質量參差不齊, 我也就根據自己的理解來分析分析需要實現的幾個功能點:
輪播圖有n張圖片和相對應的n個小圓點(指示器 indicator) 實現聯動 除了可以手動滑動外, 也可以自動滾動(輪播) 可以考慮使用Handler實現 實現無限輪回滾動 當手指按下圖片後不再自動滾動根據上述分析進行開發
activity_main.xml
<framelayout android:layout_height="220dp" android:layout_width="match_parent"> </framelayout>
指示器 小點繪制文件
indicator_select.xml
indicator_no_select.xml
MyPagerAdapter.java
public class MyPagerAdapter extends PagerAdapter { public static final int MAX_SCROLL_VALUE = 10000; private ListmItems; private Context mContext; private LayoutInflater mInflater; public MyPagerAdapter(List items, Context context) { mContext = context; mInflater = LayoutInflater.from(context); mItems = items; } /** * @param container * @param position * @return 對position進行求模操作 * 因為當用戶向左滑時position可能出現負值,所以必須進行處理 */ @Override public Object instantiateItem(ViewGroup container, int position) { View ret = null; //對ViewPager頁號求摸取出View列表中要顯示的項 position %= mItems.size(); Log.d("Adapter", "instantiateItem: position: " + position); ret = mItems.get(position); //如果View已經在之前添加到了一個父組件,則必須先remove,否則會拋出IllegalStateException。 ViewParent viewParent = ret.getParent(); if (viewParent != null) { ViewGroup parent = (ViewGroup) viewParent; parent.removeView(ret); } container.addView(ret); return ret; } /** * 由於我們在instantiateItem()方法中已經處理了remove的邏輯, * 因此這裡並不需要處理。實際上,實驗表明這裡如果加上了remove的調用, * 則會出現ViewPager的內容為空的情況。 * * @param container * @param position * @param object */ @Override public void destroyItem(ViewGroup container, int position, Object object) { //警告:不要在這裡調用removeView, 已經在instantiateItem中處理了 } @Override public int getCount() { int ret = 0; if (mItems.size() > 0) { ret = MAX_SCROLL_VALUE; } return ret; } @Override public boolean isViewFromObject(View view, Object object) { return view == (View) object; } }
Note: 一定不要在destroyItem中再調用removeView了, 因為咱們已經instantiateItem中做了處理
在MainActivity.java中給ViewPager設置Adapter
mItems = new ArrayList<>(); mViewPager.setAdapter(mAdapter); addImageView(); mAdapter.notifyDataSetChanged();
private void addImageView(){ ImageView view0 = new ImageView(this); view0.setImageResource(R.mipmap.pic0); ImageView view1 = new ImageView(this); view1.setImageResource(R.mipmap.pic1); ImageView view2 = new ImageView(this); view2.setImageResource(R.mipmap.pic2); view0.setScaleType(ImageView.ScaleType.CENTER_CROP); view1.setScaleType(ImageView.ScaleType.CENTER_CROP); view2.setScaleType(ImageView.ScaleType.CENTER_CROP); mItems.add(view0); mItems.add(view1); mItems.add(view2); }
Note: 因為咱們做的是Demo, 所以我們傳入的是一個ImageView的集合, 真正開發時, 需要傳入含有圖片url的實體類, 在Adapter中可以使用加載圖片的類庫加載
添加指示器
在onCreate中添加
//獲取指示器(下面三個小點) mBottomLiner = (LinearLayout) findViewById(R.id.live_indicator); //右下方小圓點 mBottomImages = new ImageView[mItems.size()]; for (int i = 0; i < mBottomImages.length; i++) { ImageView imageView = new ImageView(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20); params.setMargins(5, 0, 5, 0); imageView.setLayoutParams(params); //如果當前是第一個 設置為選中狀態 if (i == 0) { imageView.setImageResource(R.drawable.indicator_select); } else { imageView.setImageResource(R.drawable.indicator_no_select); } mBottomImages[i] = imageView; //添加到父容器 mBottomLiner.addView(imageView); }
添加ViewPager的監聽事件, 實現ViewPager.OnPageChangeListener接口
mViewPager.addOnPageChangeListener(this);
回調事件
/////////////////////////////////////////////////////////////////////////// // ViewPager的監聽事件 /////////////////////////////////////////////////////////////////////////// @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { currentViewPagerItem = position; if (mItems != null) { position %= mBottomImages.length; int total = mBottomImages.length; for (int i = 0; i < total; i++) { if (i == position) { mBottomImages[i].setImageResource(R.drawable.indicator_select); } else { mBottomImages[i].setImageResource(R.drawable.indicator_no_select); } } } } @Override public void onPageScrollStateChanged(int state) { }
在mBottomImages初始化之後 開啟一個線程 進行定時發送一個空消息給Handler處理, 由Handler決定切換到下一頁
//讓其在最大值的中間開始滑動, 一定要在 mBottomImages初始化之前完成 int mid = MyPagerAdapter.MAX_SCROLL_VALUE / 2; mViewPager.setCurrentItem(mid); currentViewPagerItem = mid; //定時發送消息 mThread = new Thread(){ @Override public void run() { super.run(); while (true) { mHandler.sendEmptyMessage(0); try { Thread.sleep(MainActivity.VIEW_PAGER_DELAY); } catch (InterruptedException e) { e.printStackTrace(); } } } }; mThread.start();
自定義Handler
/////////////////////////////////////////////////////////////////////////// // 為防止內存洩漏, 聲明自己的Handler並弱引用Activity /////////////////////////////////////////////////////////////////////////// private static class MyHandler extends Handler { private WeakReferencemWeakReference; public MyHandler(MainActivity activity) { mWeakReference = new WeakReference (activity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: MainActivity activity = mWeakReference.get(); if (activity.isAutoPlay) { activity.mViewPager.setCurrentItem(++activity.currentViewPagerItem); } break; } } }
Note: 其中isAutoPlay是一個用來判斷當前是否是自動輪播的boolean值變量, 主要用於實現我們接下來說的 當手指按下圖片後不再滾動
思路: 我們可以考慮對ViewPager的觸摸事件進行監聽, 然後設置一個上節說到的isAutoPlay的boolean變量用來讓Handler判斷是否進行輪播滾動
代碼實現:
ViewPager設置監聽
mViewPager.setOnTouchListener(this);
事件回調
@Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: isAutoPlay = false; break; case MotionEvent.ACTION_UP: isAutoPlay = true; break; } return false; }
注: 細心的同學可能會看出來, 我們沒有單獨說 無限循環 如何實現, 其實, 它的實現已經隱藏在了代碼中, 在這裡我簡單的說一下思路:
給ViewPager的條目個數設置個較大值, 該案例中為10000, 然後我們剛進入時選中的位置為 10000/2=5000, 也就是說我們可以向左或向右滑動約5000多張圖片, 但這是不現實的, 所以就給用戶造成了無限循環的假象
我把源碼放在了github 上, 希望大家多多支持
一、在JavaEE項目中搭建環境 1. 導入相關jar包 2. 搭建相關的包和類 UserDao: UserDaoImpl: JsonServlet
在項目中做了列表頁面和詳情頁面,用到了以下幾個知識點,在這裡和大家分享一下:1.數據庫模塊的完善:1.1升級數據庫,抽出版本字段;如果xxx.db 數據庫已經存在了,之後
很多時候我們開發的軟件需要向用戶提供軟件參數設置功能,例如我們常用的QQ,用戶可以設置是否允許陌生人添加自己為好友。對於軟件配置參數的保存,如果是window軟件通常我們
最近由於項目需要,研究了一些統計圖的做法,開始時,看了很多博文,大部分都是引用第三方的庫,雖然簡單,易上手,但是功能太死板,有很多要求都是不能滿足的,所以經過研究,自己使