web-dev-qa-db-fra.com

Comment accéder aux vues enfants de Fragment dans l'activité parent du fragment?

J'ai une activité prise en charge de fragment qui chargera des fragments diff. Le fragment a une textView avec id = "score" et je veux obtenir son pseudonyme mais findViewById pour la partition textView renvoie null. Pourquoi


textView est placé dans un fragment

public class MyActivity extends  extends ActionBarActivity
        implements NavigationDrawerFragment.NavigationDrawerCallbacks{

   private TextView scoreBoardTextView = null;

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_home);
     mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
     scoreBoardTextView = (TextView) findViewById(R.id.score); //this returns null
  }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
      //set fragment    
    }

}
62
user93796

Remarque:

Accéder directement aux vues de fragment en dehors de fragment n'est pas une bonne idée. Vous devez utiliser des interfaces fragmentées de rappel pour traiter de tels cas et éviter les bogues. La méthode suivante fonctionne mais elle n’est pas recommandée car ce n’est pas une bonne pratique .


Si vous voulez accéder à la TextView de Fragment dans son parent Activity, vous devez définir une méthode dans votre classe Fragment comme ceci:

public class MyFragment extends Fragment {

    TextView mTextView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_main, container, false);
        mTextView = (TextView) view.findViewById(R.id.textView1);
        return view;
    }

    public void setTextViewText(String value){
        mTextView.setText(value);
    }


}

Maintenant, vous pouvez utiliser ceci dans votre Activity comme ceci:

myFragment.setTextViewText("foo");

ici, myFragment est de type MyFragment.

Si vous souhaitez accéder à TextView entier, vous pouvez définir une méthode comme celle-ci dans MyFragment.Java:

public TextView getTextView1(){
    return mTextView;
}

En cela, vous pouvez accéder à la TextView elle-même.

J'espère que cela t'aides. :)

60
SMR

C'est possible avec la manière suivante:

Gardez la référence de la vue gonflée dans le fragment comme ceci:

public class MyFragment extends SherlockFragment{

MainMenuActivity activity;
public View view;
public MyFragment(){
}

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

    if ( getActivity() instanceof MainMenuActivity){
        activity = (MainMenuActivity) getActivity();
    }

    view = inflater.inflate(R.layout.aboutus, container, false);        
    return view;
}

}

Créez une fonction dans l'activité, comme ceci:

 public class MainMenuActivity extends SherlockFragmentActivity {

 SherlockFragment fragment = null;

 public void switchContent(SherlockFragment fragment) {     
    this.fragment = fragment;
    getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.mainmenu, fragment)
    .commit();

    invalidateOptionsMenu();
}

Son but est de garder la référence du fragment actuel. Chaque fois que vous voulez changer de fragment, vous appelez la fonction ci-dessus, comme ceci (à partir de fragment):

activity.switchContent( new MyFragment_2());

Maintenant, vous avez la référence actuelle du fragment. Ainsi, vous pouvez accéder directement aux vues de Fragment dans Activity comme ceci: this.fragment.view

22
Arsalan Mehmood

Vous n'avez pas besoin de référence de Fragment view pour obtenir ses composants dans Activité . Comme vous pouvez accéder directement aux composants de mise en page d'un Fragment in parent Activity

Simplement vous pouvez accéder à n'importe quel composant par cette

findViewById(R.id.child_of_fragment_layout);  
12
Ali Imran

Vous pouvez accéder avec la méthode getView de la classe Fragment.

Par exemple, vous avez un TextView dans votre MyFragment avec l'id de "text_view" 
Dans ton activité, fais un fragment de la vôtre:

MyFragment myFragment = new MyFragment();

Et lorsque vous avez besoin d'un enfant, appelez simplement getView puis recherchez Your childView.

View view = myFragment.getView();
if (view !=null) {
view.findViewById(R.id.text_view).setText("Child Accessed :D");
}
4
Saman Sattari

Pour accéder à TextView ou Button ou à tout autre élément de votre fragment, vous devez procéder comme suit:

public class BlankFragment extends Fragment {
public View view;
public TextView textView;
public Button button;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view =inflater.inflate(R.layout.fragment_blank, container, false);
    textView = (TextView)view.getRootView().findViewById(R.id.textView_fragment1);
    return view;
}

public void changeTextOfFragment(String text){
    textView.setText(text);
    view.setBackgroundResource(R.color.colorPrimaryDark);
}

Une fois que cela est fait dans votre MainActivity ou dans tout autre endroit où vous voulez accéder à votre TextView depuis votre fragment, vous devez vous assurer de configurer le fragment dans votre méthode OnCreate () de différentes manières par le biais de nullPointer. Ainsi, votre activité pour laquelle vous souhaitez modifier le mode TextView devrait ressembler à ceci:

public class MainActivity extends AppCompatActivity {
private Button button1;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
BlankFragment blankFragment = new BlankFragment();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button1 = (Button)findViewById(R.id.button1);
    changeFragment();

    fragmentManager = getFragmentManager();
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.fragment1,blankFragment);
    fragmentTransaction.commit();
}

private void changeFragment(){
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            blankFragment.changeTextOfFragment("Enter here the text which you want to be displayed on your Updated Fragment");

        }
    });
}

J'espère que cela t'aides :) 

3
F.A. Botic

Il suffit de mettre en fragment au lieu de mettre en activité:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_new_work_order,
    container, false);

    TextView scoreBoardTextView = (TextView) rootView.findViewById(R.id.score);

    return rootView;
}
2
Zoran

Si votre TextView est placé dans Fragment, vous ne pouvez pas accéder à TextView dans votre Activité parent Fragment vous pouvez définir l'interface d'intercommunication entre Fragment et Activity et envoyer des données lorsque vous cliquez sur TextView ou sur tout autre élément souhaité.

2
Ramkailash

Seulement faire ceci:

((Your_Activity) this.getActivity()).YouyActivityElements;
2
Lalit kumar

Vous ne pouvez pas accéder à l'élément Fragment dans Parent Activity, mais vous pouvez transmettre des valeurs à votre Fragment de la manière suivante.

dans votre méthode onNavigationDrawerItemSelected de MyActivity procédez comme suit

int myScore = 100;
@Override
public void onNavigationDrawerItemSelected(int position) {
    // update the main content by replacing fragments
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager
            .beginTransaction()
            .replace(R.id.container,
                    MyFragment.newInstance(myScore)).commit();
}

Et dans la classe MyFragment, créez une méthode appelée newInstance comme suit

private static final String SCORE = "score";
public static MyFragment newInstance(int score) {
    MyFragment fragment = new MyFragment();
    Bundle args = new Bundle();
    args.putInt(SCORE, score);
    fragment.setArguments(args);
    return fragment;
}

Et dans la méthode MyFragment's onCreateView() 

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container,
            false);
    TextView textView = (TextView) rootView
            .findViewById(R.id.score);
    textView.setText(Integer.toString(getArguments().getInt(
            SCORE)));
    return rootView;
}

C’est tout, j’espère que cela vous aidera. Si non s'il vous plaît faites le moi savoir.

0
Gunaseelan

La partition textView est dans la mise en page de fragment, ce n'est pas dans la mise en page de MyActivity, c'est-à-dire R.layout.activity_home. Ainsi, vous pourrez trouver la partition textview dans ce fragment une fois que vous aurez gonflé le fichier de mise en page correspondant.

0
Sherlock

J'utilise simplement des méthodes pour accéder aux vues de fragment de l'activité parent, car nous créons un nouvel objet de classe fragment pour insérer le fragment. Alors j'aime ça.

class BrowserFragment : Fragment(), Serializable {
    private lateinit var webView: NestedScrollWebView
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        webView = view.findViewById(R.id.web_view)
    }
    fun getWebView(): WebView {
        return webView
    }
}

Dans MainActivity

val browserFragment = BrowserFragment()
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.browser_fragment_placeholder, browserFragment)
fragmentTransaction.commit()

val webView = browserFragment.getWebView()
0
Jeeva

Vous devez appeler la méthode findViewById à partir de votre vue fragmentée.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
    scoreBoardTextView = (TextView) mNavigationDrawerFragment.getView().findViewById(R.id.score); 
}

Cette façon fonctionne pour moi.

0
Yoric

Déclarez simplement TextView comme public dans fragment, initialisez-le avec findViewById () dans onCreateView () du fragment. Maintenant, en utilisant l’objet Fragment que vous avez ajouté à l’activité, vous pouvez accéder à TextView.

0
Himanshu Gupta

Je vous suggère d'intégrer la fonction textview à la présentation de votre activité. Alternativement, vous pouvez avoir la vue texte en tant que fragment séparé. Regardez ma question ici. Son semblable au vôtre mais en sens inverse. Voici une version simplifiée du code que j'ai utilisé dans mon projet. Les explications sont le long du code.

La classe d'activité

public class MainActivity extends ActionBarActivity {
PlaceFragment fragment;
TextView fragmentsTextView;

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

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Bundle bundle = new Bundle();
    bundle.putString("score", "1000");
    fragment = PlaceFragment.newInstance(bundle);
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.container, fragment);
    ft.addToBackStack(null);
    ft.commit();
    // method 1
    // fragment is added some ways to access views
    // get the reference of fragment's textview
    if (fragment.getTextView() != null) {
        fragmentsTextView = fragment.getTextView();
    }
    // method 2
    // using static method dont use in production code
    // PlaceFragment.textViewInFragment.setText("2000");

    // method 3
    // let the fragment handle update its own text this is the recommended
    // way wait until fragment transaction is complete before calling
    //fragment.updateText("2000");

}

}

La classe de fragments:

public class PlaceFragment extends Fragment {
public TextView textViewInFragment;// to access via object.field same to
                                    // string.length

// public static TextView textViewInFragment;//to access via
// PlaceFragment.textView dont try this in production code
public PlaceFragment() {
}

public static PlaceFragment newInstance(Bundle bundle) {
    PlaceFragment fragment = new PlaceFragment();
    fragment.setArguments(bundle);
    return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View view = inflater.inflate(R.layout.fragment_place, container, false);
    textViewInFragment = (TextView) view
            .findViewById(R.id.textViewInFragment);
    return view;
}

@Override
public void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    if (getArguments() != null) {
        textViewInFragment.setText(getArguments().getString("score"));

    }
}

public TextView getTextView() {
    if (textViewInFragment != null) {
        return textViewInFragment;// returns instance of inflated textview
    }
    return null;// return null and check null
}

public void updateText(String text) {
    textViewInFragment.setText(text);// this is recommended way to alter
                                        // view property of fragment in
                                        // activity
}

}

La communication d'une activité à une autre est simple. C'est parce que l'activité contient un fragment. Conservez l'objet fragment et accédez à sa propriété via des setters et des getters ou les champs publics à l'intérieur de celui-ci. Mais la communication de fragment en activité nécessite une interface. 

0
Illegal Argument

Il retourne null car la TextView est un élément de la Fragment, pas la Activity

Veuillez noter que l'idée d'utiliser Fragment consiste à encapsuler un module dans la Fragment, ce qui signifie que la Activity ne devrait pas avoir un accès direct à ses propriétés. Pensez à déplacer votre logique là où vous obtenez la référence TextView à l'intérieur de la Fragment

0

Si la vue est déjà gonflée (visible, par exemple) à l'écran, vous pouvez simplement utiliser findViewById (R.id.yourTextView) dans l'activité comme d'habitude et retourner le descripteur à la vue texte ou la valeur null si la vue n'a pas été trouvée.

0
sham

pourquoi vous n'y accédez pas directement à partir de votre FragmentPagerAdapter, 

SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);

et voici l'exemple complet:

import Android.content.Intent;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.support.v4.app.FragmentManager;
import Android.support.v4.app.FragmentPagerAdapter;
import Android.support.v4.app.FragmentTransaction;
import Android.support.v4.view.ViewPager;
import Android.support.v7.app.ActionBar;
import Android.support.v7.app.ActionBarActivity;
import Android.view.Menu;
import Android.view.MenuItem;
import Android.view.View;
import Android.widget.ImageView;
import Android.widget.TextView;

import Java.util.Locale;


public class TabsActivity extends ActionBarActivity implements ActionBar.TabListener {

    /**
     * The {@link Android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link Android.support.v4.app.FragmentStatePagerAdapter}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will Host the section contents.
     */
    ViewPager mViewPager;

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

        // Set up the action bar.
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            ActionBar.Tab tab = actionBar.newTab();

            View tabView = this.getLayoutInflater().inflate(R.layout.activity_tab, null);

            ImageView icon = (ImageView) tabView.findViewById(R.id.tab_icon);
            icon.setImageDrawable(getResources().getDrawable(mSectionsPagerAdapter.getPageIcon(i)));

            TextView title = (TextView) tabView.findViewById(R.id.tab_title);
            title.setText(mSectionsPagerAdapter.getPageTitle(i));

            tab.setCustomView(tabView);

            tab.setTabListener(this);

            actionBar.addTab(tab);
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_tabs, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_logout) {
            finish();
            gotoLogin();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        mViewPager.setCurrentItem(tab.getPosition());
    }

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

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

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public ProfileFragment profileFragment;
        public SubAccountFragment subAccountFragment;
        public ChatFragment chatFragment;

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
            profileFragment = new ProfileFragment();
            subAccountFragment = new SubAccountFragment();
            chatFragment = new ChatFragment();
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return profileFragment;
                case 1:
                    return subAccountFragment;
                case 2:
                    return chatFragment;
            }
            return null;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return getString(R.string.title_section1).toUpperCase(l);
                case 1:
                    return getString(R.string.title_section2).toUpperCase(l);
                case 2:
                    return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }

        public int getPageIcon(int position) {
            switch (position) {
                case 0:
                    return R.drawable.tab_icon_0;
                case 1:
                    return R.drawable.tab_icon_1;
                case 2:
                    return R.drawable.tab_icon_2;
            }
            return 0;
        }
    }


    public void gotoLogin() {
        Intent intent = new Intent(this, LoginActivity.class);
        this.startActivity(intent);
    }

    public void requestConnectPressed(View view){
        SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
        subAccountFragment.requestConnectPressed(view);
    }
}
0
Fareed Alnamrouti