Android Datenaustausch zwischen zwei Fragments

kurztipp

Aktives Mitglied
Hallo,

ich habe eine Activity, in der zwei Fragments mit einem FragmentPagerAdapter angezeigt werden. Im ersten Fragment kann eine Eingabe gemacht und gespeichert werden, im zweiten werden diese per GridView angezeigt.
Die Daten werden vom ersten Fragment per Interface an die Activity gesendet, diese holt sich den Adapter des GridViews und fügt die neuen Daten hinzu. Die Activity ist somit sozusagen die Schnittstellte zwischen den beiden Fragments.
Leider funktioniert es nicht, da die Activity statt dem Adapter null bekommt. Warum weiß ich nicht, weil das Fragment, samt Adapter vorher initialisiert wird. Beispiel:

Activity:
Java:
public class SwipeTest extends FragmentActivity implements TestFragment1
                                                               .OnFragmentInteractionListener {

    private final String[] tabs = {"Test 1", "Test 2"};
    private ViewPager        pager;
    private ActionBar        actionBar;
    private TabsPagerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.pager = new ViewPager(this);
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup
                                                                       .LayoutParams.MATCH_PARENT,
                                                                   ViewGroup
                                                                       .LayoutParams.MATCH_PARENT);
        this.pager.setLayoutParams(params);
        setContentView(this.pager);

        this.actionBar = getActionBar();
        this.adapter = new TabsPagerAdapter(
            getSupportFragmentManager());

        this.pager.setAdapter(this.adapter);
        this.actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        setUpViewPager();
        setUpActionBar();

    }

    /**
     * Sets up the ViewPager and adds an OnPageChangeListener
     */
    private void setUpViewPager() {
        this.pager.setAdapter(this.adapter);
        // pager needs an id; crashes if it has none
        this.pager.setId(123456789);

        // Set up the listener
        ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager
            .OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i2) {
            }

            @Override
            public void onPageSelected(int i) {
                SwipeTest.this.actionBar.setSelectedNavigationItem(i);
            }

            @Override
            public void onPageScrollStateChanged(int i) {
            }
        };

        this.pager.setOnPageChangeListener(onPageChangeListener);
    }

    /**
     * Sets up the ActionBar with it's tabs and adds an ActionBar.TabListener to
     * them
     */
    private void setUpActionBar() {
        this.actionBar = getActionBar();
        this.actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Set up listener
        ActionBar.TabListener tabListener = new ActionBar.TabListener() {
            @Override
            public void onTabSelected(ActionBar.Tab tab,
                                      FragmentTransaction
                                          fragmentTransaction) {
                SwipeTest.this.pager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(ActionBar.Tab tab,
                                        FragmentTransaction
                                            fragmentTransaction) {
            }

            @Override
            public void onTabReselected(ActionBar.Tab tab,
                                        FragmentTransaction
                                            fragmentTransaction) {
            }
        };

        for (String tab_name : this.tabs) {
            this.actionBar.addTab(
                this.actionBar.newTab()
                              .setText(tab_name)
                              .setTabListener(tabListener));
        }
    }

    @Override
    public void onFragmentInteraction(String s) {
        TestFragment2 fragment = (TestFragment2) ((TabsPagerAdapter) pager
            .getAdapter()).getItem(1);
        System.out.println(fragment);
        ArrayAdapter<String> adapter = (ArrayAdapter<String>) fragment
            .getAdapter();
        System.out.println(adapter);
        adapter.add(s);
        adapter.notifyDataSetChanged();
    }


    public class TabsPagerAdapter extends FragmentPagerAdapter {

        public TabsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int index) {

            switch (index) {
                case 0:
                    return new TestFragment1();
                case 1:
                    return new TestFragment2();
            }

            return null;
        }

        @Override
        public int getCount() {
            return 2;
        }

    }
}

Fragment1:
Java:
public class TestFragment1 extends Fragment {

    private OnFragmentInteractionListener mListener;
    private EditText                      edit;

    public TestFragment1() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT);
        LinearLayout layout = new LinearLayout(getActivity());
        layout.setLayoutParams(params);
        this.edit = new EditText(getActivity());
        Button btn = new Button(getActivity());
        btn.setText("Save");
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onButtonPressed();
            }
        });
        layout.addView(this.edit);
        layout.addView(btn);
        return layout;
    }

    public void onButtonPressed() {
        if (this.mListener != null) {
            String input = this.edit.getText().toString();
            this.mListener.onFragmentInteraction(input);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            this.mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                                             + " must implement " +
                                             "OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        this.mListener = null;
    }

    public interface OnFragmentInteractionListener {
        public void onFragmentInteraction(String s);
    }

}

Fragment2
Java:
public class TestFragment2 extends Fragment {

    private final List<String> data = new ArrayList<String>();
    private ArrayAdapter<String> adapter;

    public TestFragment2() {
        // Required empty public constructor
    }

    public ArrayAdapter getAdapter() {
        System.out.println("get adapter:"+this.adapter);
        return this.adapter;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        System.out.println("Fragment2 onCreateView");
        GridView view = new GridView(getActivity());
        GridView.LayoutParams params = new AbsListView.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(params);

        this.data.add("Hello");
        this.data.add("World");

        this.adapter = new ArrayAdapter<String>(getActivity(),
                                        android.R.layout
                                            .simple_list_item_1,
                                        this.data);
        view.setAdapter(this.adapter);
        System.out.println("Fragment2 adapter initialized:"+this.adapter);

        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        System.out.println("Fragment2 onDestroyView");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        System.out.println("Fragment2 onDetach");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("Fragment2 onDestroy");
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        System.out.println("Fragment2 onAttach");
    }
}

Ausgabe:

I/System.out﹕ Fragment2 onAttach
I/System.out﹕ Fragment2 onCreateView
I/System.out﹕ Fragment2 adapter initialized:android.widget.ArrayAdapter@302ed58d
I/System.out﹕ TestFragment2{20365dc0}
I/System.out﹕ get adapter:null
I/System.out﹕ null
D/AndroidRuntime﹕ Shutting down VM
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: de.sandkasten, PID: 6254
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ArrayAdapter.add(java.lang.Object)' on a null object reference
at de.sandkasten.SwipeTest.onFragmentInteraction(SwipeTest.java:120)
at de.sandkasten.TestFragment1.onButtonPressed(TestFragment1.java:54)
at de.sandkasten.TestFragment1$1.onClick(TestFragment1.java:43)
at android.view.View.performClick(View.java:4598)
at android.view.View$PerformClick.run(View.java:19268)
at android.os.Handler.handleCallback(Handler.java:738)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5070)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)

Wieso bekomme ich statt dem adapter, der ja initialisiert wird, null zurück? Was mache ich falsch?
Ist dieser Weg, die Daten zu übermitteln überhaupt praktikabel?

Gruß
 

dzim

Top Contributor
Dass Problem liegt in deinem TabsPagerAdapter: Was steht da bei #getItem()? "return new TestFragmentX();"
Das heisst, dass du hier bei jeder Anfrage ein neues Objekt eines TestFragmentX erhälst - dessen ArrayAdapter ist natürlich nicht initialisiert, da er nie initialisiert wurde (oder je initialisierst wird).

Mein Tipp: Fragmente im Pager speichern.
Mein Absatz dazu hier in meiner Firma:
Java:
package ch.cnlab.android.commons.ui.viewpager;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public abstract class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
	
	/**
	 * <b>Hint, how the fragments tag are created</b><br/>
	 * <br/>
	 * <code>viewId</code> is the ID of the pager, here: <code>@+id/pager</code><br/>
	 * <br/>
	 * <code>
	 * private static String makeFragmentName(int viewId, int index) {<br/>
	 * return "android:switcher:" + viewId + ":" + index;<br/>
	 * }
	 * </code><br/>
	 * <br/>
	 * <b>Usage example:</b><br/>
	 * <code>
	 * FragmentManager fm = getSupportFragmentManager();<br/>
	 * Fragment fragment = fm.findFragmentByTag(String.format(MainSectionsPagerAdapter.FRAGMENT_TAG, R.id.pager, mViewPager.getCurrentItem()));
	 * </code>
	 */
	public static final String FRAGMENT_TAG = "android:switcher:%d:%d";
	
	protected final Context mContext;
	protected final FragmentManager mFragmentManager;
	
	protected final List<Fragment> mFragments = new ArrayList<Fragment>();
	
	protected Bundle mArguments = null;
	
	public CustomFragmentPagerAdapter(Context context, FragmentManager fragmentManager) {
		
		super(fragmentManager);
		
		this.mContext = context;
		this.mFragmentManager = fragmentManager;
		
		mFragments.addAll(createFraments());
	}
	
	public abstract List<Fragment> createFraments();
	
	public List<Fragment> getFragments() {
		return mFragments;
	}
	
	public void setArguments(Bundle arguments) {
		this.mArguments = arguments;
	}
}

Wenn du das Fragment anhand seines Tags mal wiederfinden musst, schau dir die JavaDoc über der public static final String FRAGMENT_TAG an...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Android Datenaustausch zwischen PC und Handy Android & Cross-Platform Mobile Apps 3
J Android Datenaustausch WLAN - Was ist am Besten? Android & Cross-Platform Mobile Apps 2
Julius99 Android Distanz zwischen zwei Location Android & Cross-Platform Mobile Apps 12
U Telepräsenz zwischen Notebook und Roboter Android & Cross-Platform Mobile Apps 1
N Android Informationen zwischen Tabs austauschen Android & Cross-Platform Mobile Apps 2
M Android Kabellose Datenübertragung zwischen zwei Handys - Reichweiten Android & Cross-Platform Mobile Apps 3
? Android erstellen der grafischen Benutzeroberfläche und Kommunikation zwischen Apps Android & Cross-Platform Mobile Apps 8
G Android Kommunikation zwischen den Activities Android & Cross-Platform Mobile Apps 1
B Android Kollision zwischen 2 Bitmaps Prüfen? Android & Cross-Platform Mobile Apps 4
S Android "Weiches wechseln" zwischen Views in einer Activity Android & Cross-Platform Mobile Apps 3
S Android Kommunikation zwischen UI -> Service -> Thread Android & Cross-Platform Mobile Apps 4
M Daten zwischen mehreren Activities Android & Cross-Platform Mobile Apps 2
M Daten zwischen Activities übergeben Android & Cross-Platform Mobile Apps 7
C Android Kommunikation zwischen Service und Activity Android & Cross-Platform Mobile Apps 8
S Android binäre Daten zwischen Android und einem Java-Server Android & Cross-Platform Mobile Apps 5
S Android Auf Funktionen zwischen Activitys zugreifen Android & Cross-Platform Mobile Apps 3
E Übergang zwischen 2 Activities Android & Cross-Platform Mobile Apps 1
G Bluetooth Verbindung zwischen Handy und PC Android & Cross-Platform Mobile Apps 5
T Unterschiede zwischen CrEme 4.1 und J9 6.1 Android & Cross-Platform Mobile Apps 3
O Bluetooth Verbindung zwischen 2 Handys Android & Cross-Platform Mobile Apps 5
T Diskrepanz zwischen SUN Toolkit und NOKIA 6610i Android & Cross-Platform Mobile Apps 3
D messages via xml zwischen server/clienthandy verschicken Android & Cross-Platform Mobile Apps 5
B Zufallszahlen zwischen 1 und 49 erstellen? aber wie? Android & Cross-Platform Mobile Apps 7
N Android Zwei Buttons gleichzeitig drücken Android & Cross-Platform Mobile Apps 9
E Android Zwei Canvase übereinander legen und anzeigen Android & Cross-Platform Mobile Apps 7
M Zwei Android Geräte verbinden Android & Cross-Platform Mobile Apps 7
G zwei Runnable gleichzeitig Android & Cross-Platform Mobile Apps 3
T Zeit in zwei Zahlen für Widget zerlegen Android & Cross-Platform Mobile Apps 2
S Zwei Anfaengerfragen Android & Cross-Platform Mobile Apps 10

Ähnliche Java Themen

Neue Themen


Oben