android - 无法访问片段方法内的视图。它 returns 空对象
android - can't access view inside fragment method. it returns null object
我正在构建一个基于 android studio 的 tabbedActivity 预设的应用程序,因此创建了片段:
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 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.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
及以后:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
DashboardTab tabDashboard = new DashboardTab();
return tabDashboard;
case 1:
VertretungsplanTab tabVertretungsplan = new VertretungsplanTab();
return tabVertretungsplan;
default:
return null;
}
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Dashboard";
case 1:
return "Vertretungsplan";
}
return null;
}
}
一切正常,但实际上这是一种非常不常见的创建选项卡的方式,所以我的问题可能是由于对 MainActivity.java
的误解造成的
public class VertretungsplanTab extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.vertretungsplan_fragment, container, false);
return rootView;
}
public void setText(String textToBeSet, VertretungsplanTab tab){
TextView tv = (TextView) getView().findViewById(R.id.textView2);
}
现在问题是由视图引起的,因为它是我方法中的空对象。
Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
我尝试了几种访问视图的方法,包括在此片段中创建一个新变量并在 onCreateView() 中将视图提交给它。
另外,如果我在 onCreatedView() 中检查它,它还不是空对象。
我也试过在 onCreateView() 中创建 TextView,但是在 onCreatedView() 之后无法调用 setText()
在网上查了几天,如果有更高级的开发人员能得到解决方案,那就太好了!
问题是 Fragment
事务是异步的,因此通常您不应从 activity 访问 Fragment
。您应该做的是在 getItem
方法中创建片段时通过 .setArguments()
传递所有必要的数据。稍后在 onViewCreated
中,您可以访问之前通过 getArguments
调用传入的 Bundle
:
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
DashboardTab tabDashboard = new DashboardTab();
Bundle bundle = new Bundle();
bundle.putString("USER_NAME", users.get(position));
tabDashboard.setArguments(bundle);
return tabDashboard;
case 1:
VertretungsplanTab tabVertretungsplan = new VertretungsplanTab();
return tabVertretungsplan;
default:
return null;
}
}
然后在Fragment
:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.textView2).setText(getArguments().getString("USER_NAME"));
}
检查将数据传递给 DetailsFragment
here
的示例
那样会更容易:
public class VertretungsplanTab extends Fragment {
private View rootView;
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.vertretungsplan_fragment, container, false);
tv = (TextView) rootView.findViewById(R.id.textView2);
return rootView;
}
public void setText(String textToBeSet, VertretungsplanTab tab){
tv.setText(textToBeSet);
}
好吧,从你的问题中基本上不清楚你想在哪里调用 setText()
方法。如果你从你想打电话的地方添加那个地方会更好 setText()
.
但据我了解你的情况,你必须在你的片段之外调用方法并且你必须在你的片段中创建一个对象。如果你从片段内部调用 setText()
方法,比如在 onViewCreated()
中,那么它将 100% 工作,但如果你尝试像这样调用方法:
VertretungsplanTab tab = new VertretungsplanTab();
tab.setText("any text", tab);
它肯定会 return 你 NullPointerException
因为你已经创建了一个新的片段对象而且我们知道一个对象只是你的 class 的蓝图意味着它没有任何修改后的值。
我用过很多Fragments,也遇到过很多次这样的情况。如果您有另一个 class 想要更新片段中的文本,处理程序是您的最佳选择。
BroadcastReceivers
对于这种情况也是一个不错的选择,您也可以为此使用接口或抽象 classes。尝试学习这些概念,因为当您想将数据从一个 class 传递到另一个时,这些是您拥有的最好的东西。
使用接口的示例是 。这只是一个例子,它与你的问题不相似,但通过这个你将了解使用接口。只是通过它..我希望它会有所帮助。
您还可以了解如何使用处理程序将数据从 activity 传递到片段或片段到 activity。
如果我理解错了你的问题,请更详细地解释,因为这是我从你的问题中所能理解的最多:)
我正在构建一个基于 android studio 的 tabbedActivity 预设的应用程序,因此创建了片段:
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 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.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
及以后:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
DashboardTab tabDashboard = new DashboardTab();
return tabDashboard;
case 1:
VertretungsplanTab tabVertretungsplan = new VertretungsplanTab();
return tabVertretungsplan;
default:
return null;
}
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Dashboard";
case 1:
return "Vertretungsplan";
}
return null;
}
}
一切正常,但实际上这是一种非常不常见的创建选项卡的方式,所以我的问题可能是由于对 MainActivity.java
的误解造成的public class VertretungsplanTab extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.vertretungsplan_fragment, container, false);
return rootView;
}
public void setText(String textToBeSet, VertretungsplanTab tab){
TextView tv = (TextView) getView().findViewById(R.id.textView2);
}
现在问题是由视图引起的,因为它是我方法中的空对象。
Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
我尝试了几种访问视图的方法,包括在此片段中创建一个新变量并在 onCreateView() 中将视图提交给它。 另外,如果我在 onCreatedView() 中检查它,它还不是空对象。
我也试过在 onCreateView() 中创建 TextView,但是在 onCreatedView() 之后无法调用 setText()
在网上查了几天,如果有更高级的开发人员能得到解决方案,那就太好了!
问题是 Fragment
事务是异步的,因此通常您不应从 activity 访问 Fragment
。您应该做的是在 getItem
方法中创建片段时通过 .setArguments()
传递所有必要的数据。稍后在 onViewCreated
中,您可以访问之前通过 getArguments
调用传入的 Bundle
:
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
DashboardTab tabDashboard = new DashboardTab();
Bundle bundle = new Bundle();
bundle.putString("USER_NAME", users.get(position));
tabDashboard.setArguments(bundle);
return tabDashboard;
case 1:
VertretungsplanTab tabVertretungsplan = new VertretungsplanTab();
return tabVertretungsplan;
default:
return null;
}
}
然后在Fragment
:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.textView2).setText(getArguments().getString("USER_NAME"));
}
检查将数据传递给 DetailsFragment
here
那样会更容易:
public class VertretungsplanTab extends Fragment {
private View rootView;
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.vertretungsplan_fragment, container, false);
tv = (TextView) rootView.findViewById(R.id.textView2);
return rootView;
}
public void setText(String textToBeSet, VertretungsplanTab tab){
tv.setText(textToBeSet);
}
好吧,从你的问题中基本上不清楚你想在哪里调用 setText()
方法。如果你从你想打电话的地方添加那个地方会更好 setText()
.
但据我了解你的情况,你必须在你的片段之外调用方法并且你必须在你的片段中创建一个对象。如果你从片段内部调用 setText()
方法,比如在 onViewCreated()
中,那么它将 100% 工作,但如果你尝试像这样调用方法:
VertretungsplanTab tab = new VertretungsplanTab();
tab.setText("any text", tab);
它肯定会 return 你 NullPointerException
因为你已经创建了一个新的片段对象而且我们知道一个对象只是你的 class 的蓝图意味着它没有任何修改后的值。
我用过很多Fragments,也遇到过很多次这样的情况。如果您有另一个 class 想要更新片段中的文本,处理程序是您的最佳选择。
BroadcastReceivers
对于这种情况也是一个不错的选择,您也可以为此使用接口或抽象 classes。尝试学习这些概念,因为当您想将数据从一个 class 传递到另一个时,这些是您拥有的最好的东西。
使用接口的示例是
您还可以了解如何使用处理程序将数据从 activity 传递到片段或片段到 activity。
如果我理解错了你的问题,请更详细地解释,因为这是我从你的问题中所能理解的最多:)