2013-05-15 13 views
10

Jak sugeruje tytuł.
Pobrałem kod Fragment stąd,.
To jest przykład fragmentu z oficjalnej witryny dla programistów Androida. http://developer.android.com/training/basics/fragments/fragment-ui.htmlFragment Androida getArguments() zwraca wartość null

To MainActivity.java 's onCreate():

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.news_articles); 

    // Check whether the activity is using the layout version with 
    // the fragment_container FrameLayout. If so, we must add the first fragment 
    if (findViewById(R.id.fragment_container) != null) { 

     // However, if we're being restored from a previous state, 
     // then we don't need to do anything and should return or else 
     // we could end up with overlapping fragments. 
     if (savedInstanceState != null) { 
      return; 
     } 

     // Create an instance of ExampleFragment 
     HeadlinesFragment fragment = new HeadlinesFragment(); 

     // In case this activity was started with special instructions from an Intent, 
     // pass the Intent's extras to the fragment as arguments 
     //fragment.setArguments(getIntent().getExtras()); 
     Bundle args= new Bundle(); 
     args.putString("category", "clothes"); 
     args.putString("item", "shirts"); 
     fragment.setArguments(args); 

     // Add the fragment to the 'fragment_container' FrameLayout 
     getSupportFragmentManager().beginTransaction() 
       .replace(R.id.fragment_container, fragment).commit(); 
    } 
} 

I HeadlinesFragment.java' s onCreate():

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // We need to use a different list item layout for devices older than Honeycomb 
    int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
      android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1; 

    Bundle args = getArguments(); 
    if (args == null) { 
     Toast.makeText(getActivity(), "arguments is null " , Toast.LENGTH_LONG).show(); 
    } else { 
     Toast.makeText(getActivity(), "text " + args , Toast.LENGTH_LONG).show(); 
    }   

    // Create an array adapter for the list view, using the Ipsum headlines array 
    setListAdapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines)); 

} 

Czytałem kilka QA tutaj, jak ten Fragment getArguments() returns null i wiele inne związane z setArguments() i , ale nadal utknąłem.

A ja przeniósł Bundle i Toast kod do onAttach() i onCreateView() z bezskutecznie. Co jest nie tak z moim kodem? Myślę, że czegoś brakuje, ale nie wiem co to jest.
Proszę o pomoc! Dzięki.

Edytuj:
Wyrażam wyraźniej moją intencję. W pobranym fragmencie FragmentBasic znajdują się MainActivity.java, HeadlinesFragment.java i ArticleFragment.java. "Komunikacja" od MainActivity.java do ArticlesFragment.java nie jest tutaj problemem. Chcę tylko wysłać dane z MainActivity.java do HeadlinesFragment.java. Ich połączenie jest następujące:

-------------------------------------- 
| MainActivity <-> HeadlinesFragment | 
|  |        | 
|  |>> ArticlesFragment   | 
-------------------------------------- 

I HeadlinesFragment działa w środowisku wykonawczym.

* Ten kod działa, gdy używasz gadżetu Android z rozszerzeniem < o szerokości 600 pikseli. Ale nie działa podczas korzystania z tabletu (> = 600px), Jak udowodniono przez @ Tesla1984 poniżej. Ale to, czego chcę, to ten sam wynik na gadżecie < 600px i gadżecie> 600px.

+0

Sprawdziłem kod i 'getArguments()' nie jest pusty. jeśli powyższy kod jest twoim rzeczywistym kodem, nie sądzę, że coś jest nie tak. jeśli nie, sprawdź zmienne? – tesla1984

+0

@ tesla1984: w której części wstawiasz swój kod? w HeadlinesFragment.java lub ArticlesFragment.java? Bo gdziekolwiek wstawię 'getArguments()' w HeadlinesFragment.java, otrzymuję wartość null. Dzięki. – tonny

+0

Czasami moje zaćmienie + ADT nie działa! .. Potrzebuję oczyścić projekt i ponownie uruchomić ... –

Odpowiedz

1

mam rozwiązać go. Wygląda na to, że jedynym sposobem przesyłania danych z MainActivity.java do HeadlinesFragment.java jest wywołanie zwrotne (jeśli ktoś inny zna inne sposoby, proszę o przyczynianie się, to mamy inne sposoby poza tym, pomagając innym w tego rodzaju problemach).

Głównym Kod z jest funkcją MainActivity.java za public Bundle getBundle() {}, a następnie ustawić sekcję interface na HeadlinesFragment.java i dodać public Bundle getBundle(); i wreszcie wywołać ją z HeadlinesFragment.java na onCreate.

Co mnie mylić to fragment.setArguments(getIntent().getExtras()); na MainActivity.java's onCreate. Umieszczono tam ten kod i wierzę, że zadziała, ponieważ jest od oficjalnego podręcznika programisty Androida i APIhttp://developer.android.com/training/basics/fragments/fragment-ui.html, ale to nie zadziałało (teraz uważam, że fragment kodu nic nie da). Tak więc każdy, kto czyta tutorial lub próbkę, bierze to z przymrużeniem oka!

Poniższe kody, aby każdy mógł je zrozumieć.

MainActivity.java:

/* 
* Copyright (C) 2012 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 
package com.example.android.fragments; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentTransaction; 
import android.widget.Toast; 

public class MainActivity extends FragmentActivity 
     implements HeadlinesFragment.OnHeadlineSelectedListener { 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.news_articles); 

     // Check whether the activity is using the layout version with 
     // the fragment_container FrameLayout. If so, we must add the first fragment 
     if (findViewById(R.id.fragment_container) != null) { 

      // However, if we're being restored from a previous state, 
      // then we don't need to do anything and should return or else 
      // we could end up with overlapping fragments. 
      if (savedInstanceState != null) { 
       return; 
      } 

      Toast.makeText(getApplicationContext(), "activity", Toast.LENGTH_LONG).show(); 

      // Create an instance of ExampleFragment 
      HeadlinesFragment fragment = new HeadlinesFragment(); 

      // In case this activity was started with special instructions from an Intent, 
      // pass the Intent's extras to the fragment as arguments 
      fragment.setArguments(getIntent().getExtras()); 

      // Add the fragment to the 'fragment_container' FrameLayout 
      getSupportFragmentManager().beginTransaction() 
        .replace(R.id.fragment_container, fragment).commit(); 
     } 
    } 

    public void onArticleSelected(int position) { 
     // The user selected the headline of an article from the HeadlinesFragment 

     // Capture the article fragment from the activity layout 
     ArticleFragment articleFrag = (ArticleFragment) 
       getSupportFragmentManager().findFragmentById(R.id.article_fragment); 

     if (articleFrag != null) { 
      // If article frag is available, we're in two-pane layout... 

      // Call a method in the ArticleFragment to update its content 
      articleFrag.updateArticleView(position); 

     } else { 
      // If the frag is not available, we're in the one-pane layout and must swap frags... 

      // Create fragment and give it an argument for the selected article 
      ArticleFragment newFragment = new ArticleFragment(); 
      Bundle args = new Bundle(); 
      args.putInt(ArticleFragment.ARG_POSITION, position); 
      newFragment.setArguments(args); 
      FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 

      // Replace whatever is in the fragment_container view with this fragment, 
      // and add the transaction to the back stack so the user can navigate back 
      transaction.replace(R.id.fragment_container, newFragment); 
      transaction.addToBackStack(null); 

      // Commit the transaction 
      transaction.commit(); 
     } 
    } 

    public Bundle getBundle() { 
     Bundle args = new Bundle(); 
     args.putString("category", "cloths"); 
     args.putString("item", "shirts"); 
     return args; 
    } 
} 

HeadlinesFragment.java:

/* 
* Copyright (C) 2012 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 
package com.example.android.fragments; 

import android.app.Activity; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v4.app.ListFragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Toast; 

public class HeadlinesFragment extends ListFragment { 
    OnHeadlineSelectedListener mCallback; 

    // The container Activity must implement this interface so the frag can deliver messages 
    public interface OnHeadlineSelectedListener { 
     /** Called by HeadlinesFragment when a list item is selected */ 
     public void onArticleSelected(int position); 
     public Bundle getBundle(); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     Bundle bundle = mCallback.getBundle(); 
     Toast.makeText(getActivity(), "headline fragment " + bundle, Toast.LENGTH_LONG).show(); 

     // We need to use a different list item layout for devices older than Honeycomb 
     int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
       android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1; 

     // Create an array adapter for the list view, using the Ipsum headlines array 
     setListAdapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines)); 

    } 

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

     return super.onCreateView(inflater, container, savedInstanceState); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 

     // When in two-pane layout, set the listview to highlight the selected list item 
     // (We do this during onStart because at the point the listview is available.) 
     if (getFragmentManager().findFragmentById(R.id.article_fragment) != null) { 
      getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
     } 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 

     // This makes sure that the container activity has implemented 
     // the callback interface. If not, it throws an exception. 
     try { 
      mCallback = (OnHeadlineSelectedListener) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
        + " must implement OnHeadlineSelectedListener"); 
     } 
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     // Notify the parent activity of selected item 
     mCallback.onArticleSelected(position); 

     // Set the item as checked to be highlighted when in two-pane layout 
     getListView().setItemChecked(position, true); 
    } 
} 
+2

Metoda 'getArguments()' nie będzie miała wartości 'null' jeśli ustawisz argumenty. i nie sugeruję, abyś użył 'callbacku' do pobrania 'bundle'. – tesla1984

+1

@ tesla1984: Przeczytaj moje pytanie. I kod. Argument został ustawiony. Czy próbowałeś uruchomić kod? Z dodanymi 'setArguments()' i 'getArguments()'? Najpierw myślę, że to jest sposób, z set-getArguments(), ale myliłem się. Aha, i jeśli masz rozwiązanie, które działa, opublikuj to poniżej. Przyjmuję twoją odpowiedź, jeśli kod działa i nie używa połączeń zwrotnych. – tonny

0

Wygląda na to, że wstawiasz parę kluczy i wartości do swojego pakietu. Prawdopodobnie musisz odwołać się do wartości klucza, jak w getArguments().getString(category);

Zgodnie z dokumentami dla putString: Wstawia wartość String do mapowania tego pakietu, zastępując istniejącą wartość dla danego klucza. Każdy klucz lub wartość może mieć wartość NULL.

Parametry klucz String lub null wartość String lub null

+1

'String category = getArguments(). GetString (" category ");' masz na myśli? Próbowałem tego. Pokazuje błąd, a program zostanie zamknięty. Możesz również przeczytać tę kontrolę jakości. Biorę przykład kodu Toast [Fragment getArguments() zwraca null] (http: // stackoverflow.com/questions/14970790/fragment-getarguments-zwraca-null) – tonny

7

@tonny

mam pobrać FragmentBasics.zip. zmieniam tylko nazwę argumentu. jest kod i pic wyniku.

główną działalność

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.news_articles); 

    // Check whether the activity is using the layout version with 
    // the fragment_container FrameLayout. If so, we must add the first fragment 
    if (findViewById(R.id.fragment_container) != null) { 

     // However, if we're being restored from a previous state, 
     // then we don't need to do anything and should return or else 
     // we could end up with overlapping fragments. 
     if (savedInstanceState != null) { 
      return; 
     } 

     // Create an instance of ExampleFragment 
     HeadlinesFragment fragment = new HeadlinesFragment(); 

     // In case this activity was started with special instructions from an Intent, 
     // pass the Intent's extras to the fragment as arguments 
//   firstFragment.setArguments(getIntent().getExtras()); 
     //test 
     Bundle args= new Bundle(); 
     args.putString("category", "clothes"); 
     args.putString("item", "shirts"); 
     fragment.setArguments(args); 

     // Add the fragment to the 'fragment_container' FrameLayout 
     getSupportFragmentManager().beginTransaction() 
       .replace(R.id.fragment_container, fragment).commit(); 
    } 
} 

HeadlinesFragment

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // We need to use a different list item layout for devices older than Honeycomb 
    int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
      android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1; 

    Bundle args = getArguments(); 
    if (args == null) { 
     Toast.makeText(getActivity(), "arguments is null " , Toast.LENGTH_LONG).show(); 
    } else { 
     Toast.makeText(getActivity(), "text " + args , Toast.LENGTH_LONG).show(); 
    }  

    // Create an array adapter for the list view, using the Ipsum headlines array 
    setListAdapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines)); 
} 

oto wynik

enter image description here

+0

Tak, wygląda na to, że działa, gdy używana jest rozdzielczość <600px. Wypróbuj go, gdy korzystasz z Nexus7 AVD. Oczywiście chcemy tego samego rezultatu podczas korzystania z tabletu lub telefonu (> 600px i <600px). Dzięki – tonny

3

Miałem ten sam problem, ale go rozwiązałem :)

Mój problem polegał na tym, że miałem element <fragment android:name=""> w układzie XML Activity. Dlatego onCreate() Fragmentu został wywołany przed wywołaniami w kodzie Java, nie ustawiając w ten sposób argumentów.

Usunąłem element <fragment> z mojego układu XML i zadziałało!

Powiązane problemy