ViewPager的详解(使用viewPager实现导航页面)

Viewpager简介

ViewPager是Google的support.v4包中的支持控件,可以实现View之间的切换。

ViewPager的使用在目前的应用环境中非常频繁,甚至对其进行相关的自定义来实现一些特别的效果。
ViewPager使用详解系列只是对于Google官方提供的支持库中的相关工具来实现效果,不涉及到自定义的东西。

ViewPager最简单的使用方法,就是与PagerAdapter的配合使用,所以我们必须了解PagerAdapter中的方法及其对应的功能。

public class ViewPagerAdapter extends PagerAdapter {
     /**
      * 获取View的总数
      *
      * @return View总数
      */
      @Override
      public int getCount() {
          return 0;
      }

      /**
       * 当ViewPager的内容有所变化时,进行调用。
       *
       * @param container ViewPager本身
       */
      @Override
      public void startUpdate(ViewGroup container) {
          super.startUpdate(container);
      }

      /**
       * 为给定的位置创建相应的View。创建View之后,需要在该方法中自行添加到container中。
       *
       * @param container ViewPager本身
       * @param position  给定的位置
       * @return 提交给ViewPager进行保存的实例对象
       */
      @Override
      public Object instantiateItem(ViewGroup container, int position) {
          return super.instantiateItem(container, position);
      }

      /**
       * 为给定的位置移除相应的View。
       *
       * @param container ViewPager本身
       * @param position  给定的位置
       * @param object    在instantiateItem中提交给ViewPager进行保存的实例对象
       */
      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
          super.destroyItem(container, position, object);
      }

      /**
       * ViewPager调用该方法来通知PageAdapter当前ViewPager显示的主要项,提供给用户对主要项进行操作的方法。
       *
       * @param container ViewPager本身
       * @param position  给定的位置
       * @param object    在instantiateItem中提交给ViewPager进行保存的实例对象
       */
      @Override
      public void setPrimaryItem(ViewGroup container, int position, Object object) {
          super.setPrimaryItem(container, position, object);
      }

      /**
       * 当ViewPager的内容变化结束时,进行调用。当该方法被调用时,必须确定所有的操作已经结束。
       *
       * @param container ViewPager本身
       */
      @Override
      public void finishUpdate(ViewGroup container) {
          super.finishUpdate(container);
      }

      /**
       * 确认View与实例对象是否相互对应。ViewPager内部用于获取View对应的ItemInfo。
       *
       * @param view   ViewPager显示的View内容
       * @param object 在instantiateItem中提交给ViewPager进行保存的实例对象
       * @return 是否相互对应
       */
      @Override
      public boolean isViewFromObject(View view, Object object) {
          return false;
      }

      /**
       * 保存与PagerAdapter关联的任何实例状态。
       *
       * @return PagerAdapter保存状态
       */
      @Override
      public Parcelable saveState() {
          return super.saveState();
      }

      /**
       * 恢复与PagerAdapter关联的任何实例状态。
       *
       * @param state  PagerAdapter保存状态
       * @param loader 用于实例化还原对象的类加载器
       */
      @Override
      public void restoreState(Parcelable state, ClassLoader loader) {
          super.restoreState(state, loader);
      }

      /**
       * 当ViewPager试图确定某个项的位置是否已更改时调用。默认有两个可选项:POSITION_UNCHANGED和POSITION_NONE。
       * POSITION_UNCHANGED:给定项的位置未变更
       * POSITION_NONE:给定项不再用于PagerAdapter中
       * 其他值:可以根据具体的情况进行调整
       *
       * @param object 在instantiateItem中提交给ViewPager进行保存的实例对象
       * @return
       */
      @Override
      public int getItemPosition(Object object) {
          return super.getItemPosition(object);
      }

      /**
       * 新增方法,目前较多用于Design库中的TabLayout与ViewPager进行绑定时,提供显示的标题。
       *
       * @param position 给定的位置
       * @return 显示的标题
       */
      @Override
      public CharSequence getPageTitle(int position) {
          return super.getPageTitle(position);
      }

      /**
       * 获取给定位置的View的显示宽度比例,该比例是相对于ViewPager。
       *
       * @param position 给定的位置
       * @return View显示的宽度比例
       */
      @Override
      public float getPageWidth(int position) {
          return super.getPageWidth(position);
      }

  }
当然,这么多的方法,其实我们经常使用到的只是其中的一部分而已,我们经常使用的是下面几个方法:
public class MyViewPager extends PagerAdapter {
    private List list;

    public MyViewPager(List list) {
        this.list = list;
    }

    @Override//此方法返回的是当前窗体的页面数
    public int getCount() {
        if (list != null && list.size() > 0) {
            return list.size();
        } else
            return 0;
    }

    @Override
    //重点解释一下此方法Viewpager会将每一个item添加到item中,item是一个arrayList数组,
    //itemInfo是每个View相关的信息,其中的Object就是instantiateItem返回的那个Object,这个对象可以
    // 不是一个View,是为了让ViewPager检查是否和View是对应的
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }

    @Override
    //此方法返回一个对象,表明pagerAdapter选择哪个对象放在ViewPager中
    public Object instantiateItem(ViewGroup container, int position) {
        return super.instantiateItem(container, position);
    }

    @Override
    //从ViewPager中移除当前的View
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
    }

    @Override
    //重写这个方法是由于不重写的话调用MyViewPager().notifyDataSetChanged()不会刷新数据
    //重写之后返回POSITION_NONE也就是-2就可以刷新数据了
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

}

注释在代码中有了,不再强调了

下面使用ViewPager来实现一个程序引导的demo,效果图如下:

(第一次进入APP会有导航页面,实在找不到图片,视觉感觉上差了很多,诸位莫怪)     

ViewPager的详解(使用viewPager实现导航页面)_第1张图片

        (第二次进入App就不会再进入导航页面了)
 一般来说,引导界面是出现第一次运行时出现的,之后不会再出现。所以需要记录是否是第一次使用程序,办法有很多,最容易想到的就是使用SharedPreferences来保存。步骤如下:
  1、程序进入欢迎界面,SplashActivity,在这里读取SharedPreferences里面的变量,先设置为true。进入引导界面,然后设置为false。
  2、之后每次进入欢迎界面读取SharedPreferences里面的变量,因为是false,所以不会运行引导界面了。
代码如下:
SplashActivity.java,欢迎界面。

package com.example.forget.viewpagerdemo;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class SplashActivity extends AppCompatActivity {
    boolean isfirst = true;
    private static final String IS_FIRST = "frist";sharedpreference的文件名称
    public static final int GO_HOME = 0x123;进入主activty的标记
    public static final int GO_GUIDE = 0x124;进入导航页的标记
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
对收到的标记进行判断执行相应的方法
                case GO_HOME:
                    goHome();
                    break;
                case GO_GUIDE:
                    goGuide();
                    break;
            }
            super.handleMessage(msg);
        }
    };

    private void goGuide() {
        Intent intent = new Intent(this, GuideActivity.class);
        startActivity(intent);
        finish();
    }

    private void goHome() {
        Intent intent = new Intent(this, HomeActivty.class);
        startActivity(intent);
        finish();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
进入闪屏页的时候进行判断,标记是否为true,若为true的话进入导航页,第一次默认标记为true
    private void init() {
        SharedPreferences sp = getSharedPreferences(IS_FIRST, MODE_PRIVATE);
        isfirst = sp.getBoolean("isFirstIn", true);
        if (isfirst) {
如果标记为true,则发送消息进入导航页
            handler.sendEmptyMessageDelayed(GO_GUIDE,3000);
        }
        else     如果标记为false,进入主activty
            handler.sendEmptyMessageDelayed(GO_HOME,3000);
    }
}
对应的导航页的适配器的代码:

package com.example.forget.viewpagerdemo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.view.PagerAdapter;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.List;

/**
 * Created by Forget on 2017/1/2.
 */

public class GuideAdapter extends PagerAdapter {
    private Activity activity;
    private List list;
    private static final String IS_FIRST = "frist";

    public GuideAdapter(Activity activity, List list) {
        this.activity = activity;
        this.list = list;
    }

    @Override返回的viewpager中的页数
    public int getCount() {
        if (list != null && list.size() > 0) {
            return list.size();
        } else return 0;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
	
    @Override 销毁当前activity
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(list.get(position));
    }

    @Override设置返回的视图
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(list.get(position));
        如果是最后一页,设置事件,使其跳转到主activity界面
	if (position == list.size() - 1) {
            ImageView imageView= (ImageView) container.getChildAt(position);
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
		将标记变成false,之后每次进入会读取此标记,不会再次进入导航页
                    setGuide();
		跳转页面
                    goHome();
                }
            });
        }
        return list.get(position);
    }

    private void goHome() {
        Intent intent = new Intent(activity, HomeActivty.class);
        activity.startActivity(intent);
        activity.finish();

    }

    private void setGuide() {
        SharedPreferences sp = activity.getSharedPreferences(IS_FIRST, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean("isFirstIn", false);
        editor.commit();
    }
}

导航页Activty的代码:

package com.example.forget.viewpagerdemo;

import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

public class GuideActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
    private ViewPager viewPager;
    private GuideAdapter guideAdapter;
    private List list;定义适配器中需要添加的视图
    private ImageView[] dots;定义底部导航图的集合
    private int curretnIndex;记录当前页面的标记

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_guide);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        initView();

        guideAdapter = new GuideAdapter(this, list);
        viewPager.setAdapter(guideAdapter);
        viewPager.addOnPageChangeListener(this);
        initData();

    }
    初始化需要填充到viewpager中的数据
    private void initView() {
        list = new ArrayList<>();
        int[] imageResour = new int[]{R.mipmap.first, R.mipmap.second, R.mipmap.third};
        for (int i = 0; i < imageResour.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setImageResource(imageResour[i]);
            imageView.setClickable(true);
            list.add(imageView);
        }

    }
    初始化需要填充到底部导航圆点的视图
    private void initData() {
	获取装小圆点的容器
        LinearLayout ll = (LinearLayout) findViewById(R.id.group);
        dots = new ImageView[guideAdapter.getCount()];
        根据索引取出容器中的小圆点,并设置选择器(选择器里面设置的是state_enabled的状态),
	for (int i = 0; i < dots.length; i++) {
            dots[i] = (ImageView) ll.getChildAt(i);
//          dots[i].setImageResource(R.mipmap.default_holo);
            dots[i].setEnabled(false);
        }
        curretnIndex = 0;

//       dots[curretnIndex].setImageResource(R.mipmap.touched_holo);
        将第一页设置成选中状态
	dots[curretnIndex].setEnabled(true);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        if (position < 0 || position > guideAdapter.getCount() - 1 || curretnIndex == position) {
            return;
        }
//        dots[position].setImageResource(R.mipmap.touched_holo);
//        dots[curretnIndex].setImageResource(R.mipmap.default_holo);
        将当期的页面设置成true,即:选中状态,将前一个页面设置成未选中状态
	dots[position].setEnabled(true);
        dots[curretnIndex].setEnabled(false);
	修改临时变量的值
        curretnIndex=position;
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

选择器如下:我们给imageview的state_enabled(是否可用的状态)设置选择器


    
    
(注意:这里再imageView中引用的话使用background进行引用,需要配合图片使用(或者给定大小),不然会导致小圆点变形)

至于主activty可以随便写,我这里给的是一张图片

你可能感兴趣的:(Android_UI)