【问题标题】:Send data from a CustomAdapter to a SubFragment with onClickListView使用 onClickListView 将数据从 CustomAdapter 发送到 SubFragment
【发布时间】:2018-11-21 21:46:24
【问题描述】:

已编辑:

问题:我试图将艺术家的详细信息从我的列表显示到片段,但我有一个 CustomAdapter 我正在使用,所以当我的应用程序逻辑如下时我不知道如何实现这一点:

  • ListViewAdapter.java --> MainFragment.java --> SongFragment.java (我必须从适配器到一个片段再到另一个片段,这导致我麻烦)

当我转到SongFragment.Java 时,我正在尝试设置艺术家的名称歌曲名称图像,但我的setOnItemClickListenerMainFragment.java 内。

下面是一个演示
步骤:

  1. 点击列表中的一首歌曲 (setOnItemClickListener) This is my customListView
  2. 打开SongFragment 并显示歌手信息(艺术家、歌曲名称、艺术家形象)This is my SongFragment after i clicked on a song

我的ListViewAdapter 代码:

public class ListViewAdapter extends BaseAdapter {

//Create variables
MediaPlayer mediaPlayer;
int layout;
Song currentSong;
ArrayList<Song> arrayList;
Context context;

public ListViewAdapter(int layout, ArrayList<Song> arrayList, Context 
context) {
    this.layout = layout;
    this.arrayList = arrayList;
    this.context = context;
}

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) {

    final Viewholder viewholder;

    if (view == null) {
        viewholder = new Viewholder();

        LayoutInflater layoutInflater = (LayoutInflater)
        context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(layout, null);

        viewholder.artistTxt = (TextView) view.findViewById(R.id.artistTxt);
        viewholder.songNameTxt = (TextView) 
        view.findViewById(R.id.songNameTxt);
        viewholder.playB = (ImageView) view.findViewById(R.id.playB);
        viewholder.stopB = (ImageView) view.findViewById(R.id.stopB);
        viewholder.artistImg = (CircleImageView) 
        view.findViewById(R.id.artistImg);

        view.setTag(viewholder);
    } else {
        viewholder = (Viewholder) view.getTag();
    }

    final Song song = arrayList.get(position);

    viewholder.artistImg.setImageResource(song.getArtistImg());
    viewholder.artistTxt.setText(song.getArtist());
    viewholder.songNameTxt.setText(song.getSongName());

    //get all songs
    mediaPlayer = MediaPlayer.create(context, song.getSong());

    viewholder.playB.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (currentSong == null) {
                mediaPlayer = MediaPlayer.create(context, 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(context, song.getSong());
                viewholder.playB.setImageResource(R.drawable.play_black);

                mediaPlayer.start();
                viewholder.playB.setImageResource(R.drawable.pause_black);
            } else {
                mediaPlayer.pause();
                viewholder.playB.setImageResource(R.drawable.play_black);
            }

            //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
    viewholder.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;
                viewholder.playB.setImageResource(R.drawable.play_black);
            }
        }
    });
    return view;
}

我的MainFragment.java 我将我的歌曲添加到列表中并调用我的适配器:

public class MainFragment extends Fragment {


//Declare variables
ArrayList<Song> arrayList;
ListView songListView;
ListViewAdapter adapter;
SongFragment songFragment;
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;


@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);

    //Find my listview
    songListView = (ListView) view.findViewById(R.id.songListView);

    //create a new arraylist object
    arrayList = new ArrayList<>();

    //Add songs to my list
    arrayList.add(new Song("Beyonce", "-Formation", R.raw.beyonce_formation, R.drawable.beyonce));
    arrayList.add(new Song("Chris Brown", "-Hope You Do", R.raw.chrisbrown_hopeyoudo, R.drawable.chrisbrown));
    arrayList.add(new Song("Akon ft. Colby'O'Donis", "-Beautiful", R.raw.akon_beautiful_ft_colbyodonis_kardinaloffishall, R.drawable.akon));
    arrayList.add(new Song("Akon", "-Beautiful", R.raw.akon_dontmatter, R.drawable.akon));
    arrayList.add(new Song("Akon", "-Locked Up", R.raw.akon_lockedup_ft_stylesp, R.drawable.akon));
    arrayList.add(new Song("Ava Max", "-Sweet but Psycho", R.raw.avamax_sweetbutpsycho, R.drawable.avamax));
    arrayList.add(new Song("Tupac and Biggie ft. Akon Remix", "-Ghetto", R.raw.tupacbiggieakon_ghetto, R.drawable.biggie));

    //Create a new adapter of my custom adapter and assign its values
    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 AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //Initiliaze my songFragment to my fragment class
            songFragment = new SongFragment();

            //call FragmentManager and begin the transaction to my songFragment class
            fragmentManager = getFragmentManager();
            fragmentTransaction = fragmentManager.beginTransaction();

            //When clicked on a listview item - navigate to songfragment and when clicked back -> go back to mainfragment
            //save my mainfragment to my stack so it isnt destroyed but kept safe so i can get back to it
            fragmentTransaction.replace(R.id.fragment_container, songFragment).addToBackStack(null).commit();

        }
    });
    //return my view
    return view;
}

} 我的customListView.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">

<de.hdodenhof.circleimageview.CircleImageView
    android:id="@+id/artistImg"
    android:layout_width="50sp"
    android:layout_height="50sp"
    android:src="@drawable/musiclogo"
    app:civ_border_color="@color/white"
    app:civ_border_width="2dp" />

<TextView
    android:id="@+id/artistTxt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/artistImg"
    android:text="Artist"
    android:textColor="@color/black"
    android:textSize="15sp"
    android:textStyle="bold" />

<TextView
    android:id="@+id/songNameTxt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/artistTxt"
    android:layout_toRightOf="@id/artistImg"
    android:text="Song Name"
    android:textColor="#11ca6b" />

<ImageView
    android:id="@+id/playB"
    android:layout_width="30sp"
    android:layout_height="30sp"
    android:layout_marginTop="4sp"
    android:layout_toLeftOf="@id/stopB"
    android:src="@drawable/play_black" />

<ImageView
    android:id="@+id/stopB"
    android:layout_width="30sp"
    android:layout_height="30sp"
    android:layout_alignParentRight="true"
    android:layout_marginTop="4sp"
    android:src="@drawable/stop_black" />

</RelativeLayout>

我的fragment_song.xml 布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/constrainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">


<ImageView
    android:id="@id/artistImg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:alpha="0.4"
    android:background="@color/black"
    android:scaleType="centerCrop"
    android:src="@drawable/edsher" />

<de.hdodenhof.circleimageview.CircleImageView
    android:id="@id/artistImg"
    android:layout_width="250sp"
    android:layout_height="250sp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="75sp"
    android:src="@drawable/edsher"
    app:civ_border_color="@color/white"
    app:civ_border_width="2sp" />

<TextView
    android:id="@id/songNameTxt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/artistImg"
    android:layout_centerInParent="true"
    android:layout_marginTop="10sp"
    android:text="Song name" />

<TextView
    android:id="@+id/currentSongLenght"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/songNameTxt"
    android:layout_marginTop="9sp"
    android:layout_toLeftOf="@id/songLenght"
    android:text="03:00" />

<TextView
    android:id="@+id/currentSongLeft"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/songNameTxt"
    android:layout_marginTop="9sp"
    android:layout_toRightOf="@id/songLenght"
    android:text="-02:20" />

<SeekBar
    android:id="@+id/songLenght"
    android:layout_width="300sp"
    android:layout_height="wrap_content"
    android:layout_below="@id/songNameTxt"
    android:layout_centerInParent="true"
    android:layout_marginTop="10sp" />


<ImageView
    android:id="@+id/previousB"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_below="@id/songLenght"
    android:layout_toLeftOf="@id/playB"
    android:src="@drawable/previous" />

<ImageView
    android:id="@id/playB"
    android:layout_width="70sp"
    android:layout_height="70sp"
    android:layout_below="@id/songLenght"
    android:layout_centerInParent="true"
    android:src="@drawable/play_big" />

<ImageView
    android:id="@+id/nextB"
    android:layout_width="60sp"
    android:layout_height="60sp"
    android:layout_below="@id/songLenght"
    android:layout_toRightOf="@id/playB"
    android:src="@drawable/next" />

<ImageView
    android:id="@+id/favoriteB"
    android:layout_width="40sp"
    android:layout_height="40sp"
    android:layout_below="@id/songLenght"
    android:layout_alignParentEnd="true"
    android:layout_marginTop="10sp"
    android:src="@drawable/favorite" />

</RelativeLayout>

【问题讨论】:

  • 你能澄清你的问题吗?顺便说一句,您的适配器似乎不正确,您确定发布了正确的代码还是遇到了编译问题?
  • 已编辑。没有我的自定义适配器按预期工作。
  • 对,你收到onItemClick的回调了吗?

标签: java android android-fragments custom-adapter custom-lists


【解决方案1】:

你会让你的SongSerializable:class Song implements Serializable{

然后在你的包中传递这个类。

Bundle bundle = new Bundle();
bundle.putSerializable("song", song);
songFragment.setArguments(bundle);

在你的SongFragment 中你应该得到参数:

public class SongFragment extends Fragment {
@Nullable
@Override
public View onCreateView( /* .... */){

Song song = getArguments().getSerializable("song");

}

}

如果您不想使用参数(我会明确使用参数),我会在我的 SongFragment 中创建一个方法,它将接收我需要的所有数据,我会在我的 mainFragment 中使用SongFragment 实例。

类似这样的:

public class SongFragment extends Fragment {

String artist;
String song;
int name;
int image;
TextView nameText, artistText;
/* all my code .... */
@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);
   nameText = view.findByViewId(R.id.my_name_id);
   artistText = view.findByViewId(R.id.my_artist_id);

}
public getSongData(String artist, String song, int name, int image){
   this.artist = artist;
   this.song = song;
   this.name = name;
   this.image = image;

   nameText.setText(name);
   artistText.setText(artist);
}

}

在您的songListView.setOnItemClickListener中的MainFragment中:

songListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        songFragment = new SongFragment();
       // -----> HERE <-----
        songFragment.getSongData(song.getArtist(), song.getSongName(), song.getName(), song.getArtistImg());
       // -----> HERE <-----

        fragmentManager = getFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();


        fragmentTransaction.replace(R.id.fragment_container, songFragment).addToBackStack(null).commit();

    }
});

【讨论】:

  • 几乎成功了!只有一件事我没有抓住。如何将我从方法中获得的值设置为我的 TextViews? getSongDetails(artist, songName, artistImg, song); DIDNT 在我的 SongFragment 中工作
  • 尝试按照我上面编辑的方法去做。如果它不起作用(我认为它总是起作用),您应该将您的 TextView 作为全局变量并将 setTextinside getSongData()。我将在更多时间对其进行编辑,以便向您展示如何操作。
  • 感谢它的工作!现在我可以在我的新片段中获取艺术家姓名、歌曲名称和艺术家的形象!我还有一个问题:如果我想在我的 SongFragment 中播放这首歌,而不是从我的列表视图中播放它怎么办(屏幕截图已发布 (1))?如何访问我的适配器中的所有媒体播放器功能到我的 SongFragment 内部(我有一个播放按钮)?
  • 您可以先在 MainFragment 中实例化,将其传递给 ListView 构造函数,然后使用 getDataSong 方法将其再次传递给 SongFragment。我认为它应该工作
  • 相信我,我尝试了几次......没有运气。我还是新手:(
【解决方案2】:

一种简单的方法是将数据作为参数传递给片段:

Bundle arguments = new Bundle();
// Set your data in the arguments
// For example: arguments.putString("song_title", item.getSongName())
// And you can get the name by calling getArguments() in SongFragment
Fragment songFragment = new SongFragment();
songFragmnet.setArguments(arguments);

以防万一您遇到点击问题,在ListView 中,每当点击项目视图时,它都会在视图上执行View.hasExplicitFocusable,所以如果您的项目视图上有任何可点击的视图,那么您将不会收到onItemClick 的回调。因此,您可能需要找到另一种解决方法来附加点击侦听器。

【讨论】:

  • 我认为问题是如何通过我的MainFragment (我有我的onItemClickListener)将我的所有物品打包从我的适配器发送到我的SongFragment 必须打开捆绑包的地方并在正确的位置设置正确的属性。我如何做到这一点?
猜你喜欢
  • 1970-01-01
  • 2013-11-03
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多