为什么在Activity中访问Fragment的TextView会抛出错误

MainActivity类:

 /* all necessary imports */ public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { /* Other variable initialized here... */ FragOne fo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); fo.setTextViewText("This is added from Activity"); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); viewPager = (ViewPager) findViewById(R.id.viewpager); setupViewPager(viewPager); tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); } private void setupViewPager(ViewPager viewPager) { ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new FragOne(), "My Tracker"); adapter.addFragment(new FragTwo(), "Team Tracker"); viewPager.setAdapter(adapter); } class ViewPagerAdapter extends FragmentPagerAdapter { private final List mFragmentList = new ArrayList(); private final List mFragmentTitleList = new ArrayList(); public ViewPagerAdapter(FragmentManager manager) { super(manager); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void addFragment(Fragment fragment, String title) { mFragmentList.add(fragment); mFragmentTitleList.add(title); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position); } } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. int id = item.getItemId(); if (id == R.id.nav_manage) { } else if (id == R.id.nav_share) { } else if (id == R.id.nav_send) { } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } } 

Fragment类:

 /* all necessary imports */ public class FragOne extends Fragment { TextView tvCName; public FragOne() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_frag_one, container, false); return view; //return inflater.inflate(R.layout.fragment_frag_one, container, false); } @Override public void onViewCreated(View view , Bundle savedInstanceState) { tvCName = (TextView) view.findViewById(R.id.tvctq); } public void setTextViewText(String value){ tvCName.setText(value); } } 

Fragment XML布局:

    

我试图从MainActivity访问FragmentTextView ,如下所示:

 FragOne fo; fo.setTextViewText("This is added from Activity"); 

我一直得到一个NullPointerExceptionError 。 我看了所有的文章,看看如何访问,但没有一个帮助我。

有人可以让我知道我做错了什么以及如何解决它?

我还打算在我的Fragment中添加其他View ,我将来需要访问它。

因为fo尚未在以下代码段中初始化:

 FragOne fo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); fo.setTextViewText("This is added from Activity"); ... } 

fo.setTextViewText()合理地抛出NPE

您必须注意Activity生命周期 – 您似乎正确地设置了所有内容,但在实际准备好的时候犯了一些错误来访问片段的正确实例。 你应该做的事情

  1. ViewPager获取片段的正确实例,如@ginomempin建议;
  2. 只是尝试不早些时候设置你的文本然后onStart你的活动onStart方法 – 我通常在onResume方法上做(如果你还没有,你可以覆盖它)。 在活动中的onResume方法中执行此操作可确保您的Fragment已经经历了它的生命周期,直到onResume ,并且如果先前已将数据带到后台,则数据将刷新。

这是一个生命周期图供您参考: 在此处输入图像描述

在活动中创建Fragment时,需要使用Fragment工厂方法。 请看下面:

**

背堆

**

修改片段的事务可以放在拥有活动的内部后台上。 当用户按下活动时,后台堆栈上的任何事务都会在活动本身完成之前弹出。

例如,考虑使用整数参数实例化的这个简单片段,并在其UI中的TextView中显示:

 public static class CountingFragment extends Fragment { int mNum; /** * Create a new instance of CountingFragment, providing "num" * as an argument. */ static CountingFragment newInstance(int num) { CountingFragment f = new CountingFragment(); // Supply num input as an argument. Bundle args = new Bundle(); args.putInt("num", num); f.setArguments(args); return f; } /** * When creating, retrieve this instance's number from its arguments. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNum = getArguments() != null ? getArguments().getInt("num") : 1; } /** * The Fragment's UI is just a simple text view showing its * instance number. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.hello_world, container, false); View tv = v.findViewById(R.id.text); ((TextView)tv).setText("Fragment #" + mNum); tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb)); return v; } } 

创建片段的新实例的函数,替换正在显示的任何当前片段实例,并将该更改推送到后栈可写为:

 void addFragmentToStack() { mStackLevel++; // Instantiate a new fragment. Fragment newFragment = CountingFragment.newInstance(mStackLevel); // Add the fragment to the activity, pushing this transaction // on to the back stack. FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.simple_fragment, newFragment); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.addToBackStack(null); ft.commit(); } 

每次调用此函数后,堆栈中都会出现一个新条目,然后按下该条目将弹出该条目以将用户返回到活动UI所处的任何先前状态。

资料来源: https : //developer.android.com/reference/android/app/Fragment.html

您需要从viewpager获取相同的FragOne实例。

首先,您只能在设置FragOne后访问FragOne实例。
然后,试试这个:

 fo = adapter.getItem(0) 

注意:
由于您已经有片段,因此最好让片段本身处理与UI相关的操作(例如设置textview)而不是Activity。