dependencies {
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.exoplayer:exoplayer:2.11.1'
<?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" />
>
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();
}
}
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);
}
//在布局中添加了 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/