自定义View(二)ViewPage广告轮播

自定义View的第二个学习案例,使用ViewPage实现广告轮播,通过组合现有的View实现效果如下:

有关ViewPage使用可以学习谷歌官方API,和训练案例:

1.使用ViewPage实现屏幕滑动:https://developer.android.com/training/animation/screen-slide.html

2.API:https://developer.android.com/reference/android/support/v4/view/ViewPager.html

viewPage试用范围较广 比如tab切换,和引导页面等。学习过程中遇到一个问题,使用setCurrentItem(posetion)实现页面定位时会报错误,需要重新设定Adapter

viewPage.setAdapter(new MyViewPageAdapter());viewPage.setCurrentItem(posetion, true);

Monition分下如下,性能方面应该不存在bug

1:布局和资源文件如下是:

主页面布局文件:

<?xml version="1.0" encoding="utf-8"?>
<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.demo.cyq.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toobar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

    </android.support.v7.widget.Toolbar>

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

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/viewPage"
        android:background="#44000000"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:id="@+id/imgDescription"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text=""
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <LinearLayout
            android:id="@+id/ll_point_group"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal">

        </LinearLayout>
    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="viePage实现轮播"
        android:textSize="26sp" />
</RelativeLayout>

下标圆点:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/point_press" android:state_enabled="false" />
    <item android:drawable="@drawable/point_normal" android:state_enabled="true"/>
</selector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:width="8dp"
        android:height="8dp"/>
    <solid android:color="#ff0000"/>

</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:width="8dp"
        android:height="8dp"/>
    <solid android:color="#FFFFFF"/>

</shape>

MainActivity.class类

package com.demo.cyq;

import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private Toolbar toolbar;
    private ViewPager viewPage;
    private TextView imgDescription;
    private ArrayList images;
    private LinearLayout ll_point_group;
    private int[] imgesId = {R.mipmap.banner1, R.mipmap.banner2, R.mipmap.banner3, R.mipmap.banner4};
    private String[] imgDescriptions = {"Facebooks Audience Network", "新一代Mac Pro发布", "全国大学生珠三角论坛", "Maple 2016"};
    private int presentPostion = 0;
    private final int OPTION_TYPE_AUTO = 1, OPTION_TYPE_POINT = 2;
    private static int pointClickPosition = 0; //point点击的位置
    private boolean isDraging = false;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            int option = msg.what;
            switch (option) {
                case OPTION_TYPE_AUTO: //option==1执行viewPage跳转到下一个
                    int currentPostion = viewPage.getCurrentItem();//获得当前的ViewPage位置
                    viewPage.setCurrentItem(++currentPostion, true);
                    handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);//回调handler 实现自动轮播
                    break;
                case OPTION_TYPE_POINT:
                    //重新设置Adapter 这个地方不设置就会报如下错误 很诡异:
                    // The specified child already has a parent. You must call removeView() on the child‘s parent first
                    int currentPostion2 = viewPage.getCurrentItem();//获得当前的ViewPage位置
                    viewPage.setAdapter(new MyViewPageAdapter());
                    viewPage.setCurrentItem(currentPostion2 - currentPostion2 % images.size() + pointClickPosition, true);
                    handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);//回调handler 实现自动轮播
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toobar);
        toolbar.setTitle("ViewPage实现图片轮播");
        setSupportActionBar(toolbar);

        viewPage = (ViewPager) findViewById(R.id.viewPage);
        ll_point_group = (LinearLayout) findViewById(R.id.ll_point_group);
        imgDescription = (TextView) findViewById(R.id.imgDescription);

        images = new ArrayList<ImageView>();

        for (int i = 0; i < imgesId.length; i++) {
            ImageView image = new ImageView(this);
            image.setBackgroundResource(imgesId[i]);
            images.add(image);

            ImageView point = new ImageView(this);
            point.setBackgroundResource(R.drawable.point_selecte);
            //为Point设置布局参数 应为point的父节点是LinerLayout,所以需要使用LinearLayout.LayoutParams
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
            params.bottomMargin = 20;
            if (i == 0)
                point.setEnabled(false);
            else {
                point.setEnabled(true);
                params.leftMargin = 20;
            }
            point.setLayoutParams(params);
            ll_point_group.addView(point);
        }
        viewPage.setAdapter(new MyViewPageAdapter());
        //初始化显示imgDescription
        imgDescription.setText(imgDescriptions[presentPostion]);
        //设置初始启动imageView的位置为1000的中间,避免初始为0时不能向左滑动
        viewPage.setCurrentItem(1000 / 2 - 1000 / 2 % images.size(), true);
        //设置ViewPage页面切换的监听事件
        viewPage.addOnPageChangeListener(new MyPageChangeListener());
        //延迟发送handler消息 用于启动ViewPage自动轮播
        handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 2000);

        for (int i = 0; i < ll_point_group.getChildCount(); i++) {
            final View point = ll_point_group.getChildAt(i);
            final int finalI = i;
            point.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    pointClickPosition = finalI;
                    handler.removeCallbacksAndMessages(null);
                    handler.sendEmptyMessageDelayed(OPTION_TYPE_POINT, 50);
                    for (int j = 0; j < ll_point_group.getChildCount(); j++) {
                        ll_point_group.getChildAt(j).setEnabled(true);
                    }
                    point.setEnabled(false);
                }
            });

        }
    }

    /**
     * viewPage切换监听
     */
    class MyPageChangeListener implements ViewPager.OnPageChangeListener {
        /**
         * 当页滑动的时候 回调该方法
         *
         * @param position             当前滑动页面的位置
         * @param positionOffset       当前页面滑动的百分比
         * @param positionOffsetPixels 当前页面滑动的像素
         */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        /**
         * 页面被选中后已完全显示时调用改方法
         *
         * @param position 被选中的页面的位置
         */
        @Override
        public void onPageSelected(int position) {
            imgDescription.setText(imgDescriptions[position % imgDescriptions.length]);
            ll_point_group.getChildAt(presentPostion % images.size()).setEnabled(true);
            ll_point_group.getChildAt(position % imgDescriptions.length).setEnabled(false);
            presentPostion = position;
        }

        /**
         * 页面滑动的状态
         * 静止-滑动
         * 滑动-静止
         * 静止-拖拽
         *
         * @param state
         */
        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == viewPage.SCROLL_STATE_DRAGGING) { //拖拽状态
                isDraging = true;
                //如果处于拖拽状态 就移除handler 避免拖拽过程中自动轮播、
                handler.removeCallbacksAndMessages(null);
            } else if (state == viewPage.SCROLL_STATE_SETTLING) {//滑动状态

            } else if (state == viewPage.SCROLL_STATE_IDLE) {//休闲状态
                isDraging = false;
                //拖拽结束后调用改方法 先移除handler 然后重新发送handler 启动自动 轮播
                handler.removeCallbacksAndMessages(null);
                handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);
            }

        }
    }

    /**
     * pageAdaapter适配器
     */
    class MyViewPageAdapter extends PagerAdapter {

        /**
         * 返回ViewPage总数
         *
         * @return
         */
        @Override
        public int getCount() {
            return 1000;
        }

        /**
         * 返回ViewPage中的position位置处的ImageView
         *
         * @param container 代表ViewPage
         * @param position  位置
         * @return 返回ViewPage
         */
        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            ImageView imageView = (ImageView) images.get(position % images.size());
            container.addView(imageView);

            //监听Touch事件 长按图片时禁止viewpage滚动
            viewPage.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    switch (motionEvent.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            //鼠标按下的时候移除handler
                            handler.removeCallbacksAndMessages(null);
                            break;
                        case MotionEvent.ACTION_MOVE:

                            break;
                        case MotionEvent.ACTION_UP:
                            //鼠标抬起的时候移除handler 并且重新发送handler
                            handler.removeCallbacksAndMessages(null);
                            handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);
                            break;
                    }
                    return false; //返回false 表示不消费触摸操作 任然可以触发其他操作
                }
            });

            //为当前imageView设置点击监听
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this, imgDescriptions[position % imgDescriptions.length], Toast.LENGTH_SHORT).show();
                }
            });

            return imageView;
        }

        /**
         * 工系统调用 判断instantiateItem方法返回的View是否和object相同
         *
         * @param view   instantiateItem方法返回的ImageView
         * @param object
         * @return
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        /**
         * 供系统调用 用于销毁ViewPage中的object
         *
         * @param container
         * @param position
         * @param object
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}
时间: 2024-08-07 07:46:47

自定义View(二)ViewPage广告轮播的相关文章

自定义View之无限大图轮播ShufBanner

无限大图轮播–ShufBanner 轮播图作为一个app的宣传,展示等,往往占据着一个很重要的地位,大部分app都将其放在首页.那么通常的做法都是使用ViewPager,使其能够作用滑动,而无限轮播无外乎两种做法. - 第一种是将ViewPager的size定义为无限大,定义其初始显示的位置为中间,这样的话因为左或者右都有很多的页面,所以造成了一种可以无限轮播的假象.同时因为ViewPager的特性,其只是加载当前显示page以及左和右的三个页面,不用担心OOM. - 第二种是,将ViewPag

安卓开发笔记——自定义广告轮播Banner(无限循环实现)

关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户"友好性",下面来看几个示例图:     再来看下我仿写的效果: 关于广告轮播Banner这个东西,GitHub上面应该有现成的开源组件,不过我没去找过,觉得实现起来不会太难,就自己去仿写了,下面我说下实现的思路: 1.首先看到这个可以滑动切换图片的界面,我们很自然就会想到ViewPager

Android无限广告轮播 - 自定义BannerView

1.概述 这其实是我第一篇想写的博客,可能是因为我遇到了太多的坑,那个时候刚入行下了很多Demo发现怎么也改不动,可能是能力有限,这次就做一个具体的实现和彻底的封装. 上次讲了Android无限广告轮播-ViewPager源码分析,有了源码分析我们对ViewPager就有了一个大概的了解,那么再来封装成自定义View,就会简单许多,附视频讲解地址:http://pan.baidu.com/s/1bpqqkGn 2.效果封装 2.1 自定义BannerViewPager extends ViewP

自定义广告轮播条向右滑动出现空白

在新项目中,广告轮播条当然非常常用了,我也是挺懒的一个人,直接用了上个App中另一个哥们用的代码,用ViewPager和Timer类实现的,看着代码应该也是网上谁写的,具体已经不知道了,代码有段类似这样 Activity mActivity; // 上下文 List<View> mListViews; // 图片组 int mScrollTime = 0; Timer timer; int oldIndex = 0; int curIndex = 0; 广告轮播本身没问题,功能都可以实现,包括

新版的复制统计工具介绍,微信加粉推广辅助工具,增强了复制统计功能以外,新增了二维码轮播,电话拨打统计

今年已经发展到了3.x版本,新版的比老版本新增了很多功能,除了之前已有的微信号在线管理,和复制统计,以及网页状态监控等功能以外.新增了扫码统计,二维码轮播,微信号自动上下控制,手动控制,拨打电话统计,点击复制,打开微信等,还有更强大的拦截功能.到现在为止,我们应该是最完善的微信加粉推广辅助工具了. 并且我们一直提供免费版,相对于付费版功能并无过多缩减,只是限制了能统计的落地页的数量,因为统计流量巨大,如果免费开放更多会统计的数量会占用更多的服务器资源造成服务器压力过大,从而服务器成本也会直线上升

Android 通过ViewFlipper实现广告轮播功能并可以通过手势滑动进行广告切换

为了实现广告轮播功能,在网上找了很多方法,有的效果很好,但是代码太麻烦,并且大多是用的viewpager,总之不是很满意. 于是看了一下sdk有个控件是ViewFlipper,使用比较方便,于是尝试了一下,最终实现了所需效果.在这里与大家分享. 首先看一下效果(主要是布局方面的效果,毕竟手势识别和滑动不太好显示,懒得弄成gif了): 1.布局文件.xml <LinearLayout android:layout_width="fill_parent" android:layout

广告轮播

1 package com.zxw.fragment; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.io.UnsupportedEncodingException; 8 import java.util.ArrayList; 9 import java.

android-自定义广告轮播Banner(无限循环实现)

关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户"友好性",下面来看几个示例图:    再来看下我仿写的效果: 关于广告轮播Banner这个东西,GitHub上面应该有现成的开源组件,不过我没去找过,觉得实现起来不会太难,就自己去仿写了,下面我说下实现的思路: 1.首先看到这个可以滑动切换图片的界面,我们很自然就会想到ViewPager控

猫猫学iOS 之广告轮播图,collectionView制作

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 效果图 不多说,好不好先看效果,之前做过一个scrollView的轮播图,但是很局限,很多多余代码,今天猫猫重新做了一个用collectionView的流水布局做的一个,可以拿去做广告轮播,也可以做系统新特性哦,来,看下效果吧. 源码共享:https://github.com/znycat/NYCarouselView 很久很久以前就想做了.总而言之,猫猫代码有