Android实现轮播图片效果

本文实例为大家分享了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>

三、运行结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现图片自动轮播并且支持手势左右无限滑动

    废话不多说了,先给大家上左右无限滑动的代码了. 1.左右无限滑动 public class MainActivity extends AppCompatActivity { private static ViewPager viewPager; private RadioGroup group; //图片资源,实际项目需要从网络获取 private int[] imageIds = {R.drawable.ym1, R.drawable.ym2, R.drawable.ym3, R.drawab

  • 详解android 视频图片混合轮播实现

    循环添加视频view  图片view for (int i = 0 ;i<beansArrayList.size();i++){ if (beansArrayList.get(i).getType()==1){ videoPlayer = new NiceVideoPlayer(this); controller = new TxVideoPlayerController(this); videoPlayer.setController(controller); videoPlayer.setU

  • Android开发在轮播图片上加入点击事件的方法

    这是我加在里面的代码,用Switch(position) 来获取当前图片,在相应的图片上加入点击事件, case  0:, case 1: 时代码如下,当点击第一张图片时,想实现case 0里面的代码,但是直接直接报错,退出,当点击第二张实现case 1中的代码时却是没问题,我想知道到底哪里不对啊. 对了,这些代码是在Fragemnt内写的,点击图片时是要从一个Fragment转到一个Activity,求大神指教

  • Android实现自定义轮播图片控件示例

    要完成一个轮播图片,首先想到的应该是使用ViewPager来实现.ViewPager已经有了滑动的功能,我们只要让它自己滚动.再加上下方的小圆点就行了.所以我们本次的自定义控件就是由ViewPager和LinearLayout叠加起来组成的. 直接先上效果图: 创建一个自定义的ViewPager 先上完整的代码 package com.kcode.autoscrollviewpager.view; import android.content.Context; import android.os

  • Android实现图片轮播效果的两种方法

    大家在使用APP的过程中,经常会看到上部banner图片轮播的效果,那么今天我们就一起来学习一下,android中图片轮询的几种实现方法: 第一种:使用动画的方法实现:(代码繁琐) 这种发放需要:两个动画效果,一个布局,一个主类来实现,不多说了,来看代码吧: public class IamgeTrActivity extends Activity { /** Called when the activity is first created. */ public ImageView image

  • Android使用ViewPager加载图片和轮播视频

    作为Android基础组件之一,大家对viewpager已经很熟悉了,网上也有很多使用viewpager来加载图片的案例.但是像微信那样点击图片,可以轮播显示图片和视频的例子却没找到.正巧项目中有需求,可以就花时间写了下,现在给一下核心代码,希望对有此需求的同学们起一个抛砖引玉的作用.话不多说了,上代码: 以下是initData的代码 public void initData() { //把聊天界面的图片和视频找出来,并加到数组中,并在 //并根据传进来的position来找到视频或图片在数组中

  • Android实现Banner界面广告图片循环轮播(包括实现手动滑动循环)

    前言:经常会看到有一些app的banner界面可以实现循环播放多个广告图片和手动滑动循环.本以为单纯的ViewPager就可以实现这些功能.但是蛋疼的事情来了,ViewPager并不支持循环翻页.所以要实现循环还得需要自己去动手.自己在网上也找了些例子,本博文的Demo是结合自己找到的一些相关例子的基础上去改造,也希望对读者有用. Demo实现的效果图如下: Demo代码: 工程目录如下图: 废话不多说,上代码. 1.主Activity代码如下: package com.stevenhu.and

  • Android实现自定义轮播图片控件详解

    首先上效果图 实现原理 要完成一个轮播图片,首先想到的应该是使用ViewPager来实现.ViewPager已经有了滑动的功能,我们只要让它自己滚动.再加上下方的小圆点就行了.所以我们本次的自定义控件就是由ViewPager和LinearLayout叠加起来组成的. 一.创建一个自定义的ViewPager 先上完整的代码 package com.kcode.autoscrollviewpager.view; import android.content.Context; import andro

  • Android实现轮播图片展示效果

    本文实例为大家分享了Android轮播图片的展示,供大家参考,具体内容如下 实现逻辑 1.创建XML布局文件,使用ViewPager完成轮播图片 2.初始化ViewPager控件,然后为控件设置适配器,创建出来的适配器实现里面的四个方法 3.四个方法分别是getCount isViewFromObject instantiateItem destroyItem 4.在onCreat方法中,加载图片资源,将图片ID存在集合中,使图片能够在页面中显示,(图片之所以能够在页面中显示,是因为在适配器中的

  • Android实现图片轮播效果

    本文实例讲述了JaAndroid实现图片轮播效果代码,分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下: 首先看下一下布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_par

随机推荐