你的位置:首页 > 操作系统

[操作系统]自定义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:布局和资源文件如下是:

主页面布局文件:

<??><RelativeLayout ="http://schemas.android.com/apk/res/android"  ="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>

下标圆点:

<??><selector ="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>

<??><shape ="http://schemas.android.com/apk/res/android"  android:shape="oval">  <size android:width="8dp"    android:height="8dp"/>  <solid android:color="#ff0000"/></shape>

<??><shape ="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);    }  }}