Android实战开发——引导页面(VeiwPager)篇

Android实战开发之引导页面



前言

本篇文章主要介绍了引导页面的设计与制作,引导页面的方法有很多种,我们采用ViewPager来实现。图片资源本篇文章从服务器获取的,当然如果没有服务器,也可以使用引用的资源图片。

引导页效果图


提示:本篇文章不过多讲解Android的一些基础知识,只讲解实现过程与思路,后续将会通过链接的方式去陆续补充完整。敬请期待……

一、概述

  1. 使用ViewPager来实现引导页面的滑动效果
  2. ViewPager的实现需要适配器(Adapter)和数据源(List<View>)
  3. Adapter的作用是将数据源与ViewPager进行适配调节

    注:List<view>是用于“打包多个”View(即视图,或者说布局),而每一个View又承载了一个图片控件用于图片的显示。

二、操作步骤

1.操作准备

  • 新建包两个包activity和adapter用于文件分类
  • 在activity和layout目录下分别创建文件activity_guide.xml和GuideActivity.java文件
  • 在activity_guide.xml布局中添加ViewPager控件用来实现布局切换,添加三个View控件作为圆点显示引导页面位置
  • 在adapter下新建文件ViewPagerAdapter.java
  • 在layout下新建三个文件layout_guide01.xml、layout_guide02.xml、layout_guide03.xml三个布局文件并分别添加三个ImageView控件用于展示图片
  • 在drawable文件目录下创建view_true.xml和view_false文件并使用shape绘画出两个不同颜色的圆,用于标识选中和未选中状态(也可以使用selector选择器这里不做讲解)

2.初始化

  • 在GuideActivity.java中初始化控件、布局、数据
  • 我们使用三张图片来作为引导页面,所以需要初始化三个布局、三个圆点、
    三个图片(布局、圆点和图片的数量一定是统一的)。
  • 这里我们将布局、图片和圆点控件用数组来声明,同时固定按顺序来声明一个int类型标识id的数组。
    //布局
    private View[] views;
    private final int[] viewsId = {
            R.layout.layout_guide01,
            R.layout.layout_guide02,
            R.layout.layout_guide03
    };
    //图片
    private ImageView[] imageViews;
    private final int[] imageViewsId = {
            R.id.imageView,
            R.id.imageView2,
            R.id.imageView3
    };
    //圆点
    private View[] circleViews;
    private final int[] circleViewsId = {
            R.id.view,
            R.id.view2,
            R.id.view3
    };
  • 控件的初始化时,我们可以使用遍历数组的方式进行循环初始化(从下标为0开始
    遍历,小于页面(图片)控件数组的长度—>取决于对应Id(layout)数组的长
    度,这样写的最大好处在于更改时只需要对Id(layout)数组进行修改,便于维护)
        layoutInflater = getLayoutInflater();
         listView = new ArrayList<>();
        viewpager = findViewById(R.id.viewPager);

		views = new View[viewsId.length];
        circleViews = new View[circleViewsId.length];
        imageViews = new ImageView[imageViewsId.length];
        for(int i = 0;i<3;i++){
            //布局初始化
            views[i] = layoutInflater.inflate(viewsId[i],null,false);
            //圆点初始化
            circleViews[i] = findViewById(circleViewsId[i]);
            //布局对应控件初始化
            imageViews[i] = views[i].findViewById(imageViewsId[i]);
            //创建视图集
            listView.add(views[i]);
        }

注:这里我们使用LayoutInferlater.inferlater方法(传入layout和null参数即 可)动态加载布局,也就是初始化,使用前需要实例化LayoutInferlate对象。 实例化List调用add方法传入View参数来初始化数据


3、适配器设置

  • 继承自PagerAdapter并实现四个基本方法
 public class ViewPagerAdapter extends PagerAdapter {
    //返回列表中视图数量
    @Override
    public int getCount() {
        return listView.size();
    }


    //为翻页控件添加视图
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {

        container.addView(listView.get(position));

        return listView.get(position);
    }

    //移除翻页控件的视图
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView(listView.get(position));

    }

    //判断视图是否属于对象
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }
}
  • 添加构造器,指定List<View>参数,用于实例化时传递List<View>数据
 //添加构造器
public ViewPagerAdapter(List<View> viewList){
    this.listView = viewList;
}
  • 实例化ViewPagerAdapter,调用写好的Adapter构造器传入初始化好的List
    数据源,调用ViewPager的setAdapter方法将ViewPagerAdapter放入
//给适配器添加布局集
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(listView);
//给viewpager添加适配器
viewpager.setAdapter(viewPagerAdapter);

3、圆点的滑动事件

  • 这里我们调用ViewPager的滑动监听方法addOnPageChangeListener并重写onpageScrolled方法(需要实现三个基本方法其他两个不做过多讲解),其中position参数表示位置int类型,positionOffset参数表示位置偏移量float类型,positionOffsetPixels参数表示像素位置偏移量int类型。这里我们只需要position参数。
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @SuppressLint("UseCompatLoadingForDrawables")
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        for(int i  = 0;i<views.length;i++){
            if(position == i){
                circleViews[i].setBackground(getDrawable(R.drawable.circle_background_true));
            }else{
                circleViews[i].setBackground(getDrawable(R.drawable.circle_background_false));
            }
        }

    }
    @Override
    public void onPageSelected(int position) {
        
    }
    @Override
    public void onPageScrollStateChanged(int state) {
        
    }
});

注: 当处于第一张引导页面的时候,此时position的值为0,圆点的状态为选中状态。反之如果不是第一张页面,position的值不为0且圆点为未选中状态。我们使用 if else来进行判断,我们有三个引导页面(即三个圆点),因此我们需要重复三次 操作,我们利用for循环来执行(循环3次)。设置圆点选中和未选中我们调用的是setBackground方法参数为Drawable,因此我么需要调用getDrawable方法然后传入int类型的资源(即R.drawable.XXXX,来引用资源)


4、通过ApI获取图片资源并设置

  • 首先创建子线程(网络请求是耗时任务需要在子线程中执行)获取图片的Json数据,我们调用封装好的requestGet方法请求json数据
Thread thread = new Thread(new Runnable() {
        @Override
           public void run() {
            //获取引导页面json数据
            JSONArray jsonArray = null;
            String uri = null;
            bitmaps = new Bitmap[imageViews.length];
            String address = "http://124.93.196.67:8080";
            String inface = "/prod-api/api/rotation/list?pageNum=1&pageSize=3";
            String json = RequestUtil.requestGet(address+inface);
        });
        thread.start();
  • 图片API接口

API接口

  • 然后解析json数据获取到rows对应的以json为元素的数组,将其强制转换为JSONArray对象,然后通过JSONArray的get方法传入数组下标来读取对应的图片json数据,然后再次解析json对象获取到advImg对应的值,将这个值拼接到服务器地址即可获得图片的地址,再通过这个url调用写好的getImageBitmap方法将url地址转换为Bitmap对象
   //获取我们需要的rows
    JSONObject jsonObject = new JSONObject(json);
    JSONArray jsonArray = (JSONArray) jsonObject.opt("rows");
    for(int i = 0;i<jsonArray.length();i++){
         String advImg = jsonArray.get(i).toString();
         JSONObject jsonObject1 = new JSONObject(advImg);
         uri = jsonObject1.opt("advImg").toString();
         String url = address + uri;
         bitmaps[i] = RequestUtil.getImageBitmap(url);
     }
  • 最后切换到主线程调用Image的setImageBitmap方法设置图片
               //切换到主线程设置图片
              runOnUiThread(new Runnable() {
                  @Override
                  public void run() {

                      for(int i =0;i<imageViews.length;i++){
                          imageViews[i].setImageBitmap(bitmaps[i]);
                      }

                  }
              });

注:关于JSONArray对象数据的读取,和Bitmap位图的设置同样采用数组遍历的方法。这里的网络请求封装和通过url获取图片的Bitmap不做讲解。


5、创建弹窗用于IP地址和端口号的保存与修改

  • 自定义弹窗的建立需要先自定义一个弹窗的布局文件alertdialog.xml
  • 首先我们需要实例化AlertDialog.Builder对象并传入上下文Context
    调用LayoutInflater.inflater方法动态加载布局,再AlertDialog.Builder对象的setView、setTitl等方法来引入布局和基本设置,最后分别调用AlertDialog.Builder对象的create和show方法来创建展示弹窗,最终初始化控件就可以对控件进行设置
//创建弹窗
        AlertDialog.Builder builder = new AlertDialog.Builder(GuideActivity.this);
        View alertDialogView = layoutInflater.inflate(R.layout.alertdialog,null);
        builder.setView(alertDialogView).setTitle("网络设置");
        builder.create();
        Dialog dialog = builder.show();
        //初始化控件
       EditText ipEt =  alertDialogView.findViewById(R.id.editTextTextPersonName2);
       EditText portEt = alertDialogView.findViewById(R.id.editTextTextPersonName3);
       Button saveBt = alertDialogView.findViewById(R.id.button5);
       Button cancelBt = alertDialogView.findViewById(R.id.button6);

   //修改IP地址和端口号
    cancelBt.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               dialog.dismiss();
               Toast.makeText(GuideActivity.this,"修改成功!",Toast.LENGTH_SHORT).show();
           }
       });

    //保存网络设置
    saveBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //保存IP和端口号
           String ip = ipEt.getText().toString().trim();
           String port = portEt.getText().toString().trim();
           sharedPreferences02 = getSharedPreferences("socket",MODE_PRIVATE);
           SharedPreferences.Editor editor = sharedPreferences02.edit();
           editor.putString("ip",ip);
           editor.putString("port",port);
           editor.apply();
           //关闭弹窗
            dialog.dismiss();
           //提示信息
           Toast.makeText(GuideActivity.this,"保存成功!",Toast.LENGTH_SHORT).show();
        }
    });

注:保存和修改IP和端口号的方法一样(Shared Preferences数据覆盖机制),SharedPreferences的使用需要声明SharedPreferences和SharedPreferences.Editor对象并分别调用getSharedPregerences方法传入String类型的name和MODE_PRIVATE和SharedPreferences.edit方法。最后调用SharedPereferences.Editor的putSting方法以键值对形式存储数据,最终调用Shared Preferences.Editor的apply方法提交保存(commit方法也可,但在一些情况下会出现问题,不建议使用)


三、总结

以上便是引导页面的设计与制作,猿友们可以根据实际需求和实际情况随机应变。有什么问题欢迎留言,一起学习进步哦~

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>