构思:
明确目标:
根据录制的视频,先明确轮播图的实际效果,视频中图片定时切换的控件是实现轮播图的关键,那么根据对控件的了解,我们猜测实现这一实际效果的控件和viewpager十分相似,viewpager是一个可以滑动页面的控件,那么结合我们的实际情况进行对比,发现需要在viewpager已知的功能上实现:1、定时切换图片,2、添加图片上的文字和圆点,3、可以向左右随意滑动切换图片(viewpager在第一张图片时向右滑动不了)。4、设置图片的点击监听事件。
功能实现:
1、新建一个android项目,默认生成一个MainActivity继承自AppCompatActivity,实现方法onCreate,这一步默认会实现,你会发现默认加载了一个启动布局:activity_main.xml
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
2、我们首先开始在activity_main下写布局,需要写viewpager控件、textview控件和Linearlayout三个控件,分别放图片、文字、圆点,根据实际效果分析,他们是层叠的,所以用帧布局,布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="190dp"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="25dp"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:gravity="center_vertical"
android:background="#33000000"
>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
android:textColor="#ffffffff"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
/>
<LinearLayout
android:id="@+id/dotView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
android:layout_marginRight="30dp"
/>
</LinearLayout>
</FrameLayout>
3、初始化布局控件到MainActivity类中,代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewpager);
dotViews = findViewById(R.id.dotView);
textView = findViewById(R.id.textView);
}
4、实现viewpager放置图片,手动滑动切换图片,此时第一张图片向右是不可滑动的:
viewPager.setAdapter(new MyAdapter(imageViews));//viewPager是控件;new MyAdapter(imageViews)看成是数据,实际是自定义适配器,里面可以理解为处理图片数据的一个机制,处理好了放viewPager控件上显示图片
5、自定义MyAdapter适配器,理解成:实现图片数据处理机制,自定义MyAdapter适配器代码如下:
public class MyAdapter extends PagerAdapter {
private ArrayList arrayList;
public MyAdapter(ArrayList arrayList) {
this.arrayList = arrayList;
}
@Override
public int getCount() {
//设置可视图数量
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;//object是承载图片的控件imageView,父控件是View
}
@Override
public ObjectinstantiateItem(ViewGroup container, int position) {
//给container添加内容~图片
container.addView(arrayList.get(position %arrayList.size()));
return arrayList.get(position %arrayList.size());
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
//销毁对应位置上的object
container.removeView((View) object);
}
}
6、添加图片资源到一个int数组,R.drawable.timg, R.drawable.timg1, R.drawable.timg2,R.drawable.timg1是res/drawable文件下的图片资源,将数组转成集合传到MyAdapter适配器:
public class MainActivity extends AppCompatActivity {
private int[]imagers;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imagers =new int[]{R.drawable.timg, R.drawable.timg1, R.drawable.timg2,R.drawable.timg1};
ArrayList <ImageView > imageViews =new ArrayList <ImageView > ();
ImageView imageView;
for (int i =0; i<imagers.length;i++){
imageView =new ImageView(MainActivity.this);
imageView.setBackgroundResource(imagers[i]);
imageViews.add(imageView);
}
}
}
小结:目前viewpager控件显示图片了,可以滑动切换显示图片了。
下一目标:让图片定时切换
1、onCreate函数下开线程设置定时器,代码如下:
new Thread() {
public void run() {
boolean running =true;
while (running) {
try {
Thread.sleep(5000);//5S切换下一张图片
}catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
viewPager.setCurrentItem(viewPager.getCurrentItem() +1);//当前图片为下一张图片,即实现了图片的切换
}
});
}
}
}.start();
下一目标:实现向右滑动切换功能,代码如下:
// 把ViewPager设置为默认选中Integer.MAX_VALUE / t2,从十几亿次开始轮播图片,达到无限循环目的(那么我们开始看到的第一张图片就是第十几亿次的图片,从而达到向右滑动的目的);
int m = (Integer.MAX_VALUE /2) %imageViews.size();
int currentPosition = Integer.MAX_VALUE /2 - m;
viewPager.setCurrentItem(currentPosition);
下一目标:添加文字:
public class MainActivityextends AppCompatActivity {
private TextView textView;
private String[] textString;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
textString =new String[]{
"text1", "text2", "text3","text4"
};
textView.setText(textString[0]);//默认设置显示为:text1
//viewpager切换时,文字显示对应也完成切换
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Toast.makeText(MainActivity.this,"onPageScrolled",Toast.LENGTH_LONG).show();
}
@Override
public void onPageSelected(int position) {
//Toast.makeText(MainActivity.this,"onPageSelected",Toast.LENGTH_LONG).show();
int currentPage = position %imageViews.size();//记录切换后的当前页的index
textView.setText(textString[currentPage]);//根据当前页的index取对应的文字显示,完成图片文字的同步显示
}
@Override
public void onPageScrollStateChanged(int state) {
//Toast.makeText(MainActivity.this,"onPageScrollStateChanged",Toast.LENGTH_LONG).show();
}
});
}
}
下一目标:添加圆点:
1、将两种颜色的图片添加到项目,顾名思义,一张是显示的灰色圆点,一张是白色的(选中状态):
2、设置圆形图片切换的状态,选中时为白色,默认为灰色,新建dot.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/white_dot" android:state_enabled="true"/>
<item android:drawable="@drawable/gray_dot" android:state_enabled="false"/>
</selector>
3、实现切换页面时,小圆点切换同步显示:
public class MainActivityextends AppCompatActivity {
private LinearLayout dotViews;
private int defaultPage =0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dotViews = findViewById(R.id.dotView);
//因为图片切换时,圆点对应切换,所以图片的张数决定圆点的个数,将圆点的图片放在for循环下面生成viewpager图片张数的圆点控件View,添加到LinearLayout控件,圆点图片默认为禁止选中状态,为灰色
for (int i =0; i <imagers.length; i++){
layoutParams =new LinearLayout.LayoutParams(30, 30);//控件大小设置
dotView =new View(this);//承载显示圆点图片的控件
dotView.setBackgroundResource(R.drawable.dot);//状态切换
dotView.setEnabled(false);//禁止选中状态
dotViews.addView(dotView, layoutParams);//将控件View添加到LinearLayout
}
dotViews.getChildAt(0).setEnabled(true);//显示第一个圆点为选中状态,白色
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Toast.makeText(MainActivity.this,"onPageScrolled",Toast.LENGTH_LONG).show();
}
@Override
public void onPageSelected(int position) {
//Toast.makeText(MainActivity.this,"onPageSelected",Toast.LENGTH_LONG).show();
//ViewPager切换的过程,比如说:默认第一个圆点是选中状态为白色,对应第一个页面index=0,现在由第一个页面切换到第二个页面index=1,会触发到onPageSelected这个函数,切换的过程要实现如下代码操作
int currentPage = position %imageViews.size();
//切换后的页面,当前页index
dotViews.getChildAt(defaultPage).setEnabled(false);
//将index=0的第一个页面的圆点变成未选中状态,灰色
dotViews.getChildAt(currentPage).setEnabled(true);;
//将index=1的页面的圆点变成选中状态,白色
defaultPage = currentPage;
//记录index=1的页面为默认页面(第一个页面index=0),为了完成下一页面的切换index=2的页面为下一个切换后的页面(相当于上一个步骤(index为0和1页面的切换)的index=1)
}
@Override
public void onPageScrollStateChanged(int state) {
//Toast.makeText(MainActivity.this,"onPageScrollStateChanged",Toast.LENGTH_LONG).show();
}
});
}
小结:目前完成页面切换后小圆点切换的同步,小圆点选中的状态是白色,其余小圆点都为灰色,一次只有一个小圆点为选中状态显示为白色
下一目标:设置每一张图片的点击监听事件:
具体实现:
1、添加pages.xml文件,目的是为了添加id值:
代码:
<?xml version="1.0" encoding="utf-8"?>
<item name="pager_img1" type="id"/>
<item name="pager_img2" type="id"/>
<item name="pager_img3" type="id"/>
<item name="pager_img4" type="id"/>
<item name="pager_img5" type="id"/>
</resources>
2、因为图片显示控件是动态添加的,所以没有对应的控件ID,需要动态添加控件id,并且需要与各个图片一一对应,
public class MainActivityextends AppCompatActivity {
private int[] imagerId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imagerId=new int[]{
R.id.pager_img1,
R.id.pager_img2,
R.id.pager_img3,
R.id.pager_img4,
R.id.pager_img5
};
ImageView imageView;
for (int i =0; i <imagers.length;i++){
imageView =new ImageView(MainActivity.this);
//图片添加到ImageView 控件已经省略,上面步骤已经实现
imageView.setId(imagerId[i]);//图片控件和id同步
imageView.setOnClickListener(new pagerOnClickListener(MainActivity.this));//设置图片点击监听
imageViews.add(imageView);
}
}
}
3、设置图片点击监听事件类,代码如下,具体业务逻辑在各个case下面写,目前显示的是一个弹窗窗口:
public class pagerOnClickListener implements View.OnClickListener{
Contextm Context;
public pagerOnClickListener(Context mContext){
this.mContext=mContext;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.pager_img1:
Toast.makeText(mContext, "图片1被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_img2:
Toast.makeText(mContext, "图片2被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_img3:
Toast.makeText(mContext, "图片3被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_img4:
Toast.makeText(mContext, "图片4被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_img5:
Toast.makeText(mContext, "图片5被点击", Toast.LENGTH_SHORT).show();
break;
}
}
}