Android Studio - Simple Video Player

1. Interface analysis

        Three interfaces: main interface, video list interface, and video playback interface, as shown in the figure below:

 2. Implementation idea

        (1) Main interface design

           It's very simple, just a background and a control, then set a click event for the control, and then jump to the video list interface

   activity_main.xml interface

<LinearLayout 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"
    tools:context=".MainActivity"
    android:background="@drawable/action"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="进入视频列表"
        android:textColor="@color/white"
        android:textStyle="bold"
        android:textSize="30sp"
        android:layout_marginTop="50dp"
        android:layout_gravity="center"
        android:id="@+id/btlogin"/>

</LinearLayout>

 MainActivity.java class

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=(TextView) findViewById(R.id.btlogin);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(MainActivity.this,MovieActivity.class);
                startActivity(intent);
            }
        });
    }
}

         (2) Video list interface

        Every jump needs to create a new Activity, so first create a MovieActivity, and then set the list in the corresponding xml file, because the control used in this interface is RecycleView, which is a new control, so you need to manually add dependencies item.

        Add dependencies in the app/build.gradle file, and add the following statement in the closure dependencies

implementation 'com.android.support:recyclerview-v7:33.0.0'

        Note that the added version must be consistent with the version displayed in the above code in this file, otherwise it will report red and the project will not run. 

 activity_movie.xml file

<LinearLayout 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"
    tools:context=".MovieActivity"
    android:orientation="vertical"
    android:background="@drawable/back">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="视频列表"
        android:textSize="30sp"
        android:gravity="center"
        android:textStyle="bold"
        android:background="@color/black"
        android:textColor="@color/white"/>
    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerview"/>
</LinearLayout>

         The list frame is as shown below, so you can see from the picture that we still need to design each row in the interface list

         Create a new xml file named movie_item_layout.ml, as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
        <ImageView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:background="@drawable/image"
            android:id="@+id/movievideo"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/moviename"
            android:text="dianyinm"
            android:textSize="25sp"
            android:layout_marginLeft="10dp"
            android:layout_gravity="center_vertical"/>
</LinearLayout>

        When I was writing, I made a small mistake, that is, I added a background image to this interface, and then caused the data in each row to be displayed on this background image no matter how the photos in the list were designed, and then another One data will be displayed on another picture, just like pagination, which is extremely ugly, so if you set the background picture in the activity_movie.xml file, you don’t need to set it again in this xml file. This interface is above A sublayout for an interface.

        

        After the interface is set up, we analyze the following. What are the attributes of the video list interface? There are video names and video addresses. Because the photos used in this design are all unified, so there is no need to write them in the attributes.

        So create the entity class Movie.java here

public class Movie {
    private String moviename;
    private String movieuri;
    public Movie(String moviename,String movieuri){
        this.moviename=moviename;
        this.movieuri=movieuri;
    }
    public String getMoviename(){
        return moviename;
    }
    public String getMovieuri(){
        return movieuri;
    }
}

        Then it is necessary to customize an adapter for RecyclerView, so create an adapter class, the code is as follows:

MovieAdapter.java

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
    List<Movie> mymovieList;
    public class ViewHolder extends RecyclerView.ViewHolder{
        View movieview;
        TextView moviename;
        public ViewHolder(@NonNull View view){
            super(view);
            moviename=itemView.findViewById(R.id.moviename);
            movieview=view;
        }
    }
    //利用适配器的构造函数传入要展示的数据
    public MovieAdapter(List<Movie> mymovieList){
        this.mymovieList=mymovieList;
    }
    //创建实例,把每一行的布局加载进来,创建一个ViewHolder实例,将布局传入到构造函数中,最后将实例返回
    public MovieAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item_layout,parent,false);
        final ViewHolder holder=new ViewHolder(view);
        //单击任意视频跳转到播放界面
        holder.movieview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //获取位置
                int position=holder.getAdapterPosition();
                Movie movie=mymovieList.get(position);
                String mymoviename=movie.getMoviename();
                String mymovievideo=movie.getMovieuri();
                //获取位置后跳转
                Intent intent=new Intent(view.getContext(),PlayActivity.class);
                //然后根据位置传递信息
                intent.putExtra("my",mymoviename);
                intent.putExtra("movieurl",mymovievideo);
                view.getContext().startActivity(intent);
            }
        });
        return holder;
    }
    //对recyclerview中子项目进行赋值,通过位置得到当前的实例,然后电影名和视频显示在控件上
    public void onBindViewHolder(@NonNull MovieAdapter.ViewHolder holder,int position){
        Movie movie=mymovieList.get(position);
        holder.moviename.setText(movie.getMoviename());
    }
    public int getItemCount(){
        return mymovieList.size();
    }
}

        MovieAdapter inherits RecyclerView.Adapter, and specifies the generic type as MovieAdapter.ViewHolder. Because it inherits the RecyclerView.Adapter class, the three methods of onCreateViewHolder(), onBindViewHolder, and getItemCount() must be rewritten.

        Because you want to read the SD card and access the video resources on the network, you need to set the read permission in the androidmanifest.xml file, as follows:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions"/>
    <uses-permission android:name="android.permission.INTERNET"/>

        After the setting, the permissions may not be obtained. When I wrote it, I could not read the data, and then checked the information, and finally got it out. It should be that the new AS software not only needs to add permissions, but also set up a separate permission. class, and then calling it when reading data works just fine. Specifically as follows

PermissionUtils.java class

public class PermissionUtils {
    // Storage Permissions
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};
    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);
        }
    }
}

        At this point, the setting is basically completed, and the next step is to control MovieActivity.java. This interface is to display the data of the list interface, as follows:

MovieActivity.java

public class MovieActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    List<Movie> movieList;
    MovieAdapter movieAdapter;
    private static final String TAG="MovieActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie);
        recyclerView=(RecyclerView) findViewById(R.id.recyclerview);
        initData();
    }
    public void initData(){
        //建立动态数组存放数据
        movieList=new ArrayList<>();
        //获取网络视频
        Movie firstmovie=new Movie("明星大侦探","http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4");
        movieList.add(firstmovie);
        Movie secondmovie=new Movie("哈哈哈哈哈","https://www.dglydz.com/mov-hahahahahadierji.html");
        movieList.add(secondmovie);
        //获取本工程中的视频
        Movie thirdmovie=new Movie("等到苦尽甘来时,待我给你讲来时的路","android.resource://"+getPackageName()+"/"+R.raw.read);
        movieList.add(thirdmovie);
        Movie forthmovie=new Movie("阳光开朗孔乙己","android.resource://"+getPackageName()+"/"+R.raw.why);
        movieList.add(forthmovie);
        //获取模拟器中的视频
        Movie fifthmovie=new Movie("我会等","file:///storage/emulated/0/Pictures/waitting.mp4");
        movieList.add(fifthmovie);
        Movie sixthmovie=new Movie("稻香","file:///storage/emulated/0/Pictures/jay.mp4");
        movieList.add(sixthmovie);
        //将视频显示在控件上
        movieAdapter=new MovieAdapter(movieList);
        StaggeredGridLayoutManager layoutManager=new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(movieAdapter);
    }
}

        (3) Play interface

        Create a new Activity . This interface is to obtain the video name and video address passed from the list, and then play it. The specific code is as follows:

activity_play.xml

<LinearLayout 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"
    tools:context=".PlayActivity"
    android:orientation="vertical"
    android:background="@drawable/back">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tvmovename"
        android:text="name"
        android:layout_marginTop="30dp"
        android:textSize="40sp"
        android:gravity="center"
        android:textStyle="bold"/>
    <VideoView
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:id="@+id/vvmovie"
        android:layout_marginTop="10dp"/>
</LinearLayout>

PlayActivity.java

public class PlayActivity extends AppCompatActivity {
     private TextView tvvedioname;
     private VideoView videoView;
     //媒体控制器
    private MediaController mediaController;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_play);
        tvvedioname= findViewById(R.id.tvmovename);
        videoView=findViewById(R.id.vvmovie);
        mediaController=new MediaController(this);
        initData();
        verifyStoragePermissions(this);
    }
    public void initData(){
        //获取从音乐列表传过来的视频名称和地址
        String videoname=getIntent().getStringExtra("my");
        String videouri=getIntent().getStringExtra("movieurl");
        //String videourl= Environment.getExternalStorageDirectory().getAbsolutePath()+"/jay.mp4";
        //Log.i("PlayActivity","videourl="+videourl);
        //将视频名称显示在文本框中,将视频地址关联到播放器中
        tvvedioname.setText(videoname);
        videoView.setVideoPath(videouri);
        //videoView.setVideoPath(videourl);
        //将视频播放器和媒体控制柄关联起来
        videoView.setMediaController(mediaController);
        //媒体控制柄和视频播放器关联起来
        mediaController.setMediaPlayer(videoView);
        //启动视频播放器播放视频
        videoView.start();
    }
}

        The loading of videos in three different paths (network/inside the folder/video in the simulator) is shown below. The specific knowledge points will not be described, and there are notes on the basic code. 

 

 

Guess you like

Origin blog.csdn.net/m0_61793503/article/details/130063998