Move logic from adapter to fragment - ERROR: Cannot find view ID's
Move logic from adapter to fragment - ERROR: Cannot find view ID's
问题: 我正在尝试将我的媒体播放器方法(在我的适配器内)合并到我的片段(我想要我的媒体播放器对象的地方)。
为什么? - 因为我希望我的适配器 不 包含任何 methods/logic。它应该 ONLY 增加浏览量,除此之外别无其他。
我试图将我的 MediaPlayer 方法(在我的适配器内)移动到我的片段,但是当我试图在我的片段(应该播放和停止歌曲)中找到我的 playB 和 stopB 时,它给了我一个空异常。我查看了我的 XML 文件(我的 playB + stopB ID 所在的位置),一切正常。
我的适配器:
public class ListViewAdapter extends BaseAdapter {
//Create variables
MediaPlayer mediaPlayer;
Song currentSong;
int layout;
ArrayList<Song> arrayList;
Context context;
//Constructor
public ListViewAdapter(int layout, ArrayList<Song> arrayList, Context context) {
this.layout = layout;
this.arrayList = arrayList;
this.context = context;
}
//ViewHolder class holding my views
private class Viewholder {
TextView artistTxt, songNameTxt;
ImageView playB, stopB;
CircleImageView artistImg;
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
//Create viewholder variable
final Viewholder viewholder;
//Check if view is null
if (view == null) {
//Create new ViewHolder object
viewholder = new Viewholder();
//Inflate my view
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.listview_customlayout, null);
//Find my view id's
viewholder.artistImg = view.findViewById(R.id.artistImgBackgroundDetail);
viewholder.artistTxt = view.findViewById(R.id.artistTxt);
viewholder.songNameTxt = view.findViewById(R.id.songNameTxt);
viewholder.playB = view.findViewById(R.id.playB);
viewholder.stopB = view.findViewById(R.id.stopB);
//Set my view to viewholder
view.setTag(viewholder);
} else {
viewholder = (Viewholder) view.getTag();
}
//Assign song to my arraylist
final Song song = arrayList.get(position);
//Set my views to their resources
viewholder.artistImg.setImageResource(song.getArtistImg());
viewholder.artistTxt.setText(song.getArtist());
viewholder.songNameTxt.setText(song.getSongName());
return view;
如您所见 - 非常简单的适配器,我可以在其中调整我的自定义列表视图。
这是我的片段class,我**无法找到视图 ID:**
MediaPlayer mediaPlayer;
Song currentSong;
int position;
ImageView playB, stopB;
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
//Actionbar
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Song list");
//Find my listview
songListView = view.findViewById(R.id.songListView);
playB = getActivity().findViewById(R.id.playB);
stopB = getActivity().findViewById(R.id.stopB);
//create a new arraylist object
arrayList = new ArrayList<>();
adapter = new ListViewAdapter(R.layout.listview_customlayout, arrayList, getActivity());
//Set my listview to my custom adapter
songListView.setAdapter(adapter);
//Click on a specific song from my list
songListView.setOnItemClickListener(new ListViewClickListener());
final Song song = arrayList.get(position);
//get all songs
mediaPlayer = MediaPlayer.create(getActivity(), song.getSong());
//Play button click performed
playB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Checks if my current song is null and creates a new song
if (currentSong == null) {
mediaPlayer = MediaPlayer.create(getActivity(), song.getSong());
}
//if mediaplayer is not null and my current song is not equal to the new song i clicked on
if (mediaPlayer != null && currentSong != song) {
//resets the mediaplayer and creates a new song from the position in the list
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(getActivity(), song.getSong());
playB.setImageResource(R.drawable.play_orange);
mediaPlayer.start();
playB.setImageResource(R.drawable.pause_orange);
} else {
mediaPlayer.pause();
playB.setImageResource(R.drawable.play_orange);
}
//check if current song is null or the newly clicked song is equal to my current song
//if true then assign the newly clicked song as my CURRENT one
//--so it doesnt play the same song for every single one
if (currentSong == null || song != currentSong) {
currentSong = song;
}
}
});
//Stop song when click performed
stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//stops my current song and make it null
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null;
playB.setImageResource(R.drawable.play_orange);
}
}
});
//return my view
return view;
我想将我的 ListViewAdapter
留给 仅增加视图 ,这意味着我 不得 包含功能。
任何建议都将受到赞赏,因为我正在努力做得更好 :)
如果您需要更多信息,请告诉我。我很乐意尽可能说清楚。
谢谢。
在 MVVM 模式中,适配器应该与视图而不是视图模型相关联。因此,您可以做的是使适配器成为片段 class 的内部 class。如果你有 mediaPlayer 一个全局变量,你可以在适配器和片段中使用它的相同实例,如果这是你正在寻找的。
希望这对您有所帮助!
试试这个
制作界面
ClickUpdate.java
public interface ClickUpdate {
void getClicks();
}
里面
ListViewAdapter.java
public static ClickUpdate clickupadte;
public static void setonConnectionListener(ClickUpdate clicklisten) {
ListViewAdapter.clickupadte = clicklisten
}
同时在 listviewadapter 中点击 stopB
viewholder.stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickupadte.getClicks();
}
});
然后终于进去了
fragment class
inside oncreateview initialise
ListViewAdapter.setonConnectionListener(this);
还实现了 ClickUpdate,然后在片段 class 中生成了一个重写的方法,名称为 getClicks 我认为在该方法中给出
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null;
//playB.setImageResource(R.drawable.play_orange);//this will cause null point error,if occured to avoid the error pass viewholder.playB inside clickupadte.getClicks(); function
}
问题: 我正在尝试将我的媒体播放器方法(在我的适配器内)合并到我的片段(我想要我的媒体播放器对象的地方)。
为什么? - 因为我希望我的适配器 不 包含任何 methods/logic。它应该 ONLY 增加浏览量,除此之外别无其他。
我试图将我的 MediaPlayer 方法(在我的适配器内)移动到我的片段,但是当我试图在我的片段(应该播放和停止歌曲)中找到我的 playB 和 stopB 时,它给了我一个空异常。我查看了我的 XML 文件(我的 playB + stopB ID 所在的位置),一切正常。
我的适配器:
public class ListViewAdapter extends BaseAdapter {
//Create variables
MediaPlayer mediaPlayer;
Song currentSong;
int layout;
ArrayList<Song> arrayList;
Context context;
//Constructor
public ListViewAdapter(int layout, ArrayList<Song> arrayList, Context context) {
this.layout = layout;
this.arrayList = arrayList;
this.context = context;
}
//ViewHolder class holding my views
private class Viewholder {
TextView artistTxt, songNameTxt;
ImageView playB, stopB;
CircleImageView artistImg;
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
//Create viewholder variable
final Viewholder viewholder;
//Check if view is null
if (view == null) {
//Create new ViewHolder object
viewholder = new Viewholder();
//Inflate my view
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.listview_customlayout, null);
//Find my view id's
viewholder.artistImg = view.findViewById(R.id.artistImgBackgroundDetail);
viewholder.artistTxt = view.findViewById(R.id.artistTxt);
viewholder.songNameTxt = view.findViewById(R.id.songNameTxt);
viewholder.playB = view.findViewById(R.id.playB);
viewholder.stopB = view.findViewById(R.id.stopB);
//Set my view to viewholder
view.setTag(viewholder);
} else {
viewholder = (Viewholder) view.getTag();
}
//Assign song to my arraylist
final Song song = arrayList.get(position);
//Set my views to their resources
viewholder.artistImg.setImageResource(song.getArtistImg());
viewholder.artistTxt.setText(song.getArtist());
viewholder.songNameTxt.setText(song.getSongName());
return view;
如您所见 - 非常简单的适配器,我可以在其中调整我的自定义列表视图。
这是我的片段class,我**无法找到视图 ID:**
MediaPlayer mediaPlayer;
Song currentSong;
int position;
ImageView playB, stopB;
@Nullable
@Override
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
//Actionbar
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Song list");
//Find my listview
songListView = view.findViewById(R.id.songListView);
playB = getActivity().findViewById(R.id.playB);
stopB = getActivity().findViewById(R.id.stopB);
//create a new arraylist object
arrayList = new ArrayList<>();
adapter = new ListViewAdapter(R.layout.listview_customlayout, arrayList, getActivity());
//Set my listview to my custom adapter
songListView.setAdapter(adapter);
//Click on a specific song from my list
songListView.setOnItemClickListener(new ListViewClickListener());
final Song song = arrayList.get(position);
//get all songs
mediaPlayer = MediaPlayer.create(getActivity(), song.getSong());
//Play button click performed
playB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Checks if my current song is null and creates a new song
if (currentSong == null) {
mediaPlayer = MediaPlayer.create(getActivity(), song.getSong());
}
//if mediaplayer is not null and my current song is not equal to the new song i clicked on
if (mediaPlayer != null && currentSong != song) {
//resets the mediaplayer and creates a new song from the position in the list
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(getActivity(), song.getSong());
playB.setImageResource(R.drawable.play_orange);
mediaPlayer.start();
playB.setImageResource(R.drawable.pause_orange);
} else {
mediaPlayer.pause();
playB.setImageResource(R.drawable.play_orange);
}
//check if current song is null or the newly clicked song is equal to my current song
//if true then assign the newly clicked song as my CURRENT one
//--so it doesnt play the same song for every single one
if (currentSong == null || song != currentSong) {
currentSong = song;
}
}
});
//Stop song when click performed
stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//stops my current song and make it null
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null;
playB.setImageResource(R.drawable.play_orange);
}
}
});
//return my view
return view;
我想将我的 ListViewAdapter
留给 仅增加视图 ,这意味着我 不得 包含功能。
任何建议都将受到赞赏,因为我正在努力做得更好 :)
如果您需要更多信息,请告诉我。我很乐意尽可能说清楚。
谢谢。
在 MVVM 模式中,适配器应该与视图而不是视图模型相关联。因此,您可以做的是使适配器成为片段 class 的内部 class。如果你有 mediaPlayer 一个全局变量,你可以在适配器和片段中使用它的相同实例,如果这是你正在寻找的。
希望这对您有所帮助!
试试这个 制作界面
ClickUpdate.java
public interface ClickUpdate {
void getClicks();
}
里面
ListViewAdapter.java
public static ClickUpdate clickupadte;
public static void setonConnectionListener(ClickUpdate clicklisten) {
ListViewAdapter.clickupadte = clicklisten
}
同时在 listviewadapter 中点击 stopB
viewholder.stopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickupadte.getClicks();
}
});
然后终于进去了
fragment class inside oncreateview initialise
ListViewAdapter.setonConnectionListener(this);
还实现了 ClickUpdate,然后在片段 class 中生成了一个重写的方法,名称为 getClicks 我认为在该方法中给出
if (currentSong != null) {
mediaPlayer.stop();
mediaPlayer.release();
currentSong = null;
//playB.setImageResource(R.drawable.play_orange);//this will cause null point error,if occured to avoid the error pass viewholder.playB inside clickupadte.getClicks(); function
}