实验目标
将第一次实验里recyclerView的每个item增加点击功能,点击后跳转到一个新的view界面。
技术说明
- 使用工具 Android studio
- API 33 Android 13
- 主要技术内容:recyclerview、adapter、activity、fragment,service
设计思路
- 将原本作业1中的fagment1改成播放器,播放音乐
- fragment2作为列表展示音乐文件名
- 创建一个musicactivity播放器
- 创建myservice1来播放音乐
- fragment2将歌名读取出来显示在recycleview中
- myadapter将每个选项中的歌名在歌曲名单中的下标传递给musicactivity
- musicactivity在歌名列表中查找到原本的歌名需要,将其写入到textview中
- musicactivity根据歌曲的序号,传给myservice1
- myservice接收参数,播放对应序号所放的歌
核心代码
播放器
myservice1.java
- 将歌曲对象按顺序写入列表,方便播放时调用
- 因为oncreat不接受intent参数,所以在onstartcommand中通过intent接收参数,并播放
public class MyService1 extends Service {
MediaPlayer player;
int [] musics={
R.raw.music1,
R.raw.music2,
R.raw.music3,
R.raw.music4
};
public MyService1() {
}
@Override
public void onCreate(){
super.onCreate();
Log.d("xr","MyService1:onCreate...");
//player=MediaPlayer.create(this,musics[0]);
//player=MediaPlayer.create(this,R.raw.music1);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("xr","MyService1:onStart...");
int musicIndex = intent.getIntExtra("musicIndex", 0); // 获取传递的参数,默认为0
player = MediaPlayer.create(this, musics[musicIndex]);
player.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
player.stop();
player.release();
super.onDestroy();
Log.d("xr","MyService1:onDestroy...");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
musicactivity.java
- 接收intent传递过来的参数,歌曲序号
- getRawSongList获取歌名列表
- 在歌名列表中根据歌曲序号将歌名显示在textview中
- 启动myservice1服务时,将歌名序号作为参数传递
- 按钮1播放,按钮2停止,按钮3返回歌单
public class MusicActivity extends AppCompatActivity {
int index;
TextView textView;
Button button1,button2,button3;
List<String> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("test","music creat1");
super.onCreate(savedInstanceState);
list=getRawSongList();
setContentView(R.layout.activity_music);
textView=findViewById(R.id.textView1234);
//接收传递的参数
Intent intent1=getIntent();
index=intent1.getIntExtra("index",0);
Log.d("test","getintent");
button1=findViewById(R.id.buttonM11);
button2=findViewById(R.id.buttonM22);
button3=findViewById(R.id.button66);
Log.d("test",String.valueOf(index));
textView.setText(list.get(index));
Intent intent=new Intent(MusicActivity.this,MyService1.class);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent.putExtra("musicIndex", index); // 设置参数
startService(intent);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent3 =new Intent();
finish();
}
});
}
public List<String> getRawSongList() {//获取歌曲列表的名字
List<String> list = new ArrayList<>();
Field[] fields = R.raw.class.getFields();
for (Field field : fields) {
String songName = field.getName();
list.add(songName);
}
return list;
}
}
fragment1.java
- 将musicactivity的代码复制到fagment1里改一下。
public class Fragment1 extends Fragment {
Button button1, button2;
int index=1;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout1, container, false);
button1 = view.findViewById(R.id.buttonM11);
button2 = view.findViewById(R.id.buttonM22);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MyService1.class);
Log.d("test",String.valueOf(index));
intent.putExtra("musicIndex", index); // 设置参数
getActivity().startService(intent);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MyService1.class);
getActivity().stopService(intent);
}
});
return view;
}
}
recycleview跳转
fragment2.java
- 读取歌名信息列表,初始化myadapter
- 将fragment2与adapter关联,绑定recycler view与item
public class Fragment2 extends Fragment {
RecyclerView recycleview;
Myadapter adapter;
Context context;
List<String> list;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.activity_recycle_view,container,false);
recycleview=view.findViewById(R.id.RecyclerView1);
context=view.getContext();
list=new ArrayList<>();
list=getRawSongList();
adapter =new Myadapter(context,list);
recycleview.setAdapter(adapter);
LinearLayoutManager manager=new LinearLayoutManager(context);
manager.setOrientation(RecyclerView.VERTICAL);
recycleview.setLayoutManager(manager);
return view;
}
public List<String> getRawSongList() {//获取歌曲列表的名字
List<String> list = new ArrayList<>();
Field[] fields = R.raw.class.getFields();
for (Field field : fields) {
String songName = field.getName();
list.add(songName);
}
return list;
}
}
recycleview.java
- 将当前activity和list 作为参数传递给myadapter。
public class RecycleViewActivity extends AppCompatActivity {
RecyclerView recycleview;
Myadapter adapter;
Context context;
List<String> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle_view);
recycleview=findViewById(R.id.RecyclerView1);
context=this;
adapter =new Myadapter(this,list);
recycleview.setAdapter(adapter);
LinearLayoutManager manager=new LinearLayoutManager(this);
manager.setOrientation(RecyclerView.VERTICAL);
recycleview.setLayoutManager(manager);
}
}
myadapter.java
- 使用holder.getAdapterPosition获取当前绑定的 ViewHolder 在适配器中的位置,这个跟歌名序号是对应关系,可以直接作为当前item对应的歌名序号进行调用
- 使用intent.putExtra将参数传给musicactivity
- startActivity启动musicactivity
public class Myadapter extends RecyclerView.Adapter<Myadapter.Myholder>{
Context context1;
List<String> list1;
public Myadapter(Context context,List<String> list){
context1=context;
list1=list;
}
@NonNull
@Override
public Myholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context1).inflate(R.layout.item,parent,false);
Myholder holder=new Myholder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull Myholder holder, int position) {
holder.textview.setText(list1.get(position));
//holder.textview.setText(Integer.toString(holder.getAdapterPosition()));
//监听器
holder.textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Bundle args = new Bundle();
//args.putInt("index", holder.getAdapterPosition());
Log.d("test","onClick");
//holder.getAdapterPosition()获取当前item的序号,跟歌名序号对应,作为参数调用musicactivity
Intent intent=new Intent(context1,MusicActivity.class);
intent.putExtra("index",holder.getAdapterPosition());
context1.startActivity(intent);
Log.d("test","start suc");
}
});
}
@Override
public int getItemCount() {
return list1.size();
}
public class Myholder extends RecyclerView.ViewHolder {
TextView textview;
public Myholder(@NonNull View itemView) {
super(itemView);
textview=itemView.findViewById(R.id.textView8);
}
}
}
layout1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MusicActivity">
<Button
android:id="@+id/buttonM11"
android:layout_width="250dp"
android:layout_height="48dp"
android:layout_marginTop="59dp"
android:text="播放"
app:layout_constraintBottom_toTopOf="@+id/buttonM22"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1234" />
<Button
android:id="@+id/buttonM22"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:text="暂停"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonM11" />
<TextView
android:id="@+id/textView1234"
android:layout_width="260dp"
android:layout_height="153dp"
android:layout_marginStart="75dp"
android:layout_marginTop="136dp"
android:layout_marginEnd="76dp"
android:layout_marginBottom="59dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/buttonM11"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_music.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MusicActivity">
<Button
android:id="@+id/buttonM11"
android:layout_width="250dp"
android:layout_height="48dp"
android:layout_marginTop="59dp"
android:text="播放"
app:layout_constraintBottom_toTopOf="@+id/buttonM22"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1234" />
<Button
android:id="@+id/buttonM22"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:text="暂停"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonM11" />
<TextView
android:id="@+id/textView1234"
android:layout_width="260dp"
android:layout_height="153dp"
android:layout_marginStart="75dp"
android:layout_marginTop="136dp"
android:layout_marginEnd="76dp"
android:layout_marginBottom="59dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/buttonM11"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button66"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="返回"
tools:layout_editor_absoluteX="-2dp"
tools:layout_editor_absoluteY="-1dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
中间出现的问题
- 因为原本将播放器的activity代码改到了fragment1里,开始时是想实现fragment2中的recycleview点击跳转到fragment1中,在fragment1的textview显示出歌名,并点击播放的,但是不知道怎么实现fragment跳转
1.1. 传参问题,myadapt如果要想传完参数后调用原本的fragment1对象就必须要mainactivity的环境。不能使用全局变量,就只能用this指针得传好几遍。
1.2. 静态问题,还写了一个函数,想用一个公用方法来返回fragment对象,结果因为myadapt中写入的函数是静态的,没办法调用非静态的fragment - 最后放弃了原本的想法,直接将播放器做成一个单独的activity,直接传参调用。
结果
-
歌单界面
-
播放界面activity
-
播放界面fragment
-
返回
总结
- 在这次实验中为recycleview的每一个选项添加了一个跳转到播放器的功能,并播放对应的歌曲。不知道如何跳转fragment,如何跨多个构建传递参数,传参只能每次都传,也无法使用全局变量,直接启用了一个新的activity,myadapter中每次点击会将该选项的序号作为歌名序号传递。
库
- gitee: recycleview的item点击跳转实现