简体   繁体   English

如何在片段之间传递数据?

[英]How to Pass Data between Fragments?

For all those who are downvoting and voting for this question to be closed thinking it has something to do with the scope of textview.....then have a look,it has nothing to do with the scope of textview 对于所有那些对这个问题进行投票和投票的人来说,认为它与textview的范围有关.....然后看看,它与textview的范围无关

Unable to pass data between fragments,the app crashes,i don't know what i am doing wrong...i followed this link http://manishkpr.webheavens.com/android-passing-data-between-fragments/ 无法在片段之间传递数据,应用程序崩溃,我不知道我做错了什么...我按照这个链接http://manishkpr.webheavens.com/android-passing-data-between-fragments/

here is the code i am using Fragment A(this fragment is passing the data) 这是我使用片段A的代码(这个片段传递数据)

public class FragmentSongs extends  Fragment implements Serializable,OnFragmentCreatedListener {
ListView SngList;


 ArrayList<SongDetails> Songinfo=null;
AdapterView.AdapterContextMenuInfo info;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) 
{

    ViewGroup view = (ViewGroup) inflater.inflate(R.layout.fragment_song, null);

    SngList = (ListView) view.findViewById(R.id.SongList);
    registerForContextMenu(SngList);
    //File f=new File(Environment.getExternalStorageDirectory()+"/Music");
    File f=new File("/system/");
    int j=0;int i=0;

    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

      Songinfo = getSongsFromDirectory(f);



    //sorting done below
    if (Songinfo.size()>0)
    {

        for( j=0; j<Songinfo.size();j++)
        {
            for ( i=j+1 ; i<Songinfo.size(); i++)
            { 
                SongDetails a=Songinfo.get(i);
                SongDetails b=Songinfo.get(j);
                if(a.getSong().toLowerCase().compareTo(b.getSong().toLowerCase())<0)
                {   

                    Songinfo.set(i,b );
                    Songinfo.set(j,a);
                }
            }

        }






   SngList.setAdapter(new CustomAdapter(Songinfo));
   return view;
    }
    else return null;

}
OnFragmentCreatedListener listener;
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        listener = (OnFragmentCreatedListener) getActivity();
        listener.onFragmentCreated(Songinfo);
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement onFragmentCreated");
    }
}

fragment B(the receiver fragment ) 片段B(接收器片段)

    public class FragmentArtists extends Fragment {
    ArrayList<SongDetails> songinfo2;
ViewGroup view;
int s=5;//TextView text;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)
{Context context;
LayoutInflater lf = getActivity().getLayoutInflater();   

    view = (ViewGroup) inflater.inflate(R.layout.fragment_artist,  null);
// view =  lf.inflate(R.layout.test,container, false);
// view = inflater.inflate(R.layout.test,container, false);


 s=s+5;
//     text=(TextView)view.findViewById(R.id.tt);when i use this,it works fine but i want to do it in the other method

//text.setText("makzzz");when i use this,it works fine but i want to do it in the other method
return view;

}

 void setSongList(ArrayList<SongDetails> songinfo) 
{    //TextView text=(TextView)this.getView().findViewById(R.id.tt);//when i used this view was not global
      TextView text=(TextView)view.findViewById(R.id.tt);//when i used this,view was global;
      //TextView text=(TextView)view.findViewById(R.id.tt);
    // text=(TextView)super.getView().findViewById(R.id.tt);


     text.setText("makzzz");

the method in holder activity (this activity holds the fragments) 持有者活动中的方法(此活动包含片段)

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mymusic);


           fragments = new Vector<Fragment>();
            fragments.add(Fragment.instantiate(this, FragmentSongs.class.getName()));
            fragments.add(Fragment.instantiate(this, FragmentArtists.class.getName()));
            fragments.add(Fragment.instantiate(this, FragmentPlaylists.class.getName()));
            fragments.add(Fragment.instantiate(this, FragmentAlbums.class.getName())); 


            ViewPagerAdapter adapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);


            ViewPager pager = (ViewPager)super.findViewById(R.id.viewpager);



            pager.setAdapter(adapter);
            pager.setOffscreenPageLimit(4);

            pager.setCurrentItem(0);

    }      public void onFragmentCreated(ArrayList<SongDetails> msg) {
            FragmentArtists Obj=(FragmentArtists)  fragments.get(1);
            Obj.setSongList(msg);
            }

    }

the callback class: 回调类:

package sourcecode.jazzplayer;

import java.util.ArrayList;

public interface OnFragmentCreatedListener {
    public void onFragmentCreated(ArrayList<SongDetails> msg);

}

here is the logcat 这是logcat

  09-19 23:50:46.851: E/AndroidRuntime(2125): java.lang.NullPointerException
09-19 23:50:46.851: E/AndroidRuntime(2125):     at sourcecode.jazzplayer.FragmentArtists.setSongList(FragmentArtists.java:55)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at sourcecode.jazzplayer.MyMusic.onFragmentCreated(MyMusic.java:45)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at sourcecode.jazzplayer.FragmentSongs.onAttach(FragmentSongs.java:128)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:883)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:823)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.app.Fragment.setUserVisibleHint(Fragment.java:819)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:130)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1066)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.View.measure(View.java:12603)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.View.measure(View.java:12603)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.View.measure(View.java:12603)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2072)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.View.measure(View.java:12603)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1044)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.os.Looper.loop(Looper.java:137)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at android.app.ActivityThread.main(ActivityThread.java:4340)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at java.lang.reflect.Method.invokeNative(Native Method)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at java.lang.reflect.Method.invoke(Method.java:511)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-19 23:50:46.851: E/AndroidRuntime(2125):     at dalvik.system.NativeStart.main(Native Method)

the error is in this line of code 错误在这行代码中

TextView text=(TextView)view.findViewById(R.id.tt); TextView text =(TextView)view.findViewById(R.id.tt); //this line is in the receiver fragment (fragmentArtist) //此行位于接收器片段(fragmentArtist)中

As I already said in my comment you're trying to work with a Fragment when it's not properly initialized yet. 正如我在评论中已经说过的那样,当它尚未正确初始化时,你正试图使用Fragment When the FragmentSongs is attached to the Activity (action requested by the ViewPager where it will appear) its onAttach() method is called. FragmentSongs附加到ActivityViewPager请求它将出现的操作)时,将调用其onAttach()方法。 In this method you cast the Activity to your listener, but you also call immediately the listener's callback . 在此方法中,您将Activity为侦听器, 但您也立即调用侦听器的回调 This will make your app crash(with the exception you posted) because in that listener you're trying to work with the view of the second Fragment of the ViewPager , FragmentArtists . 这将使您的应用程序崩溃(与您发布的除外),因为在监听你想与第二的视图的工作Fragment中的ViewPagerFragmentArtists This Fragment isn't yet initialized, at this moment the first fragment of the ViewPager is barely being attached to the activity and you're already trying to work with the view of the second fragment which will obviously fail. Fragment尚未初始化,此时ViewPager的第一个片段几乎没有附加到活动上,您已经尝试使用第二个片段的视图,这个视图显然会失败。

The tutorial you linked to is ok, simplistic, but ok(without going to that link I assumed your code is from the tutorial). 你链接到的教程是好的,简单的,但是没问题(没有去那个链接我假设你的代码来自教程)。 The problem is that you used that code from a very simplistic scenario in a more complex situation(in fact if you insert your current code in that tutorial's code you'll get the same exception(calling the listener too early)). 问题是你在一个更复杂的情况下从一个非常简单的场景中使用了这个代码(事实上,如果你在当前教程的代码中插入当前代码,你将获得相同的异常(过早地调用监听器))。

That callback listener interface should be used while the fragment is fully built(like when the user is using the app and selects a song and you want to show to him the artist part of the app(at that moment call the listener and make it pass data)) also carefully handling the possibility of a fragment not being available. 片段完全构建时应该使用该回调侦听器接口(例如当用户使用应用程序并选择一首歌并且您想向他显示应用程序的艺术家部分时(此时调用侦听器并使其通过)数据))还仔细处理片段不可用的可能性。

If you need to pass data between fragments so early in the fragment's lifecycle that you can't guarantee the fragment is yet available(like you do with calling the listener in onAttach() of a fragment) then implement the fragment to get the data directly from the activity when it's built, in one of its lifecycle methods. 如果你需要在片段生命周期的早期片段之间传递数据,你不能保证片段可用(就像你在片段的onAttach()中调用监听器那样)然后实现片段直接获取数据从它的构建活动开始,在其生命周期方法之一中。 What you're passing it's not clear so there isn't much I can say here. 你传递的东西不清楚所以我在这里说的不多。

Your FragmentSongs class needs to implement OnFragmentCreatedListener FragmentSongs类需要实现OnFragmentCreatedListener

public class FragmentSongs extends Fragment implements OnFragmentCreatedListener { 

  public void onFragmentCreated(ArrayList<SongDetails> msg) {
    // whatever
  }


}

or in onAttach of your 'Fragment A': 或者在'片段A'的onAttach上:

        listener =  (OnFragmentCreatedListener) activity;

this would mean your Activity needs to implement OnFragmentCreatedListener 这意味着您的Activity需要实现OnFragmentCreatedListener

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM