web-dev-qa-db-fra.com

Android Définir le texte de TextView dans Fragment qui est dans FragmentPagerAdapter

Celui-ci me rend fou. Fondamentalement, je veux créer un ViewPager et y ajouter quelques Fragment. Ensuite, tout ce que je veux faire, il définit une valeur dans l'un des FragmentTextViews. Je peux ajouter le Fragments très bien, et ils se joignent, mais quand je vais à findViewById() pour l'un des TextViews dans le premier Fragment il jette un NullPointerException. Pour ma vie, je n'arrive pas à comprendre pourquoi.

Voici mon code jusqu'à présent, faites-moi savoir si plus est nécessaire, s'il vous plaît.

public class SheetActivity extends FragmentActivity {

    // /////////////////////////////////////////////////////////////////////////
    // Variable Declaration
    // /////////////////////////////////////////////////////////////////////////
    private ViewPager               viewPager;
    private PagerTitleStrip         titleStrip;
    private String                  type;
    private FragmentPagerAdapter    fragmentPager;  //UPDATE

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sheet);

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        titleStrip = (PagerTitleStrip) findViewById(R.id.viewPagerTitleStrip);

        // Determine which type of sheet to create
        Intent intent = getIntent();
        this.type = intent.getStringExtra("type");
        FragmentManager manager = getSupportFragmentManager();
        switch (type) {
            case "1":
                viewPager.setAdapter(new InstallAdapter(manager));
                break;
            case "2":
                viewPager.setAdapter(new InstallAdapter(manager));
                break;
        }
        fragmentPager = (FragmentPagerAdapter) viewPager.getAdapter();  //UPDATE
    }

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

        fragmentPager.getItem(0).setText("something"); //UPDATE
    }

    class MyAdapter extends FragmentPagerAdapter {

        private final String[]      TITLES      = { "Title1", "Title2" };
        private final int           PAGE_COUNT  = TITLES.length;
        private ArrayList<Fragment> FRAGMENTS   = null;

        public MyAdapter(FragmentManager fm) {
            super(fm);
            FRAGMENTS = new ArrayList<Fragment>();
            FRAGMENTS.add(new FragmentA());
            FRAGMENTS.add(new FragmentB());
        }

        @Override
        public Fragment getItem(int pos) {
            return FRAGMENTS.get(pos);
        }

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

        @Override
        public CharSequence getPageTitle(int pos) {
            return TITLES[pos];
        }
    }
}

Tous les Fragments que j'ai créés n'ont que la méthode onCreateView() remplacée pour que je puisse afficher la disposition XML appropriée. En dehors de cela, ils sont "stock". Pourquoi ne puis-je pas interagir avec des éléments dans l'un des Fragments?

MISE À JOUR:

Alors, fais quelque chose comme ça?

public class FragmentA extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle inState) {
        return inflater.inflate(R.layout.fragment_a, container, false);
    }

    public void setText(String text) {
        TextView t = (TextView) getView().findViewById(R.id.someTextView);  //UPDATE
        t.setText(text);
    }
}

DISPOSITION XML POUR LE FRAGMENT A

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical" >

    <TextView
        Android:id="@+id/someTextView"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight="1"
        Android:textSize="22sp" />

</LinearLayout>
8
Josh I

Sauf si vous prévoyez de modifier la valeur lors de l'exécution, vous pouvez transmettre la valeur dans le fragment en tant que paramètre. Cela se fait en utilisant un bundle et en le passant comme arguments dans un fragment, qui le récupère ensuite de ses arguments. Plus d'informations ici . Si vous implémentez cela, votre instanciation de nouveaux fragments pourrait ressembler à ceci:

public InstallAdapter(FragmentManager fm) {
            super(fm);
            FRAGMENTS = new ArrayList<Fragment>();
            FRAGMENTS.add(FragmentA.newInstance("<text to set to the TextView>"));
            FRAGMENTS.add(FragmentB.newInstance("<text to set to the TextView>"));
        }

Si, toutefois, vous prévoyez de mettre à jour la valeur au moment de l'exécution (elle changera au fur et à mesure que l'utilisateur exécute l'application), vous souhaitez utiliser une interface pour modifier la communication entre votre fragment et votre activité. Infos ici . Voici à quoi cela pourrait ressembler:

//Declare your values for activity;
    ISetTextInFragment setText;
    ISetTextInFragment setText2;
...
//Add interface
public interface ISetTextInFragment{
    public abstract void showText(String testToShow);
}
...
//your new InstallAdapter
public InstallAdapter(FragmentManager fm) {
        super(fm);

        FRAGMENTS = new ArrayList<Fragment>();

        Fragment fragA = new FragmentA();
        setText= (ISetTextInFragment)fragA;
        FRAGMENTS.add(fragA);

        Fragment fragB = new FragmentB();
        setText2= (ISetTextInFragment)fragB;
        FRAGMENTS.add(fragB);
}

//then, you can do this from your activity:
...
setText.showText("text to show");
...

et il mettra à jour votre affichage de texte dans le fragment.

Bien que cela puisse être fait "plus facilement", ces méthodes sont recommandées car elles réduisent les risques de bogues et rendent le code beaucoup plus lisible et maintenable.

EDIT: voici à quoi devrait ressembler votre Fragment (modification de votre code):

public class FragmentA extends Fragment implements ISetTextInFragment {

    TextView myTextView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle inState) {
        View v = inflater.inflate(R.layout.fragment_a, container, false);
        myTextView = (TextView)v.findViewbyId(R.id.someTextView)
        return v;
    }

    @Override
    public void showText(String text) {
        myTextView.setText(text);
    }
}

Si après cela, vous obtenez toujours une exception de pointeur nul, votre TextView ne se trouve PAS là où il me faut, à savoir dans le filem R.layout.fragment_a, et il doit y être localisé. Sauf si vous appelez la méthode d'interface AVANT le chargement du fragment, bien sûr.

4
C0D3LIC1OU5

Le TextView est situé dans la disposition des fragments, pas dans le ViewPagers ou le PagerAdapter, qui est à l'origine du NPE. Maintenant, vous avez 2 options.

  • Le premier est le plus simple, vous devez simplement déplacer votre code pour changer le texte dans la classe du fragment correspondant, FragmentA dans ce cas.
  • Deuxièmement, vous pouvez transformer le TextView en FragmentA statique, afin qu'il soit accessible par d'autres classes. Votre code ressemblerait donc à ceci:

     ....
     TextView myText;
    
     @Override
     public View onCreateView(....) {
    
         myLayout = ....;
    
         myText = myLayout.findViewById(yourID);
    
         ....
    }
    

Et puis vous changeriez le texte ailleurs (si c'est vraiment nécessaire):

   FragmentA.myText.setText("new text");

Explication de la méthode 2

Utilisez ce qui suit dans votre fragment.

public static void setText(String text) {
    TextView t = (TextView) getView().findViewById(R.id.someTextView);
    t.setText(text);
}

Modifiez ensuite le texte comme:

FragmentA.setText("Lulz");
5
Aashir

Cette ligne:

TextView t = (TextView) findViewById(R.id.someTextViewInFragmentA);

recherche la vue dans votre ParentActivity. Bien sûr, il ne le trouvera pas et c'est à ce moment que vous obtenez votre NPE.

Essayez quelque chose comme ceci:

  1. Ajoutez un "tag" à vos fragments lorsque vous les ajoutez

  2. Utilisez someFragment = getSupportFragmentManager().findFragmentByTag("your_fragment_tag")

  3. Obtenez la vue du fragment fragmentView = someFragment.getView();

  4. Et enfin trouvez votre TextView et définissez le texte

    TextView t = (TextView) fragmentView.findViewById(R.id.someTextViewInFragmentA); t.setText("some text");

1
Carlos J

Que diriez-vous de changer cette ligne

TextView t = (TextView) getView().findViewById(R.id.someTextView);  //UPDATE

à

TextView t = (TextView) getActivity().findViewById(R.id.someTextView);  //UPDATE

alors vous pouvez essayer de mettre à jour "t" avec .setText ("some_string") dans "SheetActivity".

0
Artis JIANG