Android Studio - Reproductor de video simple

1. Análisis de interfaz

        Tres interfaces: interfaz principal, interfaz de lista de videos e interfaz de reproducción de video, como se muestra en la siguiente figura:

 2. Ideas de implementación

        (1) Diseño de la interfaz principal

           Es muy simple, solo un fondo y un control, luego configure un evento de clic para el control y luego salte a la interfaz de la lista de videos

   interfaz de actividad_principal.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=".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>

 Clase MainActivity.java

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) Interfaz de lista de videos

        Cada salto necesita crear una nueva actividad, así que primero cree una MovieActivity y luego establezca la lista en el archivo xml correspondiente, porque el control utilizado en esta interfaz es RecycleView, que es un control nuevo, por lo que debe agregar manualmente el elemento de dependencias. .

        Agregue dependencias en el archivo app/build.gradle y agregue la siguiente declaración en las dependencias de cierre

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

        Tenga en cuenta que la versión agregada debe ser coherente con la versión que se muestra en el código anterior en este archivo; de lo contrario, aparecerá en rojo y el proyecto no se ejecutará. 

 archivo actividad_película.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=".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>

         El cuadro de lista es como se muestra a continuación, por lo que puede ver en la imagen que todavía necesitamos diseñar cada fila en la lista de interfaz

         Cree un nuevo archivo xml llamado movie_item_layout.ml, de la siguiente manera:

<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>

        Cuando estaba escribiendo, cometí un pequeño error, es decir, agregué una imagen de fondo a esta interfaz y luego hice que los datos de cada fila se mostraran en esta imagen de fondo sin importar cómo se diseñaron las fotos en la lista, y luego, se mostrarán otros datos de One en otra imagen, al igual que la paginación, que es extremadamente fea, por lo que si configura la imagen de fondo en el archivo activity_movie.xml, no necesita configurarla nuevamente en este archivo xml. es el anterior Un subdiseño para una interfaz.

        

        Después de configurar la interfaz, analizamos lo siguiente. ¿Cuáles son los atributos de la interfaz de la lista de videos? Hay nombres de videos y direcciones de videos. Debido a que las fotos utilizadas en este diseño están todas unificadas, no es necesario escribirlas en los atributos

        Así que crea la clase de entidad Movie.java aquí

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;
    }
}

        Luego es necesario personalizar un adaptador para RecyclerView, así que cree una clase de adaptador, el código es el siguiente:

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 hereda RecyclerView.Adapter y especifica el tipo genérico como MovieAdapter.ViewHolder. Debido a que hereda la clase RecyclerView.Adapter, los tres métodos de onCreateViewHolder(), onBindViewHolder y getItemCount() deben reescribirse.

        Debido a que desea leer la tarjeta SD y acceder a los recursos de video en la red, debe configurar el permiso de lectura en el archivo androidmanifest.xml, de la siguiente manera:

 <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"/>

        Después de la configuración, es posible que no se obtengan los permisos. Cuando lo escribí, no pude leer los datos, luego verifiqué la información y finalmente la saqué. Debería ser que el nuevo software AS no solo necesita agregar permisos, pero también configure una clase de permiso separada, y luego llamarla cuando lea los datos funciona bien. Específicamente de la siguiente manera

Clase PermissionUtils.java

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);
        }
    }
}

        En este punto, la configuración está básicamente completada y el siguiente paso es controlar MovieActivity.java. Esta interfaz es para mostrar los datos de la interfaz de la lista, de la siguiente manera:

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) Interfaz de reproducción

        Cree una nueva Actividad . Esta interfaz es para obtener el nombre del video y la dirección del video pasados ​​de la lista, y luego reproducirlo. El código específico es el siguiente:

actividad_juego.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();
    }
}

        La carga de videos en tres rutas diferentes (red/dentro de la carpeta/video en el simulador) se muestra a continuación. No se describirán los puntos de conocimiento específicos, y hay notas sobre el código básico. 

 

 

Supongo que te gusta

Origin blog.csdn.net/m0_61793503/article/details/130063998
Recomendado
Clasificación