├── .gitignore ├── README.md ├── build.gradle ├── demo.gif ├── gradle.properties ├── library ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── itheima │ │ └── loopviewpager │ │ ├── LoopDotsView.java │ │ ├── LoopTitleView.java │ │ ├── LoopViewPager.java │ │ ├── anim │ │ ├── AnimStyle.java │ │ ├── FixedSpeedScroller.java │ │ └── transformer │ │ │ ├── AccordionTransformer.java │ │ │ ├── AccordionUpTransformer.java │ │ │ ├── CubeTransformer.java │ │ │ ├── CubeUpTransformer.java │ │ │ ├── LoopTransformer.java │ │ │ └── LoopVerticalTransformer.java │ │ ├── dots │ │ ├── DotCustomView.java │ │ ├── DotDefault.java │ │ ├── DotDiamondView.java │ │ ├── DotOvalView.java │ │ ├── DotStyle.java │ │ └── DotTriangleView.java │ │ └── listener │ │ ├── OnCreateItemViewListener.java │ │ └── OnItemClickListener.java │ └── res │ ├── layout │ └── hm_loopviewpager.xml │ └── values │ └── hm_attrs.xml ├── settings.gradle └── simpledemo ├── build.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── java └── com │ └── itheima │ └── simpledemo │ ├── DataFactory.java │ ├── MainActivity.java │ ├── SimpleDemo1.java │ └── SimpleDemo2.java └── res ├── layout ├── activity_main.xml ├── activity_simple_demo1.xml ├── activity_simple_demo2.xml └── item.xml ├── mipmap-xhdpi ├── a.jpg ├── b.jpg ├── c.jpg ├── d.jpg ├── dot_normal.png ├── dot_selected.png ├── e.jpg └── ic_launcher.png └── values └── strings.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | /.idea/ 3 | /build/ 4 | /gradle/ 5 | /gradlew 6 | /gradlew.bat 7 | /local.properties 8 | *.iml 9 | /*/build/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LoopViewPager 2 | Android LoopViewPager 页面轮播控件 3 | * 简 书:http://www.jianshu.com/p/f847325e8a28 4 | * CSDN:http://blog.csdn.net/mwq384807683/article/details/53691752 5 | 6 | # 运行效果 7 | ![image](demo.gif) 8 | 9 | * 爱生活,爱学习,更爱做代码的搬运工,分类查找更方便请下载黑马助手app 10 | 11 | 12 | ![黑马助手.png](http://upload-images.jianshu.io/upload_images/4037105-f777f1214328dcc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | # 添加权限 15 | ```xml 16 | 17 | 18 | 19 | 20 | ``` 21 | 22 | # 添加依赖 23 | ```xml 24 | allprojects { 25 | repositories { 26 | ... 27 | maven { url "https://jitpack.io" } 28 | } 29 | } 30 | 31 | dependencies { 32 |   compile 'com.github.open-android:LoopViewPager:2.0.0' 33 | } 34 | ``` 35 | 36 | # 可配置的属性 37 | ```xml 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | ``` 87 | # 配置说明 88 | - 1、loopTime的值应不小于1s,如果值为0,则不自动轮播; 89 | - 2、animTime的值应小于loopTime; 90 | - 3、dotWidth、dotHeight、dotRange如果没有设置,则默认值为dotSize; 91 | - 4、如果设置了dotResource、dotSelectResource,则dotShape、dotColor、dotSelectColor配置不生效; 92 | - 5、轮播调用start()方法,停止轮播调用stop()方法,start前至少设置setImgData、setImgLength、setTitleData中的其中一个; 93 | 94 | # 代码示例 95 | ###XML 96 | ```xml 97 | 104 | 105 | 113 | 114 | 121 | 122 | 128 | 129 | 130 | 131 | 132 | ``` 133 | ###Java 134 | ```java 135 | private LoopViewPager loopViewPager; 136 | 137 | @Override 138 | protected void onCreate(Bundle savedInstanceState) { 139 | super.onCreate(savedInstanceState); 140 | setContentView(R.layout.activity_simple_demo2); 141 | loopViewPager = (LoopViewPager) findViewById(R.id.lvp_pager); 142 | loopViewPager.setImgData(DataFactory.imgListString()); 143 | loopViewPager.setTitleData(DataFactory.titleListString()); 144 | loopViewPager.start(); 145 | } 146 | 147 | private List imgListString() { 148 | List imageData = new ArrayList<>(); 149 | imageData.add("http://d.hiphotos.baidu.com/image/h%3D200/sign=72b32dc4b719ebc4df787199b227cf79/58ee3d6d55fbb2fb48944ab34b4a20a44723dcd7.jpg"); 150 | imageData.add("http://pic.4j4j.cn/upload/pic/20130815/31e652fe2d.jpg"); 151 | imageData.add("http://pic.4j4j.cn/upload/pic/20130815/5e604404fe.jpg"); 152 | imageData.add("http://pic.4j4j.cn/upload/pic/20130909/681ebf9d64.jpg"); 153 | imageData.add("http://d.hiphotos.baidu.com/image/pic/item/54fbb2fb43166d22dc28839a442309f79052d265.jpg"); 154 | return imageData; 155 | } 156 | 157 | private List titleListString() { 158 | List titleData = new ArrayList<>(); 159 | titleData.add("1、在这里等着你"); 160 | titleData.add("2、在你身边"); 161 | titleData.add("3、打电话给你就是想说声“嗨”"); 162 | titleData.add("4、不介意你对我大喊大叫"); 163 | titleData.add("5、期待你总是尽全力"); 164 | return titleData; 165 | } 166 | ``` 167 | # 如何自定义 168 | ```java 169 | public class SimpleDemo2 extends AppCompatActivity { 170 | 171 | private List viewList; 172 | private LoopViewPager loopViewPager; 173 | 174 | @Override 175 | protected void onCreate(Bundle savedInstanceState) { 176 | super.onCreate(savedInstanceState); 177 | setContentView(R.layout.activity_simple_demo2); 178 | loopViewPager = (LoopViewPager) findViewById(R.id.lvp_pager); 179 | initData(); 180 | 181 | // 自定义View 182 | loopViewPager.setOnCreateItemViewListener(new OnCreateItemViewListener() { 183 | @Override 184 | public View getItemView(int position) { 185 | return viewList.get(position); 186 | } 187 | }); 188 | //处理点击事件 189 | loopViewPager.setOnItemClickListener(new OnItemClickListener() { 190 | @Override 191 | public void onItemClick(View view, int position) { 192 | Toast.makeText(SimpleDemo2.this, "position=" + position, Toast.LENGTH_SHORT).show(); 193 | } 194 | }); 195 | // 自定义动画 196 | loopViewPager.setPageTransformer(1500, new LoopVerticalTransformer() { 197 | @Override 198 | public void transformViewPage(View view, float position) { 199 | view.setPivotX(view.getMeasuredWidth() * 0.5f); 200 | view.setPivotY(position <= 0 ? view.getMeasuredHeight() : 0); 201 | view.setRotationX(-90f * position); 202 | } 203 | }); 204 | loopViewPager.setImgLength(viewList.size()); 205 | // loopViewPager.setTitleData(DataFactory.titleListString()); 206 | loopViewPager.start(); 207 | } 208 | 209 | private void initData() { 210 | viewList = new ArrayList<>(); 211 | for (int i = 1; i <= 5; i++) { 212 | View view = null; 213 | if (i == 2) { 214 | ImageView imageView = new ImageView(this); 215 | Glide.with(SimpleDemo2.this).load("http://pic.58pic.com/58pic/13/72/07/55Z58PICKka_1024.jpg").centerCrop().into(imageView); 216 | view = imageView; 217 | } else if (i == 4) { 218 | ImageView imageView = new ImageView(this); 219 | Glide.with(SimpleDemo2.this).load("http://www.bz55.com/uploads/allimg/120615/1-120615140A8.jpg").centerCrop().into(imageView); 220 | view = imageView; 221 | } else { 222 | TextView textView = new TextView(this); 223 | textView.setGravity(Gravity.CENTER); 224 | textView.setTextColor(Color.BLUE); 225 | textView.setTextSize(36); 226 | textView.setText("TextView " + i); 227 | textView.setBackgroundColor(Color.rgb(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255))); 228 | view = textView; 229 | } 230 | viewList.add(view); 231 | } 232 | } 233 | 234 | @Override 235 | protected void onDestroy() { 236 | super.onDestroy(); 237 | loopViewPager.stop(); 238 | } 239 | 240 | } 241 | ``` 242 | 243 | 244 | * 详细的使用方法在DEMO里面都演示啦,如果你觉得这个库还不错,请赏我一颗star吧~~~ 245 | 246 | * 欢迎关注微信公众号 247 | 248 | ![](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 249 | 250 | 251 | 252 | [回到顶部](#readme) 253 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:2.2.2' 7 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 8 | } 9 | } 10 | 11 | allprojects { 12 | repositories { 13 | jcenter() 14 | maven { url "https://jitpack.io" } 15 | } 16 | } 17 | 18 | task clean(type: Delete) { 19 | delete rootProject.buildDir 20 | } 21 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/demo.gif -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | apply plugin: 'com.github.dcendents.android-maven' 4 | group='com.github.open-android' 5 | 6 | android { 7 | compileSdkVersion 22 8 | buildToolsVersion "22.0.1" 9 | defaultConfig { 10 | minSdkVersion 14 11 | targetSdkVersion 22 12 | versionCode 1 13 | versionName "1.0.0" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(include: ['*.jar'], dir: 'libs') 25 | compile "com.android.support:support-v4:22.1.1" 26 | compile 'com.github.bumptech.glide:glide:3.7.0' 27 | } 28 | -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\android-sdk-windows/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/LoopDotsView.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.LinearLayout; 8 | 9 | import com.itheima.loopviewpager.dots.DotDefault; 10 | import com.itheima.loopviewpager.dots.DotDiamondView; 11 | import com.itheima.loopviewpager.dots.DotOvalView; 12 | import com.itheima.loopviewpager.dots.DotStyle; 13 | import com.itheima.loopviewpager.dots.DotTriangleView; 14 | 15 | public class LoopDotsView extends LinearLayout { 16 | 17 | private int dotSize; 18 | private int dotWidth; 19 | private int dotHeight; 20 | private int dotRange; 21 | private int dotShape; 22 | private int dotColor; 23 | private int dotSelectColor; 24 | private int dotResource; 25 | private int dotSelectResource; 26 | 27 | public LoopDotsView(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoopDotsView); 30 | dotSize = (int) a.getDimension(R.styleable.LoopDotsView_dotSize, 0); 31 | dotWidth = (int) a.getDimension(R.styleable.LoopDotsView_dotWidth, 0); 32 | dotHeight = (int) a.getDimension(R.styleable.LoopDotsView_dotHeight, 0); 33 | dotRange = (int) a.getDimension(R.styleable.LoopDotsView_dotRange, 0); 34 | dotShape = a.getInt(R.styleable.LoopDotsView_dotShape, DotDefault.dotShape); 35 | dotColor = a.getColor(R.styleable.LoopDotsView_dotColor, DotDefault.dotColor); 36 | dotSelectColor = a.getColor(R.styleable.LoopDotsView_dotSelectColor, DotDefault.dotSelectColor); 37 | dotResource = a.getResourceId(R.styleable.LoopDotsView_dotResource, 0); 38 | dotSelectResource = a.getResourceId(R.styleable.LoopDotsView_dotSelectResource, 0); 39 | a.recycle(); 40 | } 41 | 42 | public void setDotsLength(int length) { 43 | removeAllViews(); 44 | LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 45 | params.width = dotWidth > 0 ? dotWidth : dotSize; 46 | params.height = dotHeight > 0 ? dotHeight : dotSize; 47 | for (int i = 0; i < length; i++) { 48 | View dotView = null; 49 | if (dotShape == DotStyle.RECTANGLE || (dotSelectResource != 0 && dotResource != 0)) { 50 | dotView = new View(getContext()); 51 | } else if (dotShape == DotStyle.OVAL) { 52 | dotView = new DotOvalView(getContext()); 53 | } else if (dotShape == DotStyle.TRIANGLE) { 54 | dotView = new DotTriangleView(getContext()); 55 | } else if (dotShape == DotStyle.DIAMOND) { 56 | dotView = new DotDiamondView(getContext()); 57 | } 58 | if (i == 0) { 59 | params.setMargins(0, 0, 0, 0); 60 | if (dotSelectResource != 0) { 61 | dotView.setBackgroundResource(dotSelectResource); 62 | } else { 63 | dotView.setBackgroundColor(dotSelectColor); 64 | } 65 | } else { 66 | if (getOrientation() == VERTICAL) { 67 | params.setMargins(0, dotRange > 0 ? dotRange : dotSize, 0, 0); 68 | } else { 69 | params.setMargins(dotRange > 0 ? dotRange : dotSize, 0, 0, 0); 70 | } 71 | if (dotResource != 0) { 72 | dotView.setBackgroundResource(dotResource); 73 | } else { 74 | dotView.setBackgroundColor(dotColor); 75 | } 76 | } 77 | dotView.setLayoutParams(params); 78 | addView(dotView); 79 | } 80 | } 81 | 82 | public void update(int currentIndex, int oldIndex) { 83 | if (currentIndex >= 0) { 84 | if (dotSelectResource != 0) { 85 | getChildAt(currentIndex).setBackgroundResource(dotSelectResource); 86 | } else { 87 | getChildAt(currentIndex).setBackgroundColor(dotSelectColor); 88 | } 89 | } 90 | if (oldIndex >= 0) { 91 | if (dotResource != 0) { 92 | getChildAt(oldIndex).setBackgroundResource(dotResource); 93 | } else { 94 | getChildAt(oldIndex).setBackgroundColor(dotColor); 95 | } 96 | } 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/LoopTitleView.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.TextView; 6 | 7 | public class LoopTitleView extends TextView { 8 | 9 | public LoopTitleView(Context context, AttributeSet attrs) { 10 | super(context, attrs); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/LoopViewPager.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.os.Handler; 6 | import android.os.Message; 7 | import android.support.v4.view.PagerAdapter; 8 | import android.support.v4.view.ViewPager; 9 | import android.util.AttributeSet; 10 | import android.view.MotionEvent; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.FrameLayout; 14 | import android.widget.ImageView; 15 | 16 | import com.bumptech.glide.Glide; 17 | import com.itheima.loopviewpager.anim.AnimStyle; 18 | import com.itheima.loopviewpager.anim.FixedSpeedScroller; 19 | import com.itheima.loopviewpager.anim.transformer.AccordionTransformer; 20 | import com.itheima.loopviewpager.anim.transformer.AccordionUpTransformer; 21 | import com.itheima.loopviewpager.anim.transformer.CubeTransformer; 22 | import com.itheima.loopviewpager.anim.transformer.CubeUpTransformer; 23 | import com.itheima.loopviewpager.listener.OnCreateItemViewListener; 24 | import com.itheima.loopviewpager.listener.OnItemClickListener; 25 | 26 | import java.lang.reflect.Field; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | public class LoopViewPager extends FrameLayout implements View.OnTouchListener { 31 | 32 | private int loopTime; 33 | private int animTime; 34 | private int animStyle; 35 | private boolean scrollEnable; 36 | private boolean touchEnable; 37 | 38 | private ViewPager viewPager; 39 | private final int MIN_TIME = 1000; 40 | private final int CODE = 1; 41 | 42 | private List loopDotsViews; 43 | private List loopTitleViews; 44 | private int realIndex; 45 | private int showIndex; 46 | private LoopPagerAdapter loopPagerAdapter; 47 | private LoopPageChangeListener pageChangeListener; 48 | private float downX; 49 | private float downY; 50 | private long downTime; 51 | 52 | private Handler handler = new Handler() { 53 | @Override 54 | public void handleMessage(Message msg) { 55 | switch (msg.what) { 56 | case CODE: 57 | realIndex++; 58 | viewPager.setCurrentItem(realIndex); 59 | handler.sendEmptyMessageDelayed(CODE, loopTime); 60 | break; 61 | } 62 | } 63 | }; 64 | 65 | public LoopViewPager(Context context, AttributeSet attrs) { 66 | super(context, attrs); 67 | setClickable(false); 68 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoopViewPager); 69 | loopTime = a.getInt(R.styleable.LoopViewPager_loopTime, 0); 70 | animTime = a.getInt(R.styleable.LoopViewPager_animTime, 0); 71 | animStyle = a.getInt(R.styleable.LoopViewPager_animStyle, 0); 72 | scrollEnable = a.getBoolean(R.styleable.LoopViewPager_scrollEnable, true); 73 | touchEnable = a.getBoolean(R.styleable.LoopViewPager_touchEnable, true); 74 | a.recycle(); 75 | init(); 76 | } 77 | 78 | private void init() { 79 | loopDotsViews = new ArrayList<>();//轮播圆点 80 | loopTitleViews = new ArrayList<>();//轮播文本 81 | 82 | realIndex = -1;//真实的索引 83 | showIndex = -1;//展示的索引 84 | 85 | // loopTime必须大于MIN_TIME 86 | if (loopTime > 0 && loopTime < MIN_TIME) { 87 | loopTime = MIN_TIME; 88 | } 89 | // animTime必须小于loopTime 90 | if (animTime > 0 && animTime > loopTime) { 91 | animTime = loopTime; 92 | } 93 | View.inflate(getContext(), R.layout.hm_loopviewpager, this); 94 | viewPager = (ViewPager) findViewById(R.id.vp_pager); 95 | ViewPager.PageTransformer transformer = null; 96 | switch (animStyle) { 97 | case AnimStyle.ACCORDION: 98 | transformer = new AccordionTransformer(); 99 | break; 100 | case AnimStyle.ACCORDION_UP: 101 | transformer = new AccordionUpTransformer(); 102 | break; 103 | case AnimStyle.CUBE: 104 | transformer = new CubeTransformer(); 105 | break; 106 | case AnimStyle.CUBE_UP: 107 | transformer = new CubeUpTransformer(); 108 | break; 109 | } 110 | setPageTransformer(animTime, transformer); 111 | } 112 | 113 | public void setPageTransformer(ViewPager.PageTransformer transformer) { 114 | setPageTransformer(0, transformer); 115 | } 116 | 117 | public void setPageTransformer(int animTime, ViewPager.PageTransformer transformer) { 118 | try { 119 | if (animTime > 0) { 120 | Field mScroller = ViewPager.class.getDeclaredField("mScroller"); 121 | mScroller.setAccessible(true); 122 | FixedSpeedScroller scroller = new FixedSpeedScroller(getContext()); 123 | scroller.setmDuration(animTime); 124 | mScroller.set(viewPager, scroller); 125 | } 126 | } catch (Exception e) { 127 | } 128 | if (transformer != null) { 129 | viewPager.setPageTransformer(true, transformer); 130 | } 131 | } 132 | 133 | @Override 134 | public boolean onTouch(View view, MotionEvent event) { 135 | switch (event.getAction()) { 136 | case MotionEvent.ACTION_DOWN: 137 | downX = event.getX(); 138 | downY = event.getY(); 139 | downTime = System.currentTimeMillis(); 140 | if (loopTime > 0 && touchEnable) { 141 | handler.removeCallbacksAndMessages(null); 142 | } 143 | break; 144 | case MotionEvent.ACTION_UP: 145 | float x = Math.abs(event.getX() - downX); 146 | float y = Math.abs(event.getY() - downY); 147 | float t = Math.abs(System.currentTimeMillis() - downTime); 148 | if (Math.abs(event.getX() - downX) < 20 && Math.abs(event.getY() - downY) < 20 && System.currentTimeMillis() - downTime < 200) { 149 | if (onItemClickListener != null) { 150 | onItemClickListener.onItemClick(view, realIndex); 151 | } 152 | } 153 | if (loopTime > 0 && touchEnable) { 154 | handler.sendEmptyMessageDelayed(CODE, loopTime); 155 | } 156 | break; 157 | } 158 | return super.onTouchEvent(event); 159 | } 160 | 161 | @Override 162 | public boolean onInterceptTouchEvent(MotionEvent ev) { 163 | if (scrollEnable) { 164 | 165 | return super.onInterceptTouchEvent(ev); 166 | } else { 167 | return true; 168 | } 169 | } 170 | 171 | private class LoopPagerAdapter extends PagerAdapter { 172 | 173 | @Override 174 | public int getCount() { 175 | return imgLength > 0 ? Integer.MAX_VALUE : 0; 176 | } 177 | 178 | @Override 179 | public boolean isViewFromObject(View view, Object object) { 180 | return view == object; 181 | } 182 | 183 | @Override 184 | public Object instantiateItem(ViewGroup container, int position) { 185 | View view = getDefaultItemView(position % imgLength); 186 | view.setClickable(false); 187 | container.addView(view); 188 | return view; 189 | } 190 | 191 | @Override 192 | public void destroyItem(ViewGroup container, int position, Object object) { 193 | container.removeView((View) object); 194 | } 195 | 196 | } 197 | 198 | private class LoopPageChangeListener implements ViewPager.OnPageChangeListener { 199 | 200 | @Override 201 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 202 | } 203 | 204 | @Override 205 | public void onPageSelected(int position) { 206 | int currentIndex = position % imgLength; 207 | if (loopDotsViews.size() > 0 && imgLength > 0) { 208 | for (LoopDotsView loopDotsView : loopDotsViews) { 209 | loopDotsView.update(currentIndex, showIndex); 210 | } 211 | } 212 | if (loopTitleViews.size() > 0 && titleLength > 0) { 213 | for (LoopTitleView loopTitleView : loopTitleViews) { 214 | if (titleData instanceof List) { 215 | loopTitleView.setText("" + ((List) titleData).get(currentIndex)); 216 | } else if (titleData instanceof String[]) { 217 | loopTitleView.setText("" + ((String[]) titleData)[currentIndex]); 218 | } 219 | } 220 | } 221 | realIndex = position; 222 | showIndex = currentIndex; 223 | } 224 | 225 | @Override 226 | public void onPageScrollStateChanged(int state) { 227 | } 228 | 229 | } 230 | 231 | private View getDefaultItemView(final int currentIndex) { 232 | View view = null; 233 | if (onCreateItemViewListener != null) { 234 | view = onCreateItemViewListener.getItemView(currentIndex); 235 | } 236 | if (view == null) { 237 | view = new ImageView(getContext()); 238 | if (imgData instanceof List) { 239 | Glide.with(getContext()).load(((List) imgData).get(currentIndex)).centerCrop().into((ImageView) view); 240 | } else if (imgData instanceof Integer[]) { 241 | Glide.with(getContext()).load(((Integer[]) imgData)[currentIndex]).centerCrop().into((ImageView) view); 242 | } else if (imgData instanceof String[]) { 243 | Glide.with(getContext()).load(((String[]) imgData)[currentIndex]).centerCrop().into((ImageView) view); 244 | } 245 | } 246 | return view; 247 | } 248 | 249 | public void start() { 250 | if (imgLength == 0 && titleLength == 0) { 251 | throw new IllegalArgumentException(); 252 | } 253 | loopDotsViews.clear(); 254 | loopTitleViews.clear(); 255 | getLoopChild(this); 256 | realIndex = 1000 * imgLength; 257 | showIndex = -1; 258 | if (pageChangeListener == null) { 259 | pageChangeListener = new LoopPageChangeListener(); 260 | viewPager.setOnPageChangeListener(pageChangeListener); 261 | } 262 | if (loopPagerAdapter == null) { 263 | loopPagerAdapter = new LoopPagerAdapter(); 264 | viewPager.setAdapter(loopPagerAdapter); 265 | } else { 266 | loopPagerAdapter.notifyDataSetChanged(); 267 | } 268 | viewPager.setOnTouchListener(this); 269 | viewPager.setCurrentItem(realIndex); 270 | handler.removeCallbacksAndMessages(null); 271 | if (loopTime > 0) { 272 | handler.sendEmptyMessageDelayed(CODE, loopTime); 273 | } 274 | } 275 | 276 | public void stop() { 277 | clear(); 278 | if (handler != null) { 279 | handler.removeCallbacksAndMessages(null); 280 | } 281 | } 282 | 283 | private void getLoopChild(ViewGroup viewGroup) { 284 | for (int i = 0; i < viewGroup.getChildCount(); i++) { 285 | View view = viewGroup.getChildAt(i); 286 | if (view instanceof LoopDotsView) { 287 | LoopDotsView loopDotsView = (LoopDotsView) view; 288 | loopDotsView.setDotsLength(imgLength); 289 | loopDotsViews.add(loopDotsView); 290 | } else if (view instanceof LoopTitleView) { 291 | LoopTitleView loopTitleView = (LoopTitleView) view; 292 | loopTitleViews.add(loopTitleView); 293 | } else if (view instanceof ViewGroup) { 294 | getLoopChild((ViewGroup) view); 295 | } 296 | } 297 | } 298 | 299 | private T imgData; 300 | private T titleData; 301 | private int imgLength; 302 | private int titleLength; 303 | 304 | public LoopViewPager setImgData(T imgData) { 305 | this.imgData = imgData; 306 | this.imgLength = 0; 307 | if (imgData instanceof List) { 308 | this.imgLength = ((List) imgData).size(); 309 | } else { 310 | if (imgData instanceof Integer[]) { 311 | this.imgLength = ((Integer[]) imgData).length; 312 | } else if (imgData instanceof String[]) { 313 | this.imgLength = ((String[]) imgData).length; 314 | } 315 | } 316 | if (imgLength > 0) 317 | return this; 318 | else { 319 | throw new IllegalArgumentException(); 320 | } 321 | } 322 | 323 | public LoopViewPager setTitleData(T titleData) { 324 | this.titleData = titleData; 325 | this.titleLength = 0; 326 | if (titleData instanceof List) { 327 | this.titleLength = ((List) titleData).size(); 328 | } else if (titleData instanceof String[]) { 329 | this.titleLength = ((String[]) titleData).length; 330 | } 331 | if (titleLength > 0) { 332 | if (imgData == null) { 333 | imgLength = titleLength; 334 | } 335 | return this; 336 | } else 337 | throw new IllegalArgumentException(); 338 | } 339 | 340 | public void setImgLength(int imgLength) { 341 | this.imgLength = imgLength; 342 | } 343 | 344 | public void clear() { 345 | imgData = null; 346 | titleData = null; 347 | imgLength = 0; 348 | titleLength = 0; 349 | } 350 | 351 | /** 352 | * 条目创建监听 353 | */ 354 | private OnCreateItemViewListener onCreateItemViewListener; 355 | 356 | public void setOnCreateItemViewListener(OnCreateItemViewListener onCreateItemViewListener) { 357 | this.onCreateItemViewListener = onCreateItemViewListener; 358 | } 359 | 360 | /** 361 | * 条目点击监听 362 | */ 363 | private OnItemClickListener onItemClickListener; 364 | 365 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) { 366 | this.onItemClickListener = onItemClickListener; 367 | } 368 | 369 | } 370 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/AnimStyle.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim; 2 | 3 | public interface AnimStyle { 4 | 5 | int ACCORDION = 1; 6 | int ACCORDION_UP = 2; 7 | int CUBE = 3; 8 | int CUBE_UP = 4; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/FixedSpeedScroller.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim; 2 | 3 | import android.content.Context; 4 | import android.widget.Scroller; 5 | 6 | public class FixedSpeedScroller extends Scroller { 7 | 8 | private int mDuration; 9 | 10 | public void setmDuration(int mDuration) { 11 | this.mDuration = mDuration; 12 | } 13 | 14 | public FixedSpeedScroller(Context context) { 15 | super(context); 16 | } 17 | 18 | @Override 19 | public void startScroll(int startX, int startY, int dx, int dy, int duration) { 20 | super.startScroll(startX, startY, dx, dy, mDuration); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/transformer/AccordionTransformer.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim.transformer; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 折叠 7 | */ 8 | public class AccordionTransformer extends LoopTransformer { 9 | 10 | @Override 11 | public void transformPage(View view, float position) { 12 | view.setPivotX(position <= 0 ? view.getMeasuredWidth() : 0); 13 | view.setScaleX(position <= 0 ? 1f + position : 1f - position); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/transformer/AccordionUpTransformer.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim.transformer; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 折叠 7 | */ 8 | public class AccordionUpTransformer extends LoopVerticalTransformer { 9 | 10 | @Override 11 | public void transformViewPage(View view, float position) { 12 | view.setPivotY(position <= 0 ? view.getMeasuredHeight() : 0); 13 | view.setScaleY(position <= 0 ? 1f + position : 1f - position); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/transformer/CubeTransformer.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim.transformer; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 立方体 7 | */ 8 | public class CubeTransformer extends LoopTransformer { 9 | 10 | @Override 11 | public void transformPage(View view, float position) { 12 | view.setPivotX(position <= 0 ? view.getMeasuredWidth() : 0); 13 | view.setPivotY(view.getMeasuredHeight() * 0.5f); 14 | view.setRotationY(90f * position); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/transformer/CubeUpTransformer.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim.transformer; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 立方体 7 | */ 8 | public class CubeUpTransformer extends LoopVerticalTransformer { 9 | 10 | @Override 11 | public void transformViewPage(View view, float position) { 12 | view.setPivotX(view.getMeasuredWidth() * 0.5f); 13 | view.setPivotY(position <= 0 ? view.getMeasuredHeight() : 0); 14 | view.setRotationX(-90f * position); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/transformer/LoopTransformer.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim.transformer; 2 | 3 | import android.support.v4.view.ViewPager; 4 | 5 | public abstract class LoopTransformer implements ViewPager.PageTransformer { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/anim/transformer/LoopVerticalTransformer.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.anim.transformer; 2 | 3 | import android.view.View; 4 | 5 | public abstract class LoopVerticalTransformer extends LoopTransformer { 6 | 7 | @Override 8 | public void transformPage(View view, float position) { 9 | transformViewPage(view, position); 10 | if (position < -1) { 11 | view.setAlpha(0); 12 | } else if (position <= 1) { 13 | view.setAlpha(1); 14 | view.setTranslationX(-position * view.getMeasuredWidth()); 15 | view.setTranslationY(position * view.getMeasuredHeight()); 16 | } else { 17 | view.setAlpha(0); 18 | } 19 | } 20 | 21 | public abstract void transformViewPage(View view, float position); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/dots/DotCustomView.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.dots; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.PorterDuff; 8 | import android.graphics.PorterDuffXfermode; 9 | import android.view.View; 10 | 11 | public abstract class DotCustomView extends View { 12 | 13 | private int color; 14 | 15 | public DotCustomView(Context context) { 16 | super(context); 17 | } 18 | 19 | @Override 20 | protected void onDraw(Canvas canvas) { 21 | super.onDraw(canvas); 22 | Paint paint = new Paint(); 23 | paint.setAntiAlias(true); 24 | paint.setColor(color); 25 | customDraw(canvas, paint); 26 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 27 | canvas.drawColor(Color.TRANSPARENT); 28 | } 29 | 30 | @Override 31 | public void setBackgroundColor(int color) { 32 | this.color = color; 33 | invalidate(); 34 | } 35 | 36 | public abstract void customDraw(Canvas canvas, Paint paint); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/dots/DotDefault.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.dots; 2 | 3 | public interface DotDefault { 4 | 5 | int dotShape = DotStyle.RECTANGLE; 6 | int dotColor = 0x55000000; 7 | int dotSelectColor = 0xFFFFFFFF; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/dots/DotDiamondView.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.dots; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.Path; 7 | 8 | public class DotDiamondView extends DotCustomView { 9 | 10 | public DotDiamondView(Context context) { 11 | super(context); 12 | } 13 | 14 | @Override 15 | public void customDraw(Canvas canvas, Paint paint) { 16 | Path path = new Path(); 17 | path.moveTo(getWidth() / 2, 0); 18 | path.lineTo(0, getHeight() / 2); 19 | path.lineTo(getWidth() / 2, getHeight()); 20 | path.lineTo(getWidth(), getHeight() / 2); 21 | path.lineTo(getWidth() / 2, 0); 22 | canvas.drawPath(path, paint); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/dots/DotOvalView.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.dots; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.RectF; 7 | 8 | public class DotOvalView extends DotCustomView { 9 | 10 | public DotOvalView(Context context) { 11 | super(context); 12 | } 13 | 14 | @Override 15 | public void customDraw(Canvas canvas, Paint paint) { 16 | canvas.drawOval(new RectF(0, 0, getWidth(), getHeight()), paint); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/dots/DotStyle.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.dots; 2 | 3 | public interface DotStyle { 4 | 5 | int RECTANGLE = 1; 6 | int OVAL = 2; 7 | int TRIANGLE = 3; 8 | int DIAMOND = 4; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/dots/DotTriangleView.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.dots; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.Path; 7 | 8 | public class DotTriangleView extends DotCustomView { 9 | 10 | public DotTriangleView(Context context) { 11 | super(context); 12 | } 13 | 14 | @Override 15 | public void customDraw(Canvas canvas, Paint paint) { 16 | Path path = new Path(); 17 | path.moveTo(getWidth() / 2, 0); 18 | path.lineTo(0, getHeight()); 19 | path.lineTo(getWidth(), getHeight()); 20 | path.lineTo(getWidth() / 2, 0); 21 | canvas.drawPath(path, paint); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/listener/OnCreateItemViewListener.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.listener; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 条目创建监听 7 | */ 8 | public interface OnCreateItemViewListener { 9 | 10 | View getItemView(int position); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /library/src/main/java/com/itheima/loopviewpager/listener/OnItemClickListener.java: -------------------------------------------------------------------------------- 1 | package com.itheima.loopviewpager.listener; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 条目点击监听 7 | */ 8 | public interface OnItemClickListener { 9 | 10 | void onItemClick(View view, int position); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /library/src/main/res/layout/hm_loopviewpager.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /library/src/main/res/values/hm_attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':simpledemo',':library' 2 | -------------------------------------------------------------------------------- /simpledemo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "22.0.1" 6 | defaultConfig { 7 | applicationId "com.itheima.loopviewpager" 8 | minSdkVersion 14 9 | targetSdkVersion 22 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(include: ['*.jar'], dir: 'libs') 23 | compile 'com.android.support:appcompat-v7:22.1.1' 24 | // compile 'com.github.open-android:loopviewpager:1.0.0' 25 | // compile 'com.github.open-android:LoopViewPager:1.0.1' 26 | compile project(':library') 27 | } 28 | -------------------------------------------------------------------------------- /simpledemo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\android-sdk-windows/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /simpledemo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /simpledemo/src/main/java/com/itheima/simpledemo/DataFactory.java: -------------------------------------------------------------------------------- 1 | package com.itheima.simpledemo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class DataFactory { 7 | 8 | /** 9 | * 图片String集合 10 | */ 11 | public static List imgListString() { 12 | List imageData = new ArrayList<>(); 13 | imageData.add("http://d.hiphotos.baidu.com/image/h%3D200/sign=72b32dc4b719ebc4df787199b227cf79/58ee3d6d55fbb2fb48944ab34b4a20a44723dcd7.jpg"); 14 | imageData.add("http://pic.4j4j.cn/upload/pic/20130815/31e652fe2d.jpg"); 15 | imageData.add("http://pic.4j4j.cn/upload/pic/20130815/5e604404fe.jpg"); 16 | imageData.add("http://pic.4j4j.cn/upload/pic/20130909/681ebf9d64.jpg"); 17 | imageData.add("http://d.hiphotos.baidu.com/image/pic/item/54fbb2fb43166d22dc28839a442309f79052d265.jpg"); 18 | return imageData; 19 | } 20 | 21 | /** 22 | * 图片String数组 23 | */ 24 | public static String[] imgArrayString() { 25 | String[] imageData = new String[]{ 26 | "http://d.hiphotos.baidu.com/image/h%3D200/sign=72b32dc4b719ebc4df787199b227cf79/58ee3d6d55fbb2fb48944ab34b4a20a44723dcd7.jpg", 27 | "http://pic.4j4j.cn/upload/pic/20130815/31e652fe2d.jpg", 28 | "http://pic.4j4j.cn/upload/pic/20130815/5e604404fe.jpg", 29 | "http://pic.4j4j.cn/upload/pic/20130909/681ebf9d64.jpg", 30 | "http://d.hiphotos.baidu.com/image/pic/item/54fbb2fb43166d22dc28839a442309f79052d265.jpg", 31 | }; 32 | return imageData; 33 | } 34 | 35 | /** 36 | * 图片Integer集合 37 | */ 38 | public static List imgListInt() { 39 | List imageData = new ArrayList<>(); 40 | imageData.add(R.mipmap.a); 41 | imageData.add(R.mipmap.b); 42 | imageData.add(R.mipmap.c); 43 | imageData.add(R.mipmap.d); 44 | imageData.add(R.mipmap.e); 45 | return imageData; 46 | } 47 | 48 | /** 49 | * 图片Integer数组 50 | */ 51 | public static Integer[] imgArrayInt() { 52 | Integer[] imageData = new Integer[]{ 53 | R.mipmap.a, 54 | R.mipmap.b, 55 | R.mipmap.c, 56 | R.mipmap.d, 57 | R.mipmap.e 58 | }; 59 | return imageData; 60 | } 61 | 62 | /** 63 | * 标题String集合 64 | */ 65 | public static List titleListString() { 66 | List titleData = new ArrayList<>(); 67 | titleData.add("1、在这里等着你"); 68 | titleData.add("2、在你身边"); 69 | titleData.add("3、打电话给你就是想说声“嗨”"); 70 | titleData.add("4、不介意你对我大喊大叫"); 71 | titleData.add("5、期待你总是尽全力"); 72 | return titleData; 73 | } 74 | 75 | /** 76 | * 标题String数组 77 | */ 78 | public static String[] titleArrayString() { 79 | String[] titleData = new String[]{ 80 | "1、在这里等着你", 81 | "2、在你身边", 82 | "3、打电话给你就是想说声“嗨”", 83 | "4、不介意你对我大喊大叫", 84 | "5、期待你总是尽全力", 85 | }; 86 | return titleData; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /simpledemo/src/main/java/com/itheima/simpledemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.itheima.simpledemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.AdapterView; 10 | import android.widget.BaseAdapter; 11 | import android.widget.ListView; 12 | import android.widget.TextView; 13 | 14 | public class MainActivity extends AppCompatActivity { 15 | 16 | private Class[] classes = {SimpleDemo1.class, SimpleDemo2.class}; 17 | private String[] names = {"1、如何使用", "2、如何自定义"}; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | ListView listView = (ListView) findViewById(R.id.lv_list); 24 | listView.setAdapter(new BaseAdapter() { 25 | @Override 26 | public int getCount() { 27 | return classes.length; 28 | } 29 | 30 | @Override 31 | public Object getItem(int i) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public long getItemId(int i) { 37 | return 0; 38 | } 39 | 40 | @Override 41 | public View getView(int i, View view, ViewGroup viewGroup) { 42 | TextView textView = (TextView) LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false); 43 | textView.setText(names[i]); 44 | return textView; 45 | } 46 | }); 47 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 48 | @Override 49 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 50 | startActivity(new Intent(MainActivity.this, classes[i])); 51 | } 52 | }); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /simpledemo/src/main/java/com/itheima/simpledemo/SimpleDemo1.java: -------------------------------------------------------------------------------- 1 | package com.itheima.simpledemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | import com.itheima.loopviewpager.LoopViewPager; 7 | 8 | public class SimpleDemo1 extends AppCompatActivity { 9 | 10 | private LoopViewPager loopViewPager; 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_simple_demo1); 16 | loopViewPager = (LoopViewPager) findViewById(R.id.lvp_pager); 17 | loopViewPager.setImgData(DataFactory.imgListString()); 18 | loopViewPager.setTitleData(DataFactory.titleListString()); 19 | loopViewPager.start(); 20 | } 21 | 22 | @Override 23 | protected void onDestroy() { 24 | super.onDestroy(); 25 | loopViewPager.stop(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /simpledemo/src/main/java/com/itheima/simpledemo/SimpleDemo2.java: -------------------------------------------------------------------------------- 1 | package com.itheima.simpledemo; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | import android.widget.Toast; 11 | 12 | import com.bumptech.glide.Glide; 13 | import com.itheima.loopviewpager.LoopViewPager; 14 | import com.itheima.loopviewpager.anim.transformer.LoopTransformer; 15 | import com.itheima.loopviewpager.anim.transformer.LoopVerticalTransformer; 16 | import com.itheima.loopviewpager.listener.OnCreateItemViewListener; 17 | import com.itheima.loopviewpager.listener.OnItemClickListener; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.Random; 22 | 23 | public class SimpleDemo2 extends AppCompatActivity { 24 | 25 | private List viewList; 26 | private LoopViewPager loopViewPager; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_simple_demo2); 32 | loopViewPager = (LoopViewPager) findViewById(R.id.lvp_pager); 33 | initData(); 34 | 35 | // 自定义View 36 | loopViewPager.setOnCreateItemViewListener(new OnCreateItemViewListener() { 37 | @Override 38 | public View getItemView(int position) { 39 | return viewList.get(position); 40 | } 41 | }); 42 | //处理点击事件 43 | loopViewPager.setOnItemClickListener(new OnItemClickListener() { 44 | @Override 45 | public void onItemClick(View view, int position) { 46 | Toast.makeText(SimpleDemo2.this, "position=" + position, Toast.LENGTH_SHORT).show(); 47 | } 48 | }); 49 | // 自定义动画 50 | loopViewPager.setPageTransformer(1500, new LoopVerticalTransformer() { 51 | @Override 52 | public void transformViewPage(View view, float position) { 53 | view.setPivotX(view.getMeasuredWidth() * 0.5f); 54 | view.setPivotY(position <= 0 ? view.getMeasuredHeight() : 0); 55 | view.setRotationX(-90f * position); 56 | } 57 | }); 58 | loopViewPager.setImgLength(viewList.size()); 59 | // loopViewPager.setTitleData(DataFactory.titleListString()); 60 | loopViewPager.start(); 61 | } 62 | 63 | private void initData() { 64 | viewList = new ArrayList<>(); 65 | for (int i = 1; i <= 5; i++) { 66 | View view = null; 67 | if (i == 2) { 68 | ImageView imageView = new ImageView(this); 69 | Glide.with(SimpleDemo2.this).load("http://pic.58pic.com/58pic/13/72/07/55Z58PICKka_1024.jpg").centerCrop().into(imageView); 70 | view = imageView; 71 | } else if (i == 4) { 72 | ImageView imageView = new ImageView(this); 73 | Glide.with(SimpleDemo2.this).load("http://www.bz55.com/uploads/allimg/120615/1-120615140A8.jpg").centerCrop().into(imageView); 74 | view = imageView; 75 | } else { 76 | TextView textView = new TextView(this); 77 | textView.setGravity(Gravity.CENTER); 78 | textView.setTextColor(Color.BLUE); 79 | textView.setTextSize(36); 80 | textView.setText("TextView " + i); 81 | textView.setBackgroundColor(Color.rgb(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255))); 82 | view = textView; 83 | } 84 | viewList.add(view); 85 | } 86 | } 87 | 88 | @Override 89 | protected void onDestroy() { 90 | super.onDestroy(); 91 | loopViewPager.stop(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /simpledemo/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /simpledemo/src/main/res/layout/activity_simple_demo1.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 24 | 25 | 32 | 33 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /simpledemo/src/main/res/layout/activity_simple_demo2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 23 | 24 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /simpledemo/src/main/res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/a.jpg -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/b.jpg -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/c.jpg -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/d.jpg -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/dot_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/dot_normal.png -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/dot_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/dot_selected.png -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/e.jpg -------------------------------------------------------------------------------- /simpledemo/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-android/LoopViewPager/29ad96d4aa88e07bc61aff8d59c0fe45a0147500/simpledemo/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /simpledemo/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | LoopViewPager 4 | 5 | 6 | --------------------------------------------------------------------------------