Android首页无限轮播功能

最近工作不是很忙,也跟大神学习下总结一些小的技术点:

对于一个App几乎都有Banner广告功能,也就是我们常见的轮播图, 当然目前市场第三方框架已经非常成熟了,尤其是youth5201314/banner 这里有github地址也可以学习下:

https://github.com/youth5201314/banner.git

那么下面给大家介绍我的一些总结: 首先分析下轮播图的设计

  1. 多张轮播图定时效果
  2. 指示点以及每张图片的文字说明
  3. 实现无限轮播,可滑动,图片点击事件

开始布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.yangziling.carousel.MainActivity">
<!--轮播图-->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp">
        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
            
        <!--指示点和图片标题-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="35dip"
            android:layout_gravity="bottom"
            android:background="#33000000"
            android:gravity="center"
            android:orientation="vertical">
            <!--图片配文-->
            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="图片标题"
                android:textColor="@android:color/white" />
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="3dip"
                android:orientation="horizontal" >
            <!--指示点-->
                <View
                    android:id="@+id/dot_0"
                    style="@style/view_attr"
                    android:background="@drawable/dot_focused"/>
                <View
                    android:id="@+id/dot_1"
                    style="@style/view_attr"
                    android:background="@drawable/dot_normal"/>
                <View
                    android:id="@+id/dot_2"
                    style="@style/view_attr"
                    android:background="@drawable/dot_normal"/>
                <View
                    android:id="@+id/dot_3"
                    style="@style/view_attr"
                    android:background="@drawable/dot_normal"/>
                <View
                    android:id="@+id/dot_4"
                    style="@style/view_attr"
                    android:background="@drawable/dot_normal"/>
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>
</RelativeLayout>
复制代码

布局中抽取的view属性:

<style name="view_attr">
    <item name="android:layout_width">5dp</item>
    <item name="android:layout_height">5dp</item>
    <item name="android:layout_marginLeft">5dp</item>
    <item name="android:layout_marginRight">5dp</item>
</style>
复制代码

这里我展示的一些图片是在本地的,通过网络框架加载图片原理也是一样的。

这里直接给大家贴出来核心代码:

public class MainActivity extends AppCompatActivity {
    private ViewPager mMyViewPaper;
    private List<ImageView> images;
    private List<View> dots;
    private int currentItem;
    private TextView title;
    private MyAdapter adapter;
    //当前显示图片的位置
    private int localPosition = 0;
    //图片的id
    private int[] imageIds =
        new int[]{R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e};
    //图片的标题
    private String[] titles =
        new String[]{"蓝天白云", "青山绿水", "枯藤老树", "人间仙境", "岛屿大树"};
    private TimerTask mTimerTask;
    //创建一个定时器
    private final Timer timer = new Timer();
    private ImageView mImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMyViewPaper = (ViewPager) findViewById(R.id.vp);

        //显示的图片
        images = new ArrayList<>();
        for (int i = 0; i < imageIds.length; i++) {
            mImageView = new ImageView(this);
            mImageView.setBackgroundResource(imageIds[i]);
            images.add(mImageView);
        }
        //指示点
        dots = new ArrayList<>();
        dots.add(findViewById(R.id.dot_0));
        dots.add(findViewById(R.id.dot_1));
        dots.add(findViewById(R.id.dot_2));
        dots.add(findViewById(R.id.dot_3));
        dots.add(findViewById(R.id.dot_4));

        title = (TextView) findViewById(R.id.title);
        title.setText(titles[0]);

        adapter = new MyAdapter(MainActivity.this, images);
        mMyViewPaper.setAdapter(adapter);
        mMyViewPaper.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            position = position % images.size();
            title.setText(titles[position]);
            dots.get(position).setBackgroundResource(R.drawable.dot_focused);
            dots.get(localPosition).setBackgroundResource(R.drawable.dot_normal);

            localPosition = position;
            currentItem = position;
        }
        /**
         * 页面滑动时回调
         */
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }
        /**
         * 当ViewPager状态改变时,回调
         */
        @Override
        public void onPageScrollStateChanged(int state) {
            }
        });
    }
        /**
         * 轮播任务
         */
        @Override
        protected void onStart() {
            super.onStart();
            mTimerTask = new TimerTask() {

        @Override
        public void run() {
            currentItem = (currentItem + 1) % imageIds.length;
            mHandler.sendEmptyMessage(0);
        }
    };
    timer.schedule(mTimerTask, 2000, 2000);
}

/**
 * 接收子线程传递的数据
 */
private Handler mHandler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        //轮播到最后一张图片时,直接跳转至第一页,并且取消滑动效果
        if (currentItem % images.size() == 0) {
            mMyViewPaper.setCurrentItem(currentItem, false);
        }
        //非最后一张展示图片的滑动效果
        mMyViewPaper.setCurrentItem(currentItem, true);
    }
};

    @Override
    protected void onStop() {
        super.onStop();
        timer.cancel();
        }
}
复制代码

自定义了一个Adapter适配器:

public class MyAdapter extends PagerAdapter {
    private List<ImageView> images;
    private Context mContext;

    public MyAdapter(Context context,List<ImageView> images) {
        this.mContext =context;
        this.images = images;
    }
    //返回Viewpager中的view个数
    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    //判断instantiateItem中的函数返回的key与一个页面示图是不是代表同一个
    //通常直接相等就OK啦
    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }
    //移除一个固定位置的页面
    @Override
    public void destroyItem(ViewGroup view, int position, Object object) {
        view.removeView((View) object);
    }

    //将固定位置的View添加到Viewgroup中,并创建显示出来
    @Override
    public Object instantiateItem(ViewGroup view, final int position) {
        ImageView imageView = images.get(position % images.size());
        ViewGroup parent = (ViewGroup) imageView.getParent();
        //这里是动态添加示图,一个子类只能有一个父类
        //判断下如果parent存在一定要记得移除
        if (parent != null) {
            parent.removeView(imageView);
        }
        view.addView(imageView);
        //给图片添加点击事件
        imageView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext,"点击了第"+(position % images.size()+1)+"图片",Toast.LENGTH_SHORT).show();
            }
        });
        return images.get(position % images.size());
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}
复制代码

在这里面也遇到一些问题,做了一些“妥协”,比如说无限轮播的时候发现播放到最后一张时会返回到第一张再次轮播,但是会有那种卡顿的感觉。所以我做了个“妥协的处理”,就是在播放到最后一张时,取消自带的动画效果,直接跳转到第一张,然后进行轮播。

private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            //轮播到最后一张图片时,直接跳转至第一页,并且取消滑动效果
            if (currentItem % images.size() == 0) {
            mMyViewPaper.setCurrentItem(currentItem, false);
        }
        //非最后一张展示图片的滑动效果
        mMyViewPaper.setCurrentItem(currentItem, true);
    }
};
复制代码

项目的github地址:https://github.com/yangziling/Carousel.git

希望对大家有所帮助,欢迎留言,相互交流,相互学习!谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值