Как получить доступ к дочерним представлениям фрагмента внутри родительской активности фрагмента?

У меня есть поддерживаемая функция фрагмента, которая будет загружать diff-фрагменты. Фрагмент имеет некоторый textView с id = "score" и я хочу получить его дескриптор, но findViewById для textView для textView возвращает null. Почему так?

TextView помещается в фрагмент

 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 } } 

Solutions Collecting From Web of "Как получить доступ к дочерним представлениям фрагмента внутри родительской активности фрагмента?"

Если вы хотите получить доступ к TextView of Fragment внутри своей родительской Activity вы должны определить метод внутри вашего класса Fragment следующим образом:

MyFragment.java

 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); } } 

Теперь вы можете использовать это внутри своей Activity следующим образом:

 myFragment.setTextViewText("foo"); 

Здесь myFragment имеет тип MyFragment .

Если вы хотите получить доступ ко всему TextView вы можете определить такой метод внутри MyFragment.java :

 public TextView getTextView1(){ return mTextView; } 

Благодаря этому вы можете получить доступ к самому TextView .

Надеюсь это поможет. 🙂

Это возможно следующим образом:

Держите ссылку на раздутый вид в Фрагменте следующим образом:

 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; } } 

Создайте функцию в Activity, например:

  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(); } 

Его цель – сохранить ссылку на текущий фрагмент. Всякий раз, когда вы хотите сменить фрагмент, вы вызываете функцию выше, как это (из фрагмента):

 activity.switchContent( new MyFragment_2()); 

Теперь у вас есть ссылка на текущий фрагмент. Таким образом, вы можете напрямую обращаться к представлениям Fragment в Activity следующим образом: this.fragment.view

Вам не нужно ссылаться на представление фрагмента, чтобы получить его компоненты в Activity . Поскольку вы можете напрямую обращаться к компонентам компоновки фрагмента в родительской активности .

Просто вы можете получить доступ к любому компоненту с помощью этого

 findViewById(R.id.child_of_fragment_layout); 

Вы можете получить доступ с помощью метода getView класса Fragment.

Например, у вас есть TextView в My MyFragment с идентификатором «text_view»
В своей деятельности сделайте свой фрагмент:

 MyFragment myFragment = new MyFragment(); 

И когда вам нужен ребенок, просто позвоните в getView, а затем найдите ChildView.

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

Если ваш TextView размещен внутри фрагмента в этом случае, вы не можете получить доступ к TextView внутри своей родительской активности фрагментов, вы можете установить интерфейс для взаимодействия между фрагментом и активностью и отправить данные, когда вы нажимаете TextView или любую другую вещь, которую вы хотите выполнить

Только это:

 ((Your_Activity) this.getActivity()).YouyActivityElements; 

Просто добавьте фрагмент вместо того, чтобы вводить в действие:

 @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; } 

Оценка textView находится в макете фрагмента, это не в макете MyActivity, то есть R.layout.activity_home. Таким образом, вы можете найти текстовое представление счёта в этом фрагменте, как только вы надуваете соответствующий файл макета.

Он возвращает null потому что TextView является элементом Fragment , а не Activity .

Обратите внимание, что идея использования Fragment заключается в инкапсуляции модуля внутри Fragment , что означает, что Activity не должна иметь прямого доступа к его свойствам. Рассмотрите возможность перемещения своей логики, когда вы получаете ссылку TextView внутри Fragment

Вы не можете получить доступ к элементу Fragment в родительской Activity , но вы можете передавать значения в свой Fragment следующим образом.

onNavigationDrawerItemSelected методе MyActivity выполните следующие действия:

 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(); } 

А в классе MyFragment создайте метод newInstance например, следующий

 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; } 

И в MyFragment 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; } 

Это все, надеюсь, это поможет вам. Если нет, пожалуйста, дайте мне знать.

Просто объявите TextView как общедоступный в фрагменте, инициализируйте его findViewById () в onCreateView () фрагмента. Теперь, используя объект фрагмента, который вы добавили в действие, вы можете получить доступ к TextView.

Вам нужно вызвать метод findViewById из представления вашего фрагмента.

 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); } 

Этот способ работает для меня.

Я предлагаю вам сделать часть текста вашего макета. В качестве альтернативы вы можете иметь текстовое представление как фрагмент separete. Посмотрите на мой вопрос здесь. Он похож на ваш, но в обратном направлении. Вот урезанная версия кода, который я использовал в моем проекте. Объяснение приведено в коде.

Класс активности

 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"); } } 

Класс фрагмента:

 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 } } 

Коммуникация от деятельности к фрагменту является прямой. Это связано с тем, что активность содержит фрагмент. Храните объект фрагмента и получите доступ к его свойству через сеттеры и геттеры или публичные поля внутри него. Но для связи от фрагмента к активности требуется интерфейс.

Почему вы не обращаетесь к нему напрямую из вашего FragmentPagerAdapter,

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

И вот полный пример:

 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); } } 

Если представление уже надуто (например, видимо) на экране, вы можете просто использовать findViewById (R.id.yourTextView) в действии как обычно, и он вернет дескриптор в текстовое представление или null, если представление не было найдено.