《移动应用程序设计基础》实验6 安卓动画与视音频播放器的实现
实验名称:
实验6 安卓动画与视音频播放器的实现
所使用的工具软件及环境:
JDK1.8,Android Studio
一、实验目的:
【目的】
通过本实验,使得学生掌握导航的制作基本方法,掌握安卓动画和多媒体播放器的制作。
【实验设备】
安装Android Studio的电脑一台,同时安装模拟器或者Android手机真机一台,保证网络畅通。
二、实验内容:
【实验内容】
- 实现底部导航功能,包括Tween动画、Frame动画、音频播放、视频播放四个按键。
- 实现动画功能,其中Tween动画可在界面选择四种类型的动画效果。
- 实现音频播放。
- 实现视频播放。
【实验过程】
底部导航实现过程按如下实例:
1.主要布局文件activity_main.xml
<?xml version="0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="edu.zstu.multipage.MainActivity"> <!--容器,用来操作Fragment的增加替换等--> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/> <!--底部菜单栏--> <LinearLayout android:layout_width="match_parent" android:layout_height="70dp" android:orientation="horizontal" android:background="@android:color/darker_gray" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> <LinearLayout android:layout_width="0dp" android:orientation="vertical" android:layout_height="match_parent" android:layout_weight="1"> <ImageButton android:id="@+id/home_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="5dp" android:src="@drawable/home_press" android:background="@android:color/transparent" /> |
<TextView android:id="@+id/home_txt" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="主页" android:textColor="@android:color/holo_red_dark" android:gravity="center"/> </LinearLayout> <LinearLayout android:layout_width="0dp" android:orientation="vertical" android:layout_height="match_parent" android:layout_weight="1"> <ImageButton android:id="@+id/info_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="5dp" android:src="@drawable/info" android:background="@android:color/transparent"/> <TextView android:id="@+id/info_txt" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="消息" android:textColor="@android:color/black" android:gravity="center" /> </LinearLayout> </LinearLayout> </RelativeLayout> |
2.第一Fragment和第二个Fragment:fragment_first.xml(为例)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="FirstPage" android:textSize="24sp" android:gravity="center|center"/> </LinearLayout> |
3. MainActivity
3.1声明部分
ImageButton homeBtn,infoBtn;
TextView homeTxt,infoTxt;
Context mContext;
FragmentTransaction transaction;
3.2 初始化
mContext = this;
homeBtn = (ImageButton)findViewById(R.id.home_btn);
infoBtn = (ImageButton)findViewById(R.id.info_btn);
homeTxt = (TextView)findViewById(R.id.home_txt);
infoTxt = (TextView)findViewById(R.id.info_txt);
//取得Fragment管理器
Fragment firstFragment = new FirstFragment();
transaction =getSupportFragmentManager().beginTransaction();
//默认下将firstFragment添加到容器中
transaction.add(R.id.fragment_container,firstFragment);
//提交事务
transaction.commit();
3.3按钮点击(实现其中一个按钮,另一个按钮参照完成)
//背景替换
infoBtn.setImageResource(R.drawable.info);
infoTxt.setTextColor(ContextCompat
.getColor(mContext,android.R.color.black));
homeBtn.setImageResource(R.drawable.home_press);
homeTxt.setTextColor(ContextCompat
.getColor(mContext,android.R.color.holo_red_dark));
//取得Fragment管理器
Fragment firstFragment = new FirstFragment();
//将新建的firstFragment替换容器中的其他片段,这将重新加载布局文件。
transaction =getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container,firstFragment);
transaction.commit();
3.4 FirstFragment .java(SecondFragment类同)
public class FirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_first,null);
return v;
}
}
4.运行结果
编辑
按实验要求分别实现Tween动画、Frame动画、音频播放和视频播放四个导航键的功能。
三、实验结果测试(完整所有代码在资源下载压缩包中,文章结尾有资源下载链接)
共5个java文件和5个相对应的xml布局文件,其中还有一些资源文件。
编辑
主要的java代码:
//MainActivity.java package com.example.a6; import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentTransaction; public class MainActivity extends AppCompatActivity { //澹版槑 ImageButton homeBtn,infoBtn,musicBtn,videoBtn; TextView homeTxt,infoTxt,musicTxt,videoTxt; Context mContext; FragmentTransaction transaction; private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //鍒濆鍖� init(); verifyStoragePermissions(this); homeBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //鑳屾櫙鏇挎崲 infoBtn.setImageResource(R.drawable.info); infoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); musicBtn.setImageResource(R.drawable.music1); musicTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); videoBtn.setImageResource(R.drawable.video1); videoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); homeBtn.setImageResource(R.drawable.home_press); homeTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.holo_red_dark)); //鍙栧緱Fragment绠$悊鍣� Fragment_First firstFragment = new Fragment_First(); //灏嗘柊寤虹殑firstFragment鏇挎崲瀹瑰櫒涓殑鍏朵粬鐗囨锛岃繖灏嗛噸鏂板姞杞藉竷灞�鏂囦欢銆� transaction =getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container,firstFragment); transaction.commit(); } }); infoBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //鑳屾櫙鏇挎崲 infoBtn.setImageResource(R.drawable.info_press); infoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.holo_red_dark)); homeBtn.setImageResource(R.drawable.home); homeTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); musicBtn.setImageResource(R.drawable.music1); musicTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); videoBtn.setImageResource(R.drawable.video1); videoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); //鍙栧緱Fragment绠$悊鍣� Fragment_Second secondFragment = new Fragment_Second(); //灏嗘柊寤虹殑firstFragment鏇挎崲瀹瑰櫒涓殑鍏朵粬鐗囨锛岃繖灏嗛噸鏂板姞杞藉竷灞�鏂囦欢銆� transaction =getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container,secondFragment); transaction.commit(); } }); musicBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { infoBtn.setImageResource(R.drawable.info); infoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); homeBtn.setImageResource(R.drawable.home); homeTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); musicBtn.setImageResource(R.drawable.music2); musicTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.holo_red_dark)); videoBtn.setImageResource(R.drawable.video1); videoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); Fragment_Third ThirFragment=new Fragment_Third(); transaction =getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container,ThirFragment); transaction.commit(); } }); videoBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { infoBtn.setImageResource(R.drawable.info); infoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); homeBtn.setImageResource(R.drawable.home); homeTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); musicBtn.setImageResource(R.drawable.music1); musicTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.black)); videoBtn.setImageResource(R.drawable.video2); videoTxt.setTextColor(ContextCompat .getColor(mContext,android.R.color.holo_blue_dark)); Fragment_Fourth FourthFragment=new Fragment_Fourth(); transaction =getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container,FourthFragment); transaction.commit(); } }); } public static void verifyStoragePermissions(Activity activity) { // Check if we have write permission int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don't have permission so prompt the user ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); } } private void init() { mContext = this; homeBtn = (ImageButton)findViewById(R.id.home_btn); infoBtn = (ImageButton)findViewById(R.id.info_btn); homeTxt = (TextView)findViewById(R.id.home_txt); infoTxt = (TextView)findViewById(R.id.info_txt); musicBtn=(ImageButton) findViewById(R.id.musicBtn); musicTxt=(TextView)findViewById(R.id.musicTxt); videoBtn=(ImageButton)findViewById(R.id.videoBtn); videoTxt=(TextView)findViewById(R.id.videoTxt); //鍙栧緱Fragment绠$悊鍣� Fragment_First firstFragment = new Fragment_First(); transaction =getSupportFragmentManager().beginTransaction(); //榛樿涓嬪皢firstFragment娣诲姞鍒板鍣ㄤ腑 transaction.add(R.id.fragment_container,firstFragment); //鎻愪氦浜嬪姟 transaction.commit(); } }
//Fragment_First.java package com.example.a6; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.media.Image; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.widget.AdapterView; import android.widget.Button; import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Fragment_First extends Fragment { private ImageView image; Animation anim; // Context mContext; private Button rotate,translate,alpha,scale; private Context context; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.context=getActivity(); } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_first,container,false); image=(ImageView) view.findViewById(R.id.tween); rotate=(Button) view.findViewById(R.id.rotate); translate=(Button) view.findViewById(R.id.translate); alpha=(Button) view.findViewById(R.id.alpha); scale=(Button) view.findViewById(R.id.scale); setClickListener(); Animation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(5000); image.setAnimation(animation); return view; } private void setClickListener() { rotate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { anim = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(5000); //该方法用于设置一个动画效果执行完毕后,View对象保留在终止的位置 /* animation.setFillAfter(true);*/ image.startAnimation(anim); Toast.makeText(context, "旋转", Toast.LENGTH_SHORT).show(); } }); alpha.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f); alphaAnimation.setDuration(3000); AnimationSet animationSet = new AnimationSet(false); animationSet.addAnimation(alphaAnimation); // 开始播放动画。 image.startAnimation(animationSet); Toast.makeText(context, "透明", Toast.LENGTH_SHORT).show(); } }); scale.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { anim = new ScaleAnimation(0.0f, 1.2f, 0.0f, 1.2f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(2000);//所有属性可以通过set函数设置 image.startAnimation(anim); Toast.makeText(context, "缩放", Toast.LENGTH_SHORT).show(); } }); translate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { anim = new TranslateAnimation(0.0f, 1200f, 0f, 0f); anim.setDuration(2000); image.startAnimation(anim); Toast.makeText(context, "移动", Toast.LENGTH_SHORT).show(); } }); } }
//Fragment_Second.java package com.example.a6; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; public class Fragment_Second extends Fragment { private ImageView ivImage; private Button start,stop; private AnimationDrawable anim; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_second,null); ivImage = (ImageView) v.findViewById(R.id.frame_image); start=(Button) v.findViewById(R.id.startframe); stop=(Button) v.findViewById(R.id.stopframe); ivImage.setBackgroundResource(R.drawable.frame); anim = (AnimationDrawable) ivImage.getBackground(); ivImage.post( new Runnable() { @Override public void run() { anim.start(); } }); setClickListener(); return v; } private void setClickListener() { stop.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { anim.stop(); } }); start.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { anim.start(); } }); } }
//Fragment_Third.java package com.example.a6; import android.content.Context; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.io.IOException; public class Fragment_Third extends Fragment { private Button play,pause,stop,replay; private ImageView music; private MediaPlayer mediaPlayer; private Context context; Animation anim; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); context=getActivity(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment__third,container,false); play=(Button) view.findViewById(R.id.start); pause=(Button) view.findViewById(R.id.pause); replay=(Button) view.findViewById(R.id.replay); stop=(Button) view.findViewById(R.id.stop); music=(ImageView) view.findViewById(R.id.music3); play.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { anim = new RotateAnimation(0, 3600, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(50000); anim.setFillAfter(true); music.startAnimation(anim); mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource("/sdcard/Music/love.mp3"); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepareAsync(); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); Toast.makeText(context, "开始播放", Toast.LENGTH_SHORT).show(); play.setEnabled(false); } }); mediaPlayer.setLooping(true); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { play.setEnabled(true); } }); mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.seekTo(0); Toast.makeText(context, "重新播放", Toast.LENGTH_SHORT).show(); pause.setText("暂停"); //return; } return false; } }); } catch (IOException e) { e.printStackTrace(); Toast.makeText(context, "播放失败", Toast.LENGTH_SHORT).show(); } } }); replay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.seekTo(0); Toast.makeText(context, "重新播放", Toast.LENGTH_SHORT).show(); pause.setText("暂停"); //return; } } }); pause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(pause.getText().toString().trim().equals("继续")){ pause.setText("暂停"); mediaPlayer.start(); Toast.makeText(context, "继续播放", Toast.LENGTH_SHORT).show(); // return; }else if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.pause(); pause.setText("继续"); Toast.makeText(context, "暂停播放", Toast.LENGTH_SHORT).show(); } } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer=null; play.setEnabled(true); Toast.makeText(context, "停止播放", Toast.LENGTH_SHORT).show(); } } }); return view; } private void setOnclick() { } public void onDestroy() { if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer=null; } super.onDestroy(); } }
//Fragment_Fourth.java package com.example.a6; import android.content.Context; import android.media.MediaPlayer; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; import java.io.IOException; public class Fragment_Fourth extends Fragment { private MediaPlayer mediaPlayer; private SurfaceView sv_main_surface; private TextView tv_start; private TextView tv_end; private SeekBar seekbar; private Context context; private ImageButton play; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); context=getActivity(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment__fourth,container,false); sv_main_surface = (SurfaceView) view.findViewById(R.id.sv_main_surface); tv_start = (TextView)view.findViewById(R.id.tv_start); tv_end = (TextView)view. findViewById(R.id.tv_end); seekbar = (SeekBar) view.findViewById(R.id.seekbar); play=(ImageButton)view.findViewById(R.id.bt_media); //设置监听 seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { //获取音乐总时间 int duration2=mediaPlayer.getDuration()/1000; //获取音乐当前播放的位置 int position=mediaPlayer.getCurrentPosition(); //开始时间 tv_start.setText(calculateTime(position/1000)); //结束时间 tv_end.setText(calculateTime(duration2)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress=seekBar.getProgress(); //在当前位置播放 mediaPlayer.seekTo(progress); } }); play.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //判断音频文件是否为空 if(mediaPlayer==null){ //为空则创建音乐文件并播放改变按钮样式 //播放内存卡中文件 mediaPlayer=new MediaPlayer(); try { mediaPlayer.setDataSource("/sdcard/Movies/猫和老鼠.mp4"); //准备 mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } //将媒体播放器捕捉的画面展示到SurfaceView mediaPlayer.setDisplay(sv_main_surface.getHolder()); //开始播放 mediaPlayer.start(); //设置button play.setImageResource(android.R.drawable.ic_media_pause); //获取音乐总时间 int duration=mediaPlayer.getDuration(); //将音乐总时间设置为SeekBar的最大值 seekbar.setMax(duration); //线程修改时间值 new MyThread().start(); //音乐文件正在播放,则暂停并改变按钮样式 }else if(mediaPlayer.isPlaying()){ mediaPlayer.pause(); play.setImageResource(android.R.drawable.ic_media_play); }else{ //启动播放 mediaPlayer.start(); play.setImageResource(android.R.drawable.ic_media_pause); } } }); return view; } public void isPlayOrPause(View view){ } class MyThread extends Thread{ @Override public void run() { super.run(); while(seekbar.getProgress()<=seekbar.getMax()){ //获取音乐当前播放的位置 int position=mediaPlayer.getCurrentPosition(); //放入SeekBar中 seekbar.setProgress(position); } } } //计算播放时间 public String calculateTime(int time){ int minute; int second; if(time>=60){ minute=time/60; second=time%60; return minute+":"+second; }else if(time<60){ second=time; return "0:"+second; } return null; } }
实验结果截图:
编辑编辑编辑
编辑编辑编辑
编辑编辑
心得与体会:
本次实验,学习了Fragment的用法以及学会Tween四种alpha,translate,rotate,scale动画、Frame逐帧动画和音频播放,视频播放等。通过此次实验,学习到的知识颇多,对android的开发有了进一步的学习。
下载资源包链接:
https://download.csdn.net/download/weixin_48388330/76309689
资源中的图片以及内容只适用与学习