自定义View实例(二)广告轮播

学习使用自定义View实现一个可以自动无限循环轮播的广告轮播图,效果图如下:
在这里插入图片描述

具体实现思路:

  1. 首先利用view pager实现图片轮播
  2. 使用handle发送延时消息来实现图片自动播放
  3. 通过设置viewpager的item数量为Integer.MAX_VALUE,然后在adapter中获取当前位置item的方法里对position和我们实际的item数量进行求余来获取当前的item,以此达到无限循环滚动的效果

完整代码如下:

package com.car.customview;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.car.customview.adapter.MyPageAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by pulian on 2019/2/26.
 * 无限循环自动轮播的广告条
 * 自动循环的方式:1.Timer 2.开子线程  无限循环 3.ClockManager 4.handler发送延时消息
 */

public class Banner extends AppCompatActivity {
    private final static int MSG_CHANGE_PAGE = 0;
    //图片切换时间
    private final long interval = 2000;
    private ViewPager viewPager;
    //指示点容器
    private LinearLayout pointGroup;
    private TextView imgDesc;
    private List<ImageView> imgList;
    private MyPageAdapter adapter;
    //上一次view pager item的位置
    private int lastPagePosition = 0;
    private boolean isRunning = false;
    //图片资源
    private final int[] imgIds = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e};
    //文字资源
    private final String[] msgs = {"巩俐不低俗,我就不能低俗", "朴树又回来了,引发万人大合唱",
            "揭秘北京电影如何升级", "乐视TV大放送", "屌丝的逆袭"};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_banner);
        initView();
        initData();
        isRunning = true;
        handler.sendEmptyMessageDelayed(MSG_CHANGE_PAGE, interval);

    }
    
    private void initData() {
        imgList = new ArrayList<>();
        imgDesc.setText(msgs[0]);
        for (int i = 0; i < imgIds.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(imgIds[i]);
            imgList.add(imageView);
            //添加指示点
            ImageView point = new ImageView(this);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
            params.rightMargin = 20;
            point.setLayoutParams(params);
            point.setBackgroundResource(R.drawable.point_bg);
            if (i == 0) {
                point.setEnabled(true);
            } else {
                point.setEnabled(false);
            }
            pointGroup.addView(point);
        }
        adapter = new MyPageAdapter(imgList);
        viewPager.setAdapter(adapter);
        //无限循环播放初始化第一个位置
        viewPager.setCurrentItem(Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2) % imgList.size());
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
            	//对position求余换算出实际的位置
                position = position % imgList.size();
                imgDesc.setText(msgs[position]);
                //改变指示点的状态
                pointGroup.getChildAt(position).setEnabled(true);
                pointGroup.getChildAt(lastPagePosition).setEnabled(false);
                lastPagePosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    private void initView() {
        viewPager = findViewById(R.id.view_pager);
        pointGroup = findViewById(R.id.point_group);
        imgDesc = findViewById(R.id.msg);
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_CHANGE_PAGE:
                    viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
                    if (isRunning){
                        handler.sendEmptyMessageDelayed(MSG_CHANGE_PAGE, interval);
                    }
                    break;
            }
        }
    };

    @Override
    protected void onDestroy() {
        isRunning = false;
        super.onDestroy();
    }
}

viewpager的adapter代码:

package com.car.customview.adapter;

import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.List;

public class MyPageAdapter extends PagerAdapter {
    private List<ImageView> mList;
    private int count;

    public MyPageAdapter(List<ImageView> list) {
        mList = list;
        count = mList.size();
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView(mList.get(position % count));
        object = null;
    }
    /*
        获得相应位置上的view
     */
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        container.addView(mList.get(position % count));
        return mList.get(position % count);
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="200dp">

    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignBottom="@id/view_pager"
        android:background="#33000000">

        <TextView
            android:id="@+id/msg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/app_name"
            android:textColor="@android:color/white"
            android:textSize="18sp"/>
        <LinearLayout
            android:id="@+id/point_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="horizontal">

        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

用到的drawable文件
两种状态的指示点

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

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

</shape>

指示点选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <item android:drawable="@drawable/point_normal"  android:state_enabled="false"/>
    <item android:drawable="@drawable/point_focused"  android:state_enabled="true"/>
</selector>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值