ConvenientBanner.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. package com.bigkoo.convenientbanner;
  2. import android.annotation.TargetApi;
  3. import android.content.Context;
  4. import android.content.res.TypedArray;
  5. import android.os.Build;
  6. import androidx.viewpager.widget.ViewPager;
  7. import androidx.viewpager.widget.ViewPager.PageTransformer;
  8. import android.util.AttributeSet;
  9. import android.view.LayoutInflater;
  10. import android.view.MotionEvent;
  11. import android.view.View;
  12. import android.view.ViewGroup;
  13. import android.widget.ImageView;
  14. import android.widget.LinearLayout;
  15. import android.widget.RelativeLayout;
  16. import com.bigkoo.convenientbanner.adapter.CBPageAdapter;
  17. import com.bigkoo.convenientbanner.holder.CBViewHolderCreator;
  18. import com.bigkoo.convenientbanner.listener.CBPageChangeListener;
  19. import com.bigkoo.convenientbanner.listener.OnItemClickListener;
  20. import com.bigkoo.convenientbanner.transformer.ScaleYTransformer;
  21. import com.bigkoo.convenientbanner.view.CBLoopViewPager;
  22. import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R;
  23. import java.lang.ref.WeakReference;
  24. import java.lang.reflect.Field;
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. /**
  28. * 页面翻转控件,极方便的广告栏
  29. * 支持无限循环,自动翻页,翻页特效
  30. * @author Sai 支持自动翻页
  31. */
  32. public class ConvenientBanner<T> extends LinearLayout {
  33. private List<T> mDatas;
  34. private int[] page_indicatorId;
  35. private ArrayList<ImageView> mPointViews = new ArrayList<ImageView>();
  36. private CBPageChangeListener pageChangeListener;
  37. private ViewPager.OnPageChangeListener onPageChangeListener;
  38. private CBPageAdapter pageAdapter;
  39. private CBLoopViewPager viewPager;
  40. private ViewPagerScroller scroller;
  41. private ViewGroup loPageTurningPoint;
  42. private long autoTurningTime;
  43. private boolean turning;
  44. private boolean canTurn = false;
  45. private boolean manualPageable = true;
  46. private boolean canLoop = true;
  47. private boolean coverMode = false;
  48. public enum PageIndicatorAlign{
  49. ALIGN_PARENT_LEFT,ALIGN_PARENT_RIGHT,CENTER_HORIZONTAL
  50. }
  51. private AdSwitchTask adSwitchTask ;
  52. public ConvenientBanner(Context context) {
  53. super(context);
  54. init(context);
  55. }
  56. public ConvenientBanner(Context context, AttributeSet attrs) {
  57. super(context, attrs);
  58. TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ConvenientBanner);
  59. canLoop = a.getBoolean(R.styleable.ConvenientBanner_canLoop,true);
  60. coverMode = a.getBoolean(R.styleable.ConvenientBanner_coverMode,false);
  61. a.recycle();
  62. init(context);
  63. }
  64. @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  65. public ConvenientBanner(Context context, AttributeSet attrs, int defStyleAttr) {
  66. super(context, attrs, defStyleAttr);
  67. TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ConvenientBanner);
  68. canLoop = a.getBoolean(R.styleable.ConvenientBanner_canLoop,true);
  69. coverMode = a.getBoolean(R.styleable.ConvenientBanner_coverMode,false);
  70. a.recycle();
  71. init(context);
  72. }
  73. @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  74. public ConvenientBanner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  75. super(context, attrs, defStyleAttr, defStyleRes);
  76. TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ConvenientBanner);
  77. canLoop = a.getBoolean(R.styleable.ConvenientBanner_canLoop,true);
  78. coverMode = a.getBoolean(R.styleable.ConvenientBanner_coverMode,false);
  79. a.recycle();
  80. init(context);
  81. }
  82. private void init(Context context) {
  83. View hView;
  84. if (coverMode){
  85. hView = LayoutInflater.from(context).inflate(
  86. R.layout.include_viewpager_cover_mode, this, true);
  87. }else {
  88. hView = LayoutInflater.from(context).inflate(
  89. R.layout.include_viewpager, this, true);
  90. }
  91. viewPager = (CBLoopViewPager) hView.findViewById(R.id.cbLoopViewPager);
  92. loPageTurningPoint = (ViewGroup) hView
  93. .findViewById(R.id.loPageTurningPoint);
  94. initViewPagerScroll();
  95. adSwitchTask = new AdSwitchTask(this);
  96. }
  97. static class AdSwitchTask implements Runnable {
  98. private final WeakReference<ConvenientBanner> reference;
  99. AdSwitchTask(ConvenientBanner convenientBanner) {
  100. this.reference = new WeakReference<ConvenientBanner>(convenientBanner);
  101. }
  102. @Override
  103. public void run() {
  104. ConvenientBanner convenientBanner = reference.get();
  105. if(convenientBanner != null){
  106. if (convenientBanner.viewPager != null && convenientBanner.turning) {
  107. int page = convenientBanner.viewPager.getCurrentItem() + 1;
  108. convenientBanner.viewPager.setCurrentItem(page);
  109. convenientBanner.postDelayed(convenientBanner.adSwitchTask, convenientBanner.autoTurningTime);
  110. }
  111. }
  112. }
  113. }
  114. public ConvenientBanner setPages(CBViewHolderCreator holderCreator,List<T> datas){
  115. this.mDatas = datas;
  116. if (coverMode){
  117. viewPager.setPageTransformer(false,new ScaleYTransformer());
  118. }
  119. pageAdapter = new CBPageAdapter(holderCreator,mDatas);
  120. viewPager.setAdapter(pageAdapter,canLoop);
  121. if (page_indicatorId != null)
  122. setPageIndicator(page_indicatorId);
  123. return this;
  124. }
  125. /**
  126. * 通知数据变化
  127. * 如果只是增加数据建议使用 notifyDataSetAdd()
  128. */
  129. public void notifyDataSetChanged(){
  130. viewPager.getAdapter().notifyDataSetChanged();
  131. if (page_indicatorId != null)
  132. setPageIndicator(page_indicatorId);
  133. }
  134. /**
  135. * 设置底部指示器是否可见
  136. *
  137. * @param visible
  138. */
  139. public ConvenientBanner setPointViewVisible(boolean visible) {
  140. loPageTurningPoint.setVisibility(visible ? View.VISIBLE : View.GONE);
  141. return this;
  142. }
  143. /**
  144. * 底部指示器资源图片
  145. *
  146. * @param page_indicatorId
  147. */
  148. public ConvenientBanner setPageIndicator(int[] page_indicatorId) {
  149. loPageTurningPoint.removeAllViews();
  150. mPointViews.clear();
  151. this.page_indicatorId = page_indicatorId;
  152. if(mDatas==null)return this;
  153. for (int count = 0; count < mDatas.size(); count++) {
  154. // 翻页指示的点
  155. ImageView pointView = new ImageView(getContext());
  156. pointView.setPadding(5, 0, 5, 0);
  157. if (mPointViews.isEmpty())
  158. pointView.setImageResource(page_indicatorId[1]);
  159. else
  160. pointView.setImageResource(page_indicatorId[0]);
  161. mPointViews.add(pointView);
  162. loPageTurningPoint.addView(pointView);
  163. }
  164. pageChangeListener = new CBPageChangeListener(mPointViews,
  165. page_indicatorId);
  166. viewPager.setOnPageChangeListener(pageChangeListener);
  167. pageChangeListener.onPageSelected(viewPager.getRealItem());
  168. if(onPageChangeListener != null)pageChangeListener.setOnPageChangeListener(onPageChangeListener);
  169. return this;
  170. }
  171. /**
  172. * 指示器的方向
  173. * @param align 三个方向:居左 (RelativeLayout.ALIGN_PARENT_LEFT),居中 (RelativeLayout.CENTER_HORIZONTAL),居右 (RelativeLayout.ALIGN_PARENT_RIGHT)
  174. * @return
  175. */
  176. public ConvenientBanner setPageIndicatorAlign(PageIndicatorAlign align) {
  177. RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) loPageTurningPoint.getLayoutParams();
  178. layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, align == PageIndicatorAlign.ALIGN_PARENT_LEFT ? RelativeLayout.TRUE : 0);
  179. layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, align == PageIndicatorAlign.ALIGN_PARENT_RIGHT ? RelativeLayout.TRUE : 0);
  180. layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, align == PageIndicatorAlign.CENTER_HORIZONTAL ? RelativeLayout.TRUE : 0);
  181. loPageTurningPoint.setLayoutParams(layoutParams);
  182. return this;
  183. }
  184. /***
  185. * 是否开启了翻页
  186. * @return
  187. */
  188. public boolean isTurning() {
  189. return turning;
  190. }
  191. /***
  192. * 开始翻页
  193. * @param autoTurningTime 自动翻页时间
  194. * @return
  195. */
  196. public ConvenientBanner startTurning(long autoTurningTime) {
  197. //如果是正在翻页的话先停掉
  198. if(turning){
  199. stopTurning();
  200. }
  201. //设置可以翻页并开启翻页
  202. canTurn = true;
  203. this.autoTurningTime = autoTurningTime;
  204. turning = true;
  205. postDelayed(adSwitchTask, autoTurningTime);
  206. return this;
  207. }
  208. public void stopTurning() {
  209. turning = false;
  210. removeCallbacks(adSwitchTask);
  211. }
  212. /**
  213. * 自定义翻页动画效果
  214. *
  215. * @param transformer
  216. * @return
  217. */
  218. public ConvenientBanner setPageTransformer(PageTransformer transformer) {
  219. viewPager.setPageTransformer(true, transformer);
  220. return this;
  221. }
  222. /**
  223. * 设置ViewPager的滑动速度
  224. * */
  225. private void initViewPagerScroll() {
  226. try {
  227. Field mScroller = null;
  228. mScroller = ViewPager.class.getDeclaredField("mScroller");
  229. mScroller.setAccessible(true);
  230. scroller = new ViewPagerScroller(
  231. viewPager.getContext());
  232. mScroller.set(viewPager, scroller);
  233. } catch (NoSuchFieldException e) {
  234. e.printStackTrace();
  235. } catch (IllegalArgumentException e) {
  236. e.printStackTrace();
  237. } catch (IllegalAccessException e) {
  238. e.printStackTrace();
  239. }
  240. }
  241. public boolean isManualPageable() {
  242. return viewPager.isCanScroll();
  243. }
  244. public void setManualPageable(boolean manualPageable) {
  245. viewPager.setCanScroll(manualPageable);
  246. }
  247. //触碰控件的时候,翻页应该停止,离开的时候如果之前是开启了翻页的话则重新启动翻页
  248. @Override
  249. public boolean dispatchTouchEvent(MotionEvent ev) {
  250. int action = ev.getAction();
  251. if (action == MotionEvent.ACTION_UP||action == MotionEvent.ACTION_CANCEL||action == MotionEvent.ACTION_OUTSIDE) {
  252. // 开始翻页
  253. if (canTurn)startTurning(autoTurningTime);
  254. } else if (action == MotionEvent.ACTION_DOWN) {
  255. // 停止翻页
  256. if (canTurn)stopTurning();
  257. }
  258. return super.dispatchTouchEvent(ev);
  259. }
  260. //获取当前的页面index
  261. public int getCurrentItem(){
  262. if (viewPager!=null) {
  263. return viewPager.getRealItem();
  264. }
  265. return -1;
  266. }
  267. //设置当前的页面index
  268. public void setcurrentitem(int index){
  269. if (viewPager!=null) {
  270. viewPager.setCurrentItem(index);
  271. }
  272. }
  273. public ViewPager.OnPageChangeListener getOnPageChangeListener() {
  274. return onPageChangeListener;
  275. }
  276. /**
  277. * 设置翻页监听器
  278. * @param onPageChangeListener
  279. * @return
  280. */
  281. public ConvenientBanner setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) {
  282. this.onPageChangeListener = onPageChangeListener;
  283. //如果有默认的监听器(即是使用了默认的翻页指示器)则把用户设置的依附到默认的上面,否则就直接设置
  284. if(pageChangeListener != null)pageChangeListener.setOnPageChangeListener(onPageChangeListener);
  285. else viewPager.setOnPageChangeListener(onPageChangeListener);
  286. return this;
  287. }
  288. public boolean isCanLoop() {
  289. return viewPager.isCanLoop();
  290. }
  291. /**
  292. * 监听item点击
  293. * @param onItemClickListener
  294. */
  295. public ConvenientBanner setOnItemClickListener(OnItemClickListener onItemClickListener) {
  296. if (onItemClickListener == null) {
  297. viewPager.setOnItemClickListener(null);
  298. return this;
  299. }
  300. viewPager.setOnItemClickListener(onItemClickListener);
  301. return this;
  302. }
  303. /**
  304. * 设置ViewPager的滚动速度
  305. * @param scrollDuration
  306. */
  307. public void setScrollDuration(int scrollDuration){
  308. scroller.setScrollDuration(scrollDuration);
  309. }
  310. public int getScrollDuration() {
  311. return scroller.getScrollDuration();
  312. }
  313. public CBLoopViewPager getViewPager() {
  314. return viewPager;
  315. }
  316. public void setCanLoop(boolean canLoop) {
  317. this.canLoop = canLoop;
  318. viewPager.setCanLoop(canLoop);
  319. }
  320. }