Android studio 制作APP图片轮播(ViewPager 视图滑动切换工具)

效果图如下,因为懒得弄GIF就用图片代替了一下↓

这两张图片就是通过自动滑动进行切换的。

接下来讲一下具体的实现过程。

第一步:代码段

首先是Java文件

package com.example.prince.justicel.signin;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewSwitcher;

import com.example.prince.justicel.R;
import com.example.prince.justicel.color.ColorActivity;

import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import cn.bmob.v3.Bmob;


public class SignInMainActivity extends Activity {

    private int imageIds[] = {
            R.drawable.background, R.drawable.background1,
            R.drawable.background2, R.drawable.background3,
            R.drawable.background4
    };

    private ArrayList<ImageView> images = new ArrayList<>();
    private ViewPager vp;
    private int oldPosition = 0;//记录上一次点的位置
    private int currentItem; //当前页面
    private ScheduledExecutorService scheduledExecutorService;
    //图片标题
    private String titles[] = new String[]{"图片1", "图片2", "图片3", "图片4", "图片5"};
    private ArrayList<View> dots = new ArrayList<View>();;
    private TextView title;

    private Button color;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sign_main);

        Slide();//实现滑动功能的函数

    }

    public void Slide(){
        for (int i = 0; i < imageIds.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(imageIds[i]);

            images.add(imageView);
        }


        //显示的点 加入集合
        dots.add(findViewById(R.id.dot_0));
        dots.add(findViewById(R.id.dot_1));
        dots.add(findViewById(R.id.dot_2));
        dots.add(findViewById(R.id.dot_3));
        dots.add(findViewById(R.id.dot_4));

        //获取图片标题的id
        title = (TextView) findViewById(R.id.tv_test_title);

        //获取ViewPager 的id
        vp = (ViewPager) findViewById(R.id.vp);
        vp.setAdapter(new ViewPagerAdapter());

        vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                //设置页面刷新后的图片标题
                title.setText(titles[position]);
                oldPosition = position;
                currentItem = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }


    class ViewPagerAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            return images.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //将试图移除试图组
            View v =images.get(position);
            container.removeView(v);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            //将试图添加进试图组
            View v =images.get(position);
            container.addView(v);
            return v;
        }

    }

    @Override
    protected void onStart() {
        super.onStart();
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        //每隔三秒换一张图片
        scheduledExecutorService.scheduleWithFixedDelay(new ViewPagerTask(),3,3, TimeUnit.SECONDS);//TimeUnit.SECONDS);

    }
    //实现一个碎片的接口
    class ViewPagerTask implements Runnable{

        @Override
        public void run() {
            currentItem = (currentItem+1)%imageIds.length;
            //更新界面
            handler.obtainMessage().sendToTarget();
        }
    }
    //在handler进行碎片跳转
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            vp.setCurrentItem(currentItem);
        }
    };

}

然后是layout内容

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    > 
     <FrameLayout
        android:id="@+id/frameLayout_slide"
        android:layout_width="0dp"
        android:layout_height="168dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/frameLayout_top">

        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="200dp" />

        <LinearLayout
            android:id="@+id/centerLinear"
            android:layout_width="match_parent"
            android:layout_height="35dip"
            android:layout_gravity="bottom"
            android:background="#33000000"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_test_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="图片1"
                android:textColor="@android:color/white" />

            <LinearLayout
                android:id="@+id/dotLinear"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="3dip"
                android:orientation="horizontal">

                <View
                    android:id="@+id/dot_0"
                    android:layout_width="5dip"
                    android:layout_height="5dip"
                    android:layout_marginLeft="2dip"
                    android:layout_marginRight="2dip"
                    android:background="@color/colorWhite" />

                <View
                    android:id="@+id/dot_1"
                    android:layout_width="5dip"
                    android:layout_height="5dip"
                    android:layout_marginLeft="2dip"
                    android:layout_marginRight="2dip"
                    android:background="@color/colorWhite" />

                <View
                    android:id="@+id/dot_2"
                    android:layout_width="5dip"
                    android:layout_height="5dip"
                    android:layout_marginLeft="2dip"
                    android:layout_marginRight="2dip"
                    android:background="@color/colorWhite" />

                <View
                    android:id="@+id/dot_3"
                    android:layout_width="5dip"
                    android:layout_height="5dip"
                    android:layout_marginLeft="2dip"
                    android:layout_marginRight="2dip"
                    android:background="@color/colorWhite" />

                <View
                    android:id="@+id/dot_4"
                    android:layout_width="5dip"
                    android:layout_height="5dip"
                    android:layout_marginLeft="2dip"
                    android:layout_marginRight="2dip"
                    android:background="@color/colorWhite" />

            </LinearLayout>


        </LinearLayout>

    </FrameLayout>
</android.support.constraint.ConstraintLayout>

这里说明一下,android:background="@color/colorWhite"是在 res --> values --> colors.xml中添加的一个颜色,白色。

<color name="colorWhite">#ffffff</color>

第二步:代码说明

注:有部分内容引自 → 菜鸟驿站 2.6.3 ViewPager的简单使用

其实代码中的注释已经可以让大家理解大多数部分了,主要说一下 VP(ViewPager)的地方。我们需要一个Adapter (适配器)将我们的View和ViewPager进行绑定,而ViewPager则有一个特定的Adapter—— PagerAdapter。

Google官方是建议我们使用Fragment来填充ViewPager的,这样 可以更加方便的生成每个Page,以及管理每个Page的生命周期!给我们提供了两个Fragment 专用的Adapter:FragmentPageAdapterFragmentStatePagerAdapter 我们简要的来分析下这两个Adapter的区别:

  • FragmentPageAdapter:和PagerAdapter一样,只会缓存当前的Fragment以及左边一个,右边 一个,即总共会缓存3个Fragment而已,假如有1,2,3,4四个页面:
    处于1页面:缓存1,2
    处于2页面:缓存1,2,3
    处于3页面:销毁1页面,缓存2,3,4
    处于4页面:销毁2页面,缓存3,4
    更多页面的情况,依次类推~
  • FragmentStatePagerAdapter:当Fragment对用户不 见得时,整个Fragment会被销毁, 只会保存Fragment的状态!而在页面需要重新显示的时候,会生成新的页面!

综上,FragmentPageAdapter适合固定的页面较少的场合;而FragmentStatePagerAdapter则适合 于页面较多或者页面内容非常复杂(需占用大量内存)的情况!

那么我们代码中的VP如下:

 //获取ViewPager 的id
        vp = (ViewPager) findViewById(R.id.vp);
        vp.setAdapter(new ViewPagerAdapter());

对于这段代码,实现了一个ViewPagerAdapter对象。

class ViewPagerAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            return images.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //将试图移除试图组
            View v =images.get(position);
            container.removeView(v);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            //将试图添加进试图组
            View v =images.get(position);
            container.addView(v);
            return v;
        }

    }

而ViewPagerAdapter则继承了PagerAdapter

这是最普通的PagerAdapter,如果想使用这个PagerAdapter需要重写下面的四个方法: 当然,实际上我们只需重写getCount()和isViewFromObject()就可以了~

  • getCount():获得viewpager中有多少个view
  • destroyItem():移除一个给定位置的页面。适配器有责任从容器中删除这个视图。 这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。

而另外两个方法则是涉及到一个key的东东:

  • instantiateItem(): ①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来 ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,当然你也可以 自定义自己的key,但是key和每个view要一一对应的关系
  • isViewFromObject(): 判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是 代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写 return view == object!

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值