zoukankan      html  css  js  c++  java
  • 自定义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);
            }
        }
    }
  • 相关阅读:
    PAT Basic 1077 互评成绩计算 (20 分)
    PAT Basic 1055 集体照 (25 分)
    PAT Basic 1059 C语言竞赛 (20 分)
    PAT Basic 1072 开学寄语 (20 分)
    PAT Basic 1049 数列的片段和 (20 分)
    蓝桥杯BASIC-13 数列排序
    蓝桥杯入门——3.序列求和
    蓝桥杯入门——2.圆的面积
    蓝桥杯入门——1.Fibonacci数列
    树的总结(遍历,BST,AVL原型,堆,练习题)
  • 原文地址:https://www.cnblogs.com/chenyangqi/p/5784938.html
Copyright © 2011-2022 走看看