Android实现轮播图片效果

作者:棉花糖没有糖 时间:2023-07-08 02:20:24 

本文实例为大家分享了Android实现轮播图片效果的具体代码,供大家参考,具体内容如下

一、原理

首先,将这些要轮播的图片和一些文本分别放置在不同的数据集合中,程序启动的时候默认显示一组图片和文本数据,然后启动一个定时器,每隔一段时间便替换掉显示的图片和文本数据,同时加入一些动画效果,已达到轮播的特效。同时,我们也要实现手指滑动图片达到轮播的效果。

二、实现

1、程序启动界面MainActivity


public class MainActivity extends AppCompatActivity implements ImageBannerFramLayout.FramLayoutLisenner{
 private ImageBannerFramLayout mGroup;
 private int[] ids = new int[] {
     R.drawable.i1,//图片资源1
     R.drawable.i2,//图片资源2
 };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   //计算当前手机宽度
   DisplayMetrics displayMetrics = new DisplayMetrics();
   getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
   int width = displayMetrics.widthPixels;
   mGroup = (ImageBannerFramLayout) findViewById(R.id.image_group);
   mGroup.setLisenner(this);
   List<Bitmap> list = new ArrayList<>();
   for (int i = 0; i < ids.length; i++) {
     Bitmap bitmap = BitmapFactory.decodeResource(getResources(),ids[i]);
     list.add(bitmap);
   }
   mGroup.addBitmaps(list);
 }

@Override
 public void chickImageIndex(int pos) {
   Toast.makeText(this,"索引值 = " + pos,Toast.LENGTH_SHORT).show();
 }
}

2、新建包view下面新建两个类

1)新建ImageBarnnerViewGroup类继承自ViewGroup


public class ImageBarnnerViewGroup extends ViewGroup {
 private int children;//我们View Group的子视图总个数
 private int childwidth;//子视图的宽度
 private int childheight;//子视图的高度

private int x;//此时的x的值代表的是第一次按下的位置的横坐标,每一次移动过的过程中 移动之前的位置横坐标
 private int index = 0;//代表名为每张图片的索引
 private Scroller scroller;

/**
  * 利用一个单击变量开关进行判断,离开屏幕的一瞬间判断用户的操作是点击
  */
 private boolean isClick;//true的时候点击事件,false的时候不是点击事件
 private ImageBarnnerLister lister;

private ImageBarnnerViewGroupLisnner barnnerViewGroupLisnner;

public ImageBarnnerLister getLister() {
   return lister;
 }

public void setLister(ImageBarnnerLister lister) {
   this.lister = lister;
 }

public ImageBarnnerViewGroupLisnner getBarnnerViewGroupLisnner() {
   return barnnerViewGroupLisnner;
 }
 public void setBarnnerViewGroupLisnner(ImageBarnnerViewGroupLisnner barnnerViewGroupLisnner) {
   this.barnnerViewGroupLisnner = barnnerViewGroupLisnner;
 }
 public interface ImageBarnnerLister {
   void chickImageIndex(int pos);//pos代表的是我们当前的图片的具体索引值
 }
 /**
  * 实现轮播图底部圆点切换效果
  * 自定义一个继承自FragmenLayou布局,利用FragmeLayout布局特性
  */

//自动轮播
 private boolean isAuto = true;//默认情况下开启轮播
 private Timer timer = new Timer();
 private TimerTask timerTask;

@SuppressLint("HandlerLeak")
 private android.os.Handler autohandler = new android.os.Handler() {
   @Override
   public void handleMessage(Message msg) {
     switch (msg.what) {
       case 0://我们需要图片的自动轮播
         if (++index >= children) {//如果是最后一张图片,从第一张开始
           index = 0;
         }
         scrollTo(childwidth * index,0);
         barnnerViewGroupLisnner.selectImage(index);
         break;
       default:
     }
   }
 };

private void startAuto() {
   isAuto = true;

}

private void stopAuto() {
   isAuto = false;
 }

/**
  * 采用Timer,TimerTask,Handler三者结合的方式来实现自动轮播
  */

public ImageBarnnerViewGroup(Context context) {
   super(context);
   initObj();
 }

public ImageBarnnerViewGroup(Context context, AttributeSet attrs) {
   super(context, attrs);
   initObj();
 }

public ImageBarnnerViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
   super(context, attrs, defStyleAttr, defStyleRes);
   initObj();
 }

private void initObj() {
   scroller = new Scroller(getContext());

timerTask = new TimerTask() {
     @Override
     public void run() {
       if (isAuto) {//开启轮播图
         autohandler.sendEmptyMessage(0);
       }
     }
   };
   timer.schedule(timerTask,100,3000);
 }

@Override
 public void computeScroll() {
   super.computeScroll();
   if (scroller.computeScrollOffset()) {
     scrollTo(scroller.getCurrX(),0);
     invalidate();//重绘
   }
 }

@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
   //1.求出子视图的个数
   children = getChildCount();//我们可以知道自试图的个数
   if (0 == children)
   {
     setMeasuredDimension(0,0);
   } else {
     measureChildren(widthMeasureSpec, heightMeasureSpec);
     //此时我们以第一个子视图=为基准,也就是说我们的View Group
     View view = getChildAt(0);
     childwidth = view.getMeasuredWidth();
     childheight = view.getMeasuredHeight();
     int width = view.getMeasuredWidth() * children;
     setMeasuredDimension(width,childheight);
   }
   //2.测量子视图的宽度和高度
   //3.根据子视图的狂赌和高度,求出该ViewGroup的宽度和高度
 }

@Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
   return super.onInterceptTouchEvent(ev);
 }
 /**
  * 用两种方式来实现轮播图的手动轮播
  * 1,利用scrollTo,scrollBy 完成轮播图的手动轮播
  * 1,利用Scroller 对象完成轮播图的手动效果
  * @param event
  * @return
  */

@Override
 public boolean onTouchEvent(MotionEvent event) {
   switch (event.getAction()) {
     case MotionEvent.ACTION_DOWN://表示用户按下的一瞬间
       stopAuto();//停止图片轮播
       if (!scroller.isFinished()) {
         scroller.abortAnimation();
       }
       isClick = true;
       x=(int)event.getX();
       break;
     case MotionEvent.ACTION_MOVE://表示用户按下之后在屏幕上移动的过程
       int moveX = (int) event.getX();
       int distance = moveX - x;
       scrollBy(-distance,0);
       x = moveX;
       isClick = false;
       break;
     case MotionEvent.ACTION_UP://标识的是用户抬起的一瞬间
       int scrollX = getScrollX();
       index = (scrollX + childwidth / 2) / childwidth;
       if (index < 0) {  //已经滑动到了最左边
         index = 0;
       } else if (index > children - 1) {//说明已经滑动到了最右边
         index = children - 1;
       }

if (isClick) { //点击事件
         lister.chickImageIndex(index);
       } else {
         int dx = index * childwidth - scrollX;
         scroller.startScroll(scrollX,0,dx,0);
         postInvalidate();
         barnnerViewGroupLisnner.selectImage(index);
       }
       startAuto();//开启图片轮播
       break;
     default:
   }
   return true;
   //返回true的目的是告诉该View Group容器的父View 我们已经处理好了该事件
 }

@Override
 protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
   if (b) {
     int lefrMargin = 0;
     for (int j = 0; j < children; j++) {
       View view = getChildAt(j);
       view.layout(lefrMargin,0,lefrMargin + childwidth,childheight);
       lefrMargin += childwidth;
     }
   }
 }

public interface ImageBarnnerViewGroupLisnner{
   void selectImage(int index);
 }
}

2)新建ImageBannerFramLayout类继承自FrameLayout实现两个接口


public class ImageBannerFramLayout extends FrameLayout implements ImageBarnnerViewGroup.ImageBarnnerViewGroupLisnner,ImageBarnnerViewGroup.ImageBarnnerLister{

private ImageBarnnerViewGroup imageBarnnerViewGroup;
 private LinearLayout linearLayout;

private FramLayoutLisenner lisenner;

public FramLayoutLisenner getLisenner() {
   return lisenner;
 }

public void setLisenner(FramLayoutLisenner lisenner) {
   this.lisenner = lisenner;
 }

public ImageBannerFramLayout(@NonNull Context context) {
   super(context);
   initImageBarnnerViewGroup();
   initDotLinearlayout();
 }

public ImageBannerFramLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
   super(context, attrs);
   initImageBarnnerViewGroup();
   initDotLinearlayout();
 }

public ImageBannerFramLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
   super(context, attrs, defStyleAttr);
   initImageBarnnerViewGroup();
   initDotLinearlayout();
 }

public void addBitmaps(List<Bitmap> list) {
   for (int i = 0; i < list.size(); i++) {
     Bitmap bitmap = list.get(i);
     addBitmapToImageBarnnerViewGroup(bitmap);
     addDotToLinearlayout();
   }
 }

private void addDotToLinearlayout() {
   ImageView iv = new ImageView(getContext());
   LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams
       (LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.MATCH_PARENT);
   layoutParams.setMargins(5,5,5,5);
   iv.setLayoutParams(layoutParams);
   iv.setImageResource(R.drawable.dot_normal);
   linearLayout.addView(iv);
 }

private void addBitmapToImageBarnnerViewGroup(Bitmap bitmap) {
   ImageView imageView = new ImageView(getContext());
   imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
   imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
   imageView.setImageBitmap(bitmap);
   imageBarnnerViewGroup.addView(imageView);
 }

//初始化自定义图片轮播功能核心类
 private void initImageBarnnerViewGroup() {
   imageBarnnerViewGroup = new ImageBarnnerViewGroup(getContext());
   FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams
       (FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
   imageBarnnerViewGroup.setLayoutParams(layoutParams);
   imageBarnnerViewGroup.setBarnnerViewGroupLisnner(this);//将linsnner传递给Framlayout
   imageBarnnerViewGroup.setLister(this);
   addView(imageBarnnerViewGroup);
 }

//初始化底部圆点布局
 private void initDotLinearlayout() {
   linearLayout = new LinearLayout(getContext());
   FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams
       (FrameLayout.LayoutParams.MATCH_PARENT, 40);
   linearLayout.setLayoutParams(layoutParams);
   linearLayout.setOrientation(LinearLayout.HORIZONTAL);
   linearLayout.setGravity(Gravity.CENTER);

linearLayout.setBackgroundColor(Color.RED);
   addView(linearLayout);

FrameLayout.LayoutParams layoutParams1 = (LayoutParams) linearLayout.getLayoutParams();
   layoutParams.gravity = Gravity.BOTTOM;
   linearLayout.setLayoutParams(layoutParams1);
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     linearLayout.setAlpha(0.5f);
   } else {
     linearLayout.getBackground().setAlpha(100);
   }
 }

@Override
 public void selectImage(int index) {
   int count = linearLayout.getChildCount();
   for (int i = 0;i < count; i++) {
     ImageView iv = (ImageView) linearLayout.getChildAt(i);
     if (i == index) {
       iv.setImageResource(R.drawable.dot_select);
     } else {
       iv.setImageResource(R.drawable.dot_normal);
     }
   }
 }

@Override
 public void chickImageIndex(int pos) {
   lisenner.chickImageIndex(pos);
 }

public interface FramLayoutLisenner{
   void chickImageIndex(int pos);
 }
}

3、程序布局页面activity_main


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity">
 <com.example.tony.imagegroup.view.ImageBannerFramLayout
   android:id="@+id/image_group"
   android:layout_width="match_parent"
   android:layout_height="200dp">
 </com.example.tony.imagegroup.view.ImageBannerFramLayout>
</RelativeLayout>

4、新建两个drawable资源文件dot_normal.xml和dot_select.xml,实现轮播图底部小圆点

不同的是前者颜色为白色后者为黑色


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="oval">
 <solid android:color="@android:color/white"/>
 <size android:height="10dp"
   android:width="10dp"/>
</shape>

三、运行结果

Android实现轮播图片效果

来源:https://blog.csdn.net/qq_18378065/article/details/82711618

标签:Android,轮播图片
0
投稿

猜你喜欢

  • Android之在linux终端执行shell脚本直接打印当前运行app的日志的实现方法

    2021-06-12 23:41:08
  • IDEA版最新MyBatis程序配置教程详解

    2022-08-25 03:27:26
  • 在Java中按值调用和按引用调用

    2021-12-26 20:09:21
  • Android实现图片的高斯模糊(两种方式)

    2023-01-24 05:42:48
  • c#添加图片、文本水印到PDF文件

    2021-08-30 13:36:57
  • Mybatis-Plus自动填充更新操作相关字段的实现

    2022-01-14 20:43:01
  • C#实现图片上传(PC端和APP)保存及 跨域上传说明

    2022-11-10 17:05:11
  • java中抽象类和接口的相同和不同点介绍

    2021-05-30 04:53:31
  • 使用Springboot搭建OAuth2.0 Server的方法示例

    2023-01-28 07:19:16
  • Spring Boot整合Lombok的方法详解

    2023-11-22 09:06:21
  • Android判断手机是否联网及自动跳转功能(收藏版)

    2023-10-06 18:42:33
  • Java 抽象类特点总结

    2023-07-28 10:39:46
  • Android组件Glide实现图片平滑滚动效果

    2022-02-24 22:53:14
  • 使用maven运行Java Main的三种方法解析

    2021-09-24 10:09:28
  • Java AQS信号量Semaphore的使用

    2021-06-11 17:10:44
  • C#的String和StringBuilder详解

    2022-06-21 09:51:31
  • SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法

    2023-07-25 07:09:08
  • flutter实现底部导航栏

    2023-08-23 01:06:13
  • java基础之Object类

    2022-11-17 21:20:10
  • android studio实现简单的计算器小功能

    2022-07-22 17:53:26
  • asp之家 软件编程 m.aspxhome.com