【问题标题】:Move logic from adapter to fragment - ERROR: Cannot find view ID's将逻辑从适配器移动到片段 - 错误:找不到视图 ID
【发布时间】:2018-12-02 12:13:10
【问题描述】:

问题:我试图将我的媒体播放器方法(在我的适配器内)合并到我的片段(我想在其中拥有我的媒体播放器对象)。
为什么? - 因为我希望我的适配器包含任何方法/逻辑。它应该增加视图,而不是其他任何东西。

我试图将我的 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;

如您所见 - 非常简单的适配器,我在其中调整了我的自定义列表视图。

这是我**无法找到视图 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 留给只增加视图,这意味着我不得包含功能。

感谢任何建议,因为我正在努力改进我正在做的事情:)

如果您需要更多信息,请告诉我。我很乐意尽量说清楚。

谢谢。

【问题讨论】:

  • 不明白你的意思
  • 很抱歉给您带来不便。我现在编辑了。
  • 意思是你想将媒体播放器实例从片段传递到适配器?
  • 没有。恰恰相反。我试图将媒体播放器对象从适配器移动到片段,但是当我尝试为我的 playB 查找视图 ID 时,我不断收到 nullexceptions
  • 有时可以通过接口,空指针错误是因为id stopB还没有初始化

标签: android android-fragments android-listview android-arrayadapter


【解决方案1】:

试试这个 制作界面

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

然后终于进去了

片段类 在oncreateview里面初始化

ListViewAdapter.setonConnectionListener(this);

还实现了 ClickUpdate,然后在片段类中生成一个重写的方法,名称为 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
        }

【讨论】:

  • 对不起,我没有得到最后一部分
  • @Delice 意味着一个被覆盖的方法会生成你粘贴 mediaplayer.stop() 等代码
【解决方案2】:

在 MVVM 模式中,适配器应该与视图相关联,而不是与视图模型相关联。所以你可能做的就是让适配器成为片段类的内部类。如果你有 mediaPlayer 一个全局变量,你可以在适配器和片段中使用它的相同实例,如果那是你正在寻找的。​​p>

希望这会有所帮助!

【讨论】:

  • 我宁愿远离 MVVM 模式,因为它更复杂,我需要更改我的整个项目架构,但感谢您的意见!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多