• 自定义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);
            }
        }
    }
  • 相关阅读:
    pycharm的常规使用
    python-引用/模块
    6-4 函数
    5-21文件的操作
    5-21python数据类型
    python-基础
    5-7接口测试工具之jmeter的使用
    接口测试基础
    把命令结果作为变量赋值
    shell变量子串
  • 原文地址:https://www.cnblogs.com/chenyangqi/p/5784938.html
Copyright © 2020-2023  润新知