Android文件列表RecyclerView中点击视频播放

Android文件列表RecyclerView中点击视频播放

1. app gradle

dependencies {

implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.exoplayer:exoplayer:2.11.1'

2. AndroidManifest配置

<?xml version="1.0" encoding="utf-8"?>
:android="http://schemas.android.com/apk/res/android"
    package="com.example.myitemtouch">
    
    :allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        :name=".MySimpleExoPlayer" 
        	android:configChanges="orientation">
        >
        :name=".MainActivity"
            android:configChanges="orientation">
            -filter>
                :name="android.intent.action.MAIN" />

                :name="android.intent.category.LAUNCHER" />
            -filter>
        >
    >
    -permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
>

3. activity布局

MainActivity

package com.example.myitemtouch;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private List<MyFile> myFileList = new ArrayList<>();
    private OnItemClickListener onItemClickListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recyclerview);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // specify an adapter (see also next example)
        adapter = new MyAdapter(myFileList);
        recyclerView.setAdapter(adapter);
        onItemClickListener = new OnItemClickListener() {
            @Override
            public void onItemClick(MyAdapter.MyViewHolder viewHolder) {
                Log.d("Main","onItemClick");
                //RecyclerView.ViewHolder mViewHolder;
                MyAdapter.MyViewHolder mViewHolder;
                mViewHolder = viewHolder;
                String vhText = (String) mViewHolder.textView.getText();
                Log.d("Main",vhText);
                Intent intent = new Intent(MainActivity.this,MySimpleExoPlayer.class);
                intent.putExtra("fileName",vhText);
                startActivity(intent);
            }
        };
        recyclerView.addOnItemTouchListener(new RecyclerItemTouchListener(recyclerView) {
        });


        initMyFile(Environment.getExternalStorageDirectory());
    }

    private void initMyFile(File externalStorageDirectory) {
        myFileList.clear();
        List<File> files = new ArrayList<>();
        Collections.addAll(files, externalStorageDirectory.listFiles());
        for (File file : files) {
            String fileName = file.getName();
            MyFile myFile = new MyFile(fileName);
            myFileList.add(myFile);
        }
        adapter.notifyDataSetChanged();
    }


    private class mySimpleGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onSingleTapUp(MotionEvent event) {
            Log.d("Main","SingleTap");
            View childView = recyclerView.findChildViewUnder(event.getX(),event.getY());
            if (childView != null && onItemClickListener != null) {
                MyAdapter.MyViewHolder viewHolder = (MyAdapter.MyViewHolder) recyclerView.getChildViewHolder(childView);
                Log.d("Main","onItemClick");
                onItemClickListener.onItemClick(viewHolder);
            }
            return true;
        }

    }

    public abstract class RecyclerItemTouchListener extends RecyclerView.SimpleOnItemTouchListener {
        private GestureDetector mGestureDetector;
        private RecyclerView mRecyclerView;

        public RecyclerItemTouchListener(RecyclerView recyclerView) {
            mRecyclerView = recyclerView;
            mGestureDetector = new GestureDetector(mRecyclerView.getContext(),new mySimpleGestureListener());
        }

        @Override
        public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
            mGestureDetector.onTouchEvent(e);
            return false;
        }

        @Override
        public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
            mGestureDetector.onTouchEvent(e);
        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }
    }
}

MySimpleExoPlayer

package com.example.myitemtouch;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;

import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;

public class MySimpleExoPlayer extends AppCompatActivity {
    private String fileName;
    private PlayerView playerView;
    private SimpleExoPlayer player;
    private Context context = MySimpleExoPlayer.this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_simple_exo_player);
        Intent intent = getIntent();
        fileName = intent.getStringExtra("fileName");
        playerView = findViewById(R.id.exo_player);
        initializePlayer();
    }
    private void initializePlayer() {
        player = new SimpleExoPlayer.Builder(context).build();
        playerView.setPlayer(player);
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context,
                Util.getUserAgent(context,"myExoPlayer"));
        MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(Environment.getExternalStorageDirectory() + "/" + fileName));
        player.prepare(mediaSource);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        player.release();
    }
}

4.其它类

MyAdapter //适配器,填充数据

package com.example.myitemtouch;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private List<MyFile> mFileList;
    public MyAdapter(List<MyFile> myFileList) {
        mFileList = myFileList;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public MyViewHolder(View v) {
            super(v);
            textView = v.findViewById(R.id.textView);
        }
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_view, parent, false);
        MyViewHolder myViewHolder = new MyViewHolder(v);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        MyFile myFile = mFileList.get(position);
        holder.textView.setText(myFile.getFileName());
    }

    @Override
    public int getItemCount() {
        return mFileList.size();
    }
}

MyFile

package com.example.myitemtouch;

public class MyFile {
    private String fileName;
    public MyFile(String fileName) {
        super();
        this.fileName = fileName;
    }

    public String getFileName() {
        return fileName;
    }
}

OnItemClickListener //接口定义

package com.example.myitemtouch;


public interface OnItemClickListener {
    void onItemClick(MyAdapter.MyViewHolder viewHolder);
}

5. 关键代码

//在布局中添加了 RecyclerView 微件之后,获取对象句柄,将其连接到布局管理器,并为要显示的数据附加适配器

// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);

// use a linear layout manager
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);

// specify an adapter (see also next example)
adapter = new MyAdapter(myFileList);
recyclerView.setAdapter(adapter);

//要将所有数据输入列表中,您必须扩展 RecyclerView.Adapter 类。此对象会创建项的视图,并在原始项不再可见时用新数据项替换部分视图的内容。

//MyViewHolder参数需要是View,否则报错(TextView与String[]类型不匹配)

public MyViewHolder(View v) {
            super(v);
            textView = v.findViewById(R.id.textView);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_view, parent, false);
        MyViewHolder myViewHolder = new MyViewHolder(v);
        return myViewHolder;
}

//设置R.layout.my_view中的textView

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
        MyFile myFile = mFileList.get(position);
        holder.textView.setText(myFile.getFileName());
}

//初始化文件列表,将指定文件夹内的所有文件信息,添加到List中;
//通过List中保存的每一个信息,生成RecyclerView Adapter需要的数据,并添加进去。

private void initMyFile(File externalStorageDirectory) {
        myFileList.clear();
        List<File> files = new ArrayList<>();
        Collections.addAll(files, externalStorageDirectory.listFiles());
        for (File file : files) {
            String fileName = file.getName();
            MyFile myFile = new MyFile(fileName);
            myFileList.add(myFile);
        }
        adapter.notifyDataSetChanged();
}

//RecyclerView item点击
//addOnItemTouchListener (API) 借助GestureDetectorCompat根据触摸手势来判断是否为点击事件

recyclerView.addOnItemTouchListener(new RecyclerItemTouchListener(recyclerView) {
});

//触摸手势监听

public abstract class RecyclerItemTouchListener extends RecyclerView.SimpleOnItemTouchListener {
    private GestureDetector mGestureDetector;
    private RecyclerView mRecyclerView;

    public RecyclerItemTouchListener(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
         mGestureDetector = new GestureDetector(mRecyclerView.getContext(),new mySimpleGestureListener());
    }

    @Override
    public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        return false;
    }

    @Override
    public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

//GestureDetector手势实现

    private class mySimpleGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onSingleTapUp(MotionEvent event) {
            Log.d("Main","SingleTap");
            View childView = recyclerView.findChildViewUnder(event.getX(),event.getY());
            if (childView != null && onItemClickListener != null) {
                MyAdapter.MyViewHolder viewHolder = (MyAdapter.MyViewHolder) recyclerView.getChildViewHolder(childView);
                Log.d("Main","onItemClick");
                onItemClickListener.onItemClick(viewHolder);
            }
            return true;
        }

    }

//onItemClickListener接口实现

onItemClickListener = new OnItemClickListener() {
        @Override
        public void onItemClick(MyAdapter.MyViewHolder viewHolder) {
            Log.d("Main","onItemClick");
            //RecyclerView.ViewHolder mViewHolder;
            MyAdapter.MyViewHolder mViewHolder;
            mViewHolder = viewHolder;
            String vhText = (String) mViewHolder.textView.getText();
            Log.d("Main",vhText);
            Intent intent = new Intent(MainActivity.this,MySimpleExoPlayer.class);
            intent.putExtra("fileName",vhText);
            startActivity(intent);
        }
};

//MySimpleExoPlayer播放点击的item

private void initializePlayer() {
    player = new SimpleExoPlayer.Builder(context).build();
    playerView.setPlayer(player);
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context,
            Util.getUserAgent(context,"myExoPlayer"));
    MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(Uri.parse(Environment.getExternalStorageDirectory() + "/" + fileName));
    player.prepare(mediaSource);
}

参考链接:
https://developer.android.google.cn/guide/topics/ui/layout/recyclerview?hl=zh_cn#java
MyViewHolder参数需要是View,否则报错(TextView与String[]类型不匹配)
https://www.jianshu.com/p/4fc6164e4709
RecyclerView 的item显示的间距过大(item占满父布局)
https://www.jianshu.com/p/3047c050b556
文件列表
https://blog.csdn.net/qq_40019723/article/details/79369529
https://blog.csdn.net/u013372185/article/details/52415234
RecyclerView item点击
https://segmentfault.com/a/1190000005176416
https://blog.csdn.net/u010940300/article/details/48806035
http://syang.site/2017/05/13/Android-RecyclerView%E9%80%9A%E8%BF%87addOnItemTouchListener%E5%A4%84%E7%90%86onClick%E7%82%B9%E5%87%BB%E4%BA%8B%E4%BB%B6/

你可能感兴趣的:(android)