关于android:Android-利用ViewPager开发引导页并加入帧动画属性动画和音乐播放

41次阅读

共计 12900 个字符,预计需要花费 33 分钟才能阅读完成。

一、前言

<font face= 黑体 > 当初很多 App 都有疏导页,明天咱们就利用 ViewPager 来实现疏导页,并且在疏导页中退出 帧动画 属性动画 音乐播放 等性能。

<font face= 黑体 > 性能目录如下:

二、最终成果展现

<font face= 黑体 > 最终成果如下所示:

三、实现步骤

3.1、引入 ViewPager

<font face= 黑体 > 布局采纳 ConstraintLayout 实现,整体还是很简略的,就是一个全屏的 ViewPager 加上右上角的音乐播放按钮以及底部的小圆点。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/mViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv_music_switch"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="30dp"
        android:layout_marginEnd="20dp"
        android:src="@drawable/img_guide_music"
        app:layout_constraintEnd_toStartOf="@+id/tv_guide_skip"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_guide_skip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        android:text="跳过"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv_guide_point_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:src="@drawable/img_guide_point_p"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.45"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/iv_guide_point_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:src="@drawable/img_guide_point"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/iv_guide_point_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:src="@drawable/img_guide_point"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.55"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3.2、实现 ViewPager 成果

3.2.1、引入 ViewPager 的三个子 View

<font face= 黑体 > 三个子 View 的布局都一样,这里就以一个为例子,子 View 的布局也很简略,就是一个图片加上一个文字。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv_guide_star"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@drawable/guide_star_anim" />

    <TextView
        android:id="@+id/tv_guide_star"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="身在井隅,心向璀璨"
        android:textSize="18sp" />

</LinearLayout>

3.2.2、创立 ViewPager 适配器

public class BasePageAdapter extends PagerAdapter {

    private List<View> mList;

    public BasePageAdapter(List<View> mList) {this.mList = mList;}

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

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {container.addView(mList.get(position));
        return mList.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {container.removeView(mList.get(position));
    }
}

3.2.3、代码实现

public class MainActivity extends AppCompatActivity {

    private ImageView iv_music_switch;
    private TextView tv_guide_skip;
    private ImageView iv_guide_point_1;
    private ImageView iv_guide_point_2;
    private ImageView iv_guide_point_3;
    private ViewPager mViewPager;

    private View view1;
    private View view2;
    private View view3;

    private List<View> mPageList = new ArrayList<>();
    private BasePageAdapter mPageAdapter;

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

        initView();}

    private void initView() {iv_music_switch = findViewById(R.id.iv_music_switch);
        tv_guide_skip = findViewById(R.id.tv_guide_skip);
        iv_guide_point_1 = findViewById(R.id.iv_guide_point_1);
        iv_guide_point_2 = findViewById(R.id.iv_guide_point_2);
        iv_guide_point_3 = findViewById(R.id.iv_guide_point_3);
        mViewPager = findViewById(R.id.mViewPager);

        view1 = View.inflate(this, R.layout.layout_pager_guide_1, null);
        view2 = View.inflate(this, R.layout.layout_pager_guide_2, null);
        view3 = View.inflate(this, R.layout.layout_pager_guide_3, null);

        mPageList.add(view1);
        mPageList.add(view2);
        mPageList.add(view3);

        // 预加载
        mViewPager.setOffscreenPageLimit(mPageList.size());

        mPageAdapter = new BasePageAdapter(mPageList);
        mViewPager.setAdapter(mPageAdapter);
    }
}

3.2.4、成果展现

<font face= 黑体 > 当初咱们曾经实现类滑动,然而上面的小圆点并没有随着咱们的滑动而变动。

3.3、实现小圆点逻辑

<font face= 黑体 > 小圆点的逻辑很简略,只须要去监听 ViewPager 的页面变动,而后动静的扭转小圆点的图片就能够了。

<font face= 黑体 > 监听 ViewPager 的页面变动:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }

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

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

<font face= 黑体 > 动静抉择小圆点:

private void swlectPoint(int position) {switch (position) {
        case 0:
            iv_guide_point_1.setImageResource(R.drawable.img_guide_point_p);
            iv_guide_point_2.setImageResource(R.drawable.img_guide_point);
            iv_guide_point_3.setImageResource(R.drawable.img_guide_point);
            break;
        case 1:
            iv_guide_point_1.setImageResource(R.drawable.img_guide_point);
            iv_guide_point_2.setImageResource(R.drawable.img_guide_point_p);
            iv_guide_point_3.setImageResource(R.drawable.img_guide_point);
            break;
        case 2:
            iv_guide_point_1.setImageResource(R.drawable.img_guide_point);
            iv_guide_point_2.setImageResource(R.drawable.img_guide_point);
            iv_guide_point_3.setImageResource(R.drawable.img_guide_point_p);
            break;
    }
}

<font face= 黑体 > 成果展现:

<font face= 黑体 > 能够看到,上面的小圆点曾经随着咱们的滑动而动静的变动了。

3.4、实现帧动画

<font face= 黑体 > 帧动画的实质就是将一张张的图片,通过代码对这些图片进行间断的流动,从而造成动画。帧动画的实现能够通过 xml 形式 实现和 代码形式 实现,咱们这里利用的是 xml 形式 来实现的。

3.4.1、在 /res/drawable 新建 animation-list

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">

    <item android:drawable="@mipmap/img_star_1" android:duration="2000"/>
    <item android:drawable="@mipmap/img_star_2" android:duration="2000"/>
    <item android:drawable="@mipmap/img_star_3" android:duration="2000"/>
    <item android:drawable="@mipmap/img_star_4" android:duration="2000"/>
    <item android:drawable="@mipmap/img_star_5" android:duration="2000"/>
    <item android:drawable="@mipmap/img_star_6" android:duration="2000"/>
    <item android:drawable="@mipmap/img_star_7" android:duration="2000"/>

</animation-list>

3.4.2、在布局中引入

<ImageView
    android:id="@+id/iv_guide_smile"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="@drawable/guide_smile_anim" />

3.4.3、开启帧动画

<font face= 黑体 > 开启帧动画须要获取背景,并将其强转成 AnimationDrawable。

 // 帧动画
iv_guide_star = view1.findViewById(R.id.iv_guide_star);
iv_guide_night = view2.findViewById(R.id.iv_guide_night);
iv_guide_smile = view3.findViewById(R.id.iv_guide_smile);

// 播放帧动画
AnimationDrawable animStar = (AnimationDrawable) iv_guide_star.getBackground();
if (!animStar.isRunning()) {animStar.start();
}

AnimationDrawable animNight = (AnimationDrawable) iv_guide_night.getBackground();
if (!animNight.isRunning()) {animNight.start();
}

AnimationDrawable animSmile = (AnimationDrawable) iv_guide_smile.getBackground();
if (!animSmile.isRunning()) {animSmile.start();
}

3.4.4、成果展现

3.5、实现音乐播放

<font face= 黑体 > 音乐播放是用 MediaPlayer 实现的,我这里封装了一个 MediaPlayerManager 音乐播放工具类,其实就是对 MediaPlayer 一些 API 的调用,源码中会提供这个工具类,这里就不细讲了,播放的音乐文件是存储在本地 raw 文件夹下的。

/**
* 播放音乐
 */
private void startMusic() {mGuideMusic = new MediaPlayerManager();
    mGuideMusic.setLooping(true);
    final AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.guide);
    mGuideMusic.startPlay(file);

    mGuideMusic.setOnComplteionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {mGuideMusic.startPlay(file);
        }
    });
}

3.6、属性动画

<font face= 黑体 > 当咱们在播放音乐的时候,须要让音乐图片始终旋转,咱们这里就用属性动画的 ObjectAnimator 对象动画来实现。

public class AnimUtils {

    /**
     * 旋转动画
     * @param view
     * @return
     */
    public static ObjectAnimator rotation(View view) {ObjectAnimator mAnim = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
        mAnim.setDuration(2 * 1000);
        mAnim.setRepeatMode(ValueAnimator.RESTART);
        mAnim.setRepeatCount(ValueAnimator.INFINITE);
        mAnim.setInterpolator(new LinearInterpolator());
        return mAnim;
    }

}

<font face= 黑体 > 在播放音乐的时候开启:

 private void startMusic() {mGuideMusic = new MediaPlayerManager();
    mGuideMusic.setLooping(true);
    final AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.guide);
    mGuideMusic.startPlay(file);

    mGuideMusic.setOnComplteionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {mGuideMusic.startPlay(file);
        }
    });

    // 旋转动画
    mAnim = AnimUtils.rotation(iv_music_switch);
    mAnim.start();}

<font face= 黑体 > 成果展现:

能够看到音乐图片曾经在旋转了。

四、MainActivity 残缺代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView iv_music_switch;
    private TextView tv_guide_skip;
    private ImageView iv_guide_point_1;
    private ImageView iv_guide_point_2;
    private ImageView iv_guide_point_3;
    private ViewPager mViewPager;

    private View view1;
    private View view2;
    private View view3;

    private List<View> mPageList = new ArrayList<>();
    private BasePageAdapter mPageAdapter;

    private ImageView iv_guide_star;
    private ImageView iv_guide_night;
    private ImageView iv_guide_smile;

    private MediaPlayerManager mGuideMusic;

    private ObjectAnimator mAnim;

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

        initView();}

    private void initView() {iv_music_switch = findViewById(R.id.iv_music_switch);
        tv_guide_skip = findViewById(R.id.tv_guide_skip);
        iv_guide_point_1 = findViewById(R.id.iv_guide_point_1);
        iv_guide_point_2 = findViewById(R.id.iv_guide_point_2);
        iv_guide_point_3 = findViewById(R.id.iv_guide_point_3);
        mViewPager = findViewById(R.id.mViewPager);

        iv_music_switch.setOnClickListener(this);

        view1 = View.inflate(this, R.layout.layout_pager_guide_1, null);
        view2 = View.inflate(this, R.layout.layout_pager_guide_2, null);
        view3 = View.inflate(this, R.layout.layout_pager_guide_3, null);

        mPageList.add(view1);
        mPageList.add(view2);
        mPageList.add(view3);

        // 预加载
        mViewPager.setOffscreenPageLimit(mPageList.size());

        mPageAdapter = new BasePageAdapter(mPageList);
        mViewPager.setAdapter(mPageAdapter);

        // 帧动画
        iv_guide_star = view1.findViewById(R.id.iv_guide_star);
        iv_guide_night = view2.findViewById(R.id.iv_guide_night);
        iv_guide_smile = view3.findViewById(R.id.iv_guide_smile);

        // 播放帧动画
        AnimationDrawable animStar = (AnimationDrawable) iv_guide_star.getBackground();
        animStar.start();

        AnimationDrawable animNight = (AnimationDrawable) iv_guide_night.getBackground();
        animNight.start();

        AnimationDrawable animSmile = (AnimationDrawable) iv_guide_smile.getBackground();
        animSmile.start();

        // 小圆点逻辑
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }

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

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

        // 歌曲的逻辑
        startMusic();}

    /**
     * 播放音乐
     */
    private void startMusic() {mGuideMusic = new MediaPlayerManager();
        mGuideMusic.setLooping(true);
        final AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.guide);
        mGuideMusic.startPlay(file);

        mGuideMusic.setOnComplteionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {mGuideMusic.startPlay(file);
            }
        });

        // 旋转动画
        mAnim = AnimUtils.rotation(iv_music_switch);
        mAnim.start();}

    /**
     * 动静抉择小圆点
     *
     * @param position
     */
    private void seletePoint(int position) {switch (position) {
            case 0:
                iv_guide_point_1.setImageResource(R.drawable.img_guide_point_p);
                iv_guide_point_2.setImageResource(R.drawable.img_guide_point);
                iv_guide_point_3.setImageResource(R.drawable.img_guide_point);
                break;
            case 1:
                iv_guide_point_1.setImageResource(R.drawable.img_guide_point);
                iv_guide_point_2.setImageResource(R.drawable.img_guide_point_p);
                iv_guide_point_3.setImageResource(R.drawable.img_guide_point);
                break;
            case 2:
                iv_guide_point_1.setImageResource(R.drawable.img_guide_point);
                iv_guide_point_2.setImageResource(R.drawable.img_guide_point);
                iv_guide_point_3.setImageResource(R.drawable.img_guide_point_p);
                break;
        }
    }

    @Override
    public void onClick(View view) {switch (view.getId()) {
            case R.id.iv_music_switch:
                if (mGuideMusic.MEDIA_STATUS == MediaPlayerManager.MEDIA_STATUS_PAUSE) {mAnim.start();
                    mGuideMusic.continuePlay();
                    iv_music_switch.setImageResource(R.drawable.img_guide_music);
                } else if (mGuideMusic.MEDIA_STATUS == MediaPlayerManager.MEDIA_STATUS_PLAY) {mAnim.pause();
                    mGuideMusic.pausePlay();
                    iv_music_switch.setImageResource(R.drawable.img_guide_music_off);
                }
                break;
        }
    }

    @Override
    protected void onDestroy() {super.onDestroy();
        mGuideMusic.stopPlay();}

}

五、源码

<font face= 黑体 > 源码已上传至 github,有须要的能够去下载。

正文完
 0