Android 实现图片标题轮播
【摘要】
先上一下效果图,这里的标题先用图片的url显示 本文写的效果是作用于Android的广告轮播控件,实现本地或网络图片播放和循环播放,线程控制避免引起过多线程不能及时回收的问题。 目前可以支持的功能有: 开...
先上一下效果图,这里的标题先用图片的url显示
本文写的效果是作用于Android的广告轮播控件,实现本地或网络图片播放和循环播放,线程控制避免引起过多线程不能及时回收的问题。
目前可以支持的功能有: 开启或关闭自动轮播功能(默认开启) 设置轮播延迟时间 自由开始或结束轮播 设置指示器或标题的位置 图片点击监听 多种banner样式
一、资源文件:
首先是布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="xyz.ncvt.viewpagerdemo.MainActivity">
<FrameLayout
android:layout_width="0dp"
android:layout_height="200dp" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="8dp"/>
<LinearLayout
android:weightSum="10"
android:background="#33000000"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="35dip">
<TextView
android:layout_weight="8"
android:id="@+id/tv_pager_title"
android:text="很长的标题。。。。。你懂我意思吧"
android:paddingLeft="8dip"
android:gravity="center_vertical"
android:textColor="@color/white"
android:layout_width="0dp" android:layout_height="35dip"/>
<!--用来动态添加轮播小点-->
<LinearLayout
android:id="@+id/lineLayout_dot"
android:layout_weight="2"
android:gravity="center|right"
android:layout_marginRight="5dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:orientation="horizontal"
android:layout_width="0dp" android:layout_height="match_parent">
</LinearLayout>
</LinearLayout>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
- 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
轮播小点资源(Drawable):这个是vector,(在Android中指的是Vector Drawable)大家可以自行搜索了解。
<vector android:height="5dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="5dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#fff" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
</vector>
- 1
- 2
- 3
- 4
创建一个图片ID资源文件,用于图片点击事件:存放在values文件夹内
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="pager_image1" type="id" />
<item name="pager_image2" type="id" />
<item name="pager_image3" type="id" />
<item name="pager_image4" type="id" />
</resources>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
二、定义一个适配器,可以是内部类也可以是单独一个类
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.List;
public class ViewPagerAdapter extends PagerAdapter {
private List<ImageView> images;
private ViewPager viewPager;
/**
* 构造方法,传入图片列表和ViewPager实例
* @param images
* @param viewPager
*/
public ViewPagerAdapter(List<ImageView> images, ViewPager viewPager){
this.images = images;
this.viewPager = viewPager;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;//返回一个无限大的值,可以 无限循环
}
/**
* 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 初始化一个条目
* @param container
* @param position 当前需要加载条目的索引
* @return
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 把position对应位置的ImageView添加到ViewPager中
ImageView iv = images.get(position % images.size());
viewPager.addView(iv);
// 把当前添加ImageView返回回去.
return iv;
}
/**
* 销毁一个条目
* position 就是当前需要被销毁的条目的索引
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 把ImageView从ViewPager中移除掉
viewPager.removeView(images.get(position % images.size()));
}
- 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
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
三、编写MainActivity:
public class MainActivity extends AppCompatActivity {
private ViewPager mViewPager;
private TextView mTvPagerTitle;
private List<ImageView> mImageList;//轮播的图片集合
private String[] mImageTitles;//标题集合
private int previousPosition = 0;//前一个被选中的position
private List<View> mDots;//小点
private boolean isStop = false;//线程是否停止
private static int PAGER_TIOME = 5000;//间隔时间
// 在values文件假下创建了pager_image_ids.xml文件,并定义了4张轮播图对应的id,用于点击事件
private int[] imgae_ids = new int[]{R.id.pager_image1,R.id.pager_image2,R.id.pager_image3,R.id.pager_image4};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
/**
* 第一步、初始化控件
*/
public void init() {
mViewPager = (ViewPager) findViewById(R.id.viewPager);
mTvPagerTitle = (TextView) findViewById(R.id.tv_pager_title);
initData();//初始化数据
initView();//初始化View,设置适配器
autoPlayView();//开启线程,自动播放
}
/**
* 第二步、初始化数据(图片、标题、点击事件)
*/
public void initData() {
//初始化标题列表和图片
mImageTitles = new String[]{"这是一个好看的标题1","这是一个优美的标题2","这是一个快乐的标题3","这是一个开心的标题4"};
int[] imageRess = new int[]{R.drawable.ncvt_wifi_head,R.drawable.img1,R.drawable.img2,R.drawable.img3};
//添加图片到图片列表里
mImageList = new ArrayList<>();
ImageView iv;
for (int i = 0; i < mImageList.size(); i++) {
iv = new ImageView(this);
iv.setBackgroundResource(imageRess[i]);//设置图片
iv.setId(imgae_ids[i]);//顺便给图片设置id
iv.setOnClickListener(new pagerImageOnClick());//设置图片点击事件
mImageList.add(iv);
}
//添加轮播点
LinearLayout linearLayoutDots = (LinearLayout) findViewById(R.id.lineLayout_dot);
mDots = addDots(linearLayoutDots,fromResToDrawable(this,R.drawable.ic_dot_normal),mImageList.size());//其中fromResToDrawable()方法是我自定义的,目的是将资源文件转成Drawable
}
//图片点击事件
private class pagerImageOnClick implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.pager_image1:
Toast.makeText(MainActivity.this, "图片1被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image2:
Toast.makeText(MainActivity.this, "图片2被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image3:
Toast.makeText(MainActivity.this, "图片3被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image4:
Toast.makeText(MainActivity.this, "图片4被点击", Toast.LENGTH_SHORT).show();
break;
}
}
}
/**
* 第三步、给PagerViw设置适配器,并实现自动轮播功能
*/
public void initView(){
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(mImageList, mViewPager);
mViewPager.setAdapter(viewPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//伪无限循环,滑到最后一张图片又从新进入第一张图片
int newPosition = position % mImageList.size();
// 把当前选中的点给切换了, 还有描述信息也切换
mTvPagerTitle.setText(mImageTitles[newPosition]);//图片下面设置显示文本
//设置轮播点
LinearLayout.LayoutParams newDotParams = (LinearLayout.LayoutParams) mDots.get(newPosition).getLayoutParams();
newDotParams.width = 24;
newDotParams.height = 24;
LinearLayout.LayoutParams oldDotParams = (LinearLayout.LayoutParams) mDots.get(previousPosition).getLayoutParams();
oldDotParams.width = 16;
oldDotParams.height = 16;
// 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
previousPosition = newPosition;
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
setFirstLocation();
}
/**
* 第四步:设置刚打开app时显示的图片和文字
*/
private void setFirstLocation() {
mTvPagerTitle.setText(mImageTitles[previousPosition]);
// 把ViewPager设置为默认选中Integer.MAX_VALUE / t2,从十几亿次开始轮播图片,达到无限循环目的;
int m = (Integer.MAX_VALUE / 2) % mImageList.size();
int currentPosition = Integer.MAX_VALUE / 2 - m;
mViewPager.setCurrentItem(currentPosition);
}
/**
* 第五步: 设置自动播放,每隔PAGER_TIOME秒换一张图片
*/
private void autoPlayView() {
//自动播放图片
new Thread(new Runnable() {
@Override
public void run() {
while (!isStop){
runOnUiThread(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
}
});
SystemClock.sleep(PAGER_TIOME);
}
}
}).start();
}
/**
* 资源图片转Drawable
* @param context
* @param resId
* @return
*/
public Drawable fromResToDrawable(Context context, int resId) {
return context.getResources().getDrawable(resId);
}
/**
* 动态添加一个点
* @param linearLayout 添加到LinearLayout布局
* @param backgount 设置
* @return
*/
public int addDot(final LinearLayout linearLayout, Drawable backgount) {
final View dot = new View(this);
LinearLayout.LayoutParams dotParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
dotParams.width = 16;
dotParams.height = 16;
dotParams.setMargins(4,0,4,0);
dot.setLayoutParams(dotParams);
dot.setBackground(backgount);
dot.setId(View.generateViewId());
linearLayout.addView(dot);
return dot.getId();
}
/**
* 添加多个轮播小点到横向线性布局
* @param linearLayout
* @param backgount
* @param number
* @return
*/
public List<View> addDots(final LinearLayout linearLayout, Drawable backgount, int number){
List<View> dots = new ArrayList<>();
for (int i = 0; i < number; i++) {
int dotId = addDot(linearLayout,backgount);
dots.add(findViewById(dotId));
}
return dots;
}
- 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
- 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
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
以上代码供大家学习参考,我优化一下代码,再上demo吧,,不懂的可以留言给我。
文章来源: chengsy.blog.csdn.net,作者:程思扬,版权归原作者所有,如需转载,请联系作者。
原文链接:chengsy.blog.csdn.net/article/details/88977822
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)