问题:
当我尝试通过父 Activity 从另一个片段中引用一个片段的布局时。我试图访问的布局始终为空。
我相信这与通过 Activity 的 newInstance() 方法创建时未调用 onCreate() 和 onCreateView() 有关。这是我有点陌生的 Android 领域,我不能 100% 确定 Activity 和 Fragment 生命周期如何交互。背景的简要概述和问题底部包含的所有代码。
这很可能是一个我目前看不到的简单修复。为了完整起见,包括了细节。
背景:
问题是,我有两个Fragments
由一个Activity
班级托管。该类Activity
由一个标准基Activity
类组成,我将其用于整个应用程序的许多活动。这保持对 ActionBar Fragments 布局的引用(用于更改标题、图像等)并包含用于获取新 ActionBar 实例等的方法。(此处的关键方法setActionBarTitle(title)
- 稍后提及)包含在下面的代码[1]
Activity
包含两个 Fragment的继承类的第二部分是特定于任务的Activity
,在本例中是帮助Activity
。
这是Activity
加载操作栏片段(通过newInstance(title)
基类中的方法)和相应的片段,在本例中为帮助片段。[2]
哪里出错了:
在该onAttach()
方法中,我得到了对父级Activity
-的引用Activity_Help
。
问题出onCreateView()
在我的帮助Fragment
[3]中。目标是访问 Activity_Help 的 setActionBarTitle 方法。
由于 Activity_Help 扩展了 Activity 基类 (General_Activity),因此setActionBarTitle()
方法和存储的 actionBarLayout 都可以访问。似乎它应该可以访问更改操作栏片段文本所需的所有内容?
然而,事情就是这样。。
[Fragment_Help]
parentActivity.setActionBarTitle("New title");
导致..[General_Activity]
fragmentActionBar.setTitle(newTitle);
导致..[Fragment_Example1_ActionBar]
TextView tvTitle = (TextView) actionBarLayout.findViewById(R.id.tvCustomActionBarTitle);
错误行 - actionBarLayout 为空
操作栏片段的完整代码包含在最底部。[4]
我相信首先提到的是在 Activity_Help.fragmentActionBar 中没有保持它的布局。当第二次访问以更改 时TextView
,布局为空,因此为 NPE。
任何建议将不胜感激!
超类活动代码 [1]
public class General_Activity extends Activity
{
Fragment_Example1_ActionBar fragmentActionBar;
....
// Start Help Activity
case R.id.bMenuHelp:
Intent helpIntent = new Intent(this, Activity_Help.class);
helpIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(helpIntent);
break;
....
// Create a new ActionBar with given title
public void newActionBarInstance(String initialTitle)
{
fragmentActionBar = Fragment_Example1_ActionBar.newInstance(initialTitle);
}
// Create a new ActionBar with no title
public Fragment_Example1_ActionBar newActionBarInstance()
{
return Fragment_Wurth_Example1_ActionBar.newInstance("");
}
// Set ActionBar title
public void setActionBarTitle(String newTitle)
{
fragmentActionBar.setTitle(newTitle);
}
}
Activity_帮助代码 [2]
public class Activity_Help extends General_Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container_layout);
FragmentManager fragmentManager = getFragmentManager();
Fragment_Help fragmentWholeScreen = new Fragment_Help();
// SC - Create new ActionBar with given title
newActionBarInstance("Help");
if (!fragmentWholeScreen.isAdded())
{
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container_layout_example1, fragmentWholeScreen);
fragmentTransaction.add(R.id.fragment_action_bar, fragmentActionBar);
fragmentTransaction.commit();
}
}
};
Fragment_帮助代码 [3]
public class Fragment_Help extends Fragment
{
Activity_Help parentActivity;
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
parentActivity = (Activity_Help) activity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View helpLayout = inflater.inflate(R.layout.fragment_help, null);
parentActivity.setActionBarTitle("New title");
return helpLayout;
}
}
Fragment_Example1_Action条形码 [4]
public class Fragment_Example1_ActionBar extends Fragment
{
OnCustomActionBarItemSelectedListener onCustomActionBarItemSelectedListener;
View actionBarLayout;
String title;
// Pass in original title
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.i("ACTiON_BAR", "++ ON CREATE ++ " + System.currentTimeMillis());
super.onCreate(savedInstanceState);
Bundle receivedArguments = getArguments();
title = receivedArguments.getString(App.ACTION_BAR_TITLE_KEY);
actionBarLayout = getActivity().getLayoutInflater().inflate(R.layout.action_bar_layout, null);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.i("ACTiON_BAR", "+ ON CREATE VIEW + " + System.currentTimeMillis());
if (title != null)
{
setTitle(title);
}
// Get reference to ActionBar buttons and set Listeners
final ImageButton bActionBarLogo = (ImageButton) actionBarLayout.findViewById(R.id.bCustomActionBarHome);
final ImageButton bActionBarMenu = (ImageButton) actionBarLayout.findViewById(R.id.bCustomActionBarMenu);
final ImageButton bActionBarVehicleCheckIn = (ImageButton) actionBarLayout.findViewById(R.id.bCustomActionBarVehicleCheckIn);
bActionBarLogo.setOnClickListener(actionBarButtonListener);
bActionBarMenu.setOnClickListener(actionBarButtonListener);
bActionBarVehicleCheckIn.setOnClickListener(actionBarButtonListener);
return actionBarLayout;
}
// Intermediate menu button listener calling parent Activity implementation
OnClickListener actionBarButtonListener = new OnClickListener()
{
public void onClick(View actionBarItem)
{
onCustomActionBarItemSelectedListener.onCustomActionBarItemSelected(actionBarItem);
}
};
// Set ActionBar title
public void setTitle(String newTitle)
{
// Get refence to the title TextView in the custom layout
TextView tvTitle = (TextView) actionBarLayout.findViewById(R.id.tvCustomActionBarTitle);
// Set the title
tvTitle.setText(newTitle);
}
// Set ActionBar text size
public void setTextSize(float textSize)
{
// Get refence to the title TextView in the custom layout
TextView tvTitle = (TextView) actionBarLayout.findViewById(R.id.tvCustomActionBarTitle);
// Set the title
tvTitle.setTextSize(textSize);
}
// Get reference to parent activity and it's Action Bar listener
@Override
public void onAttach(Activity activity)
{
Log.i("ACTiON_BAR", "+++ ON ATTACH +++ " + System.currentTimeMillis());
super.onAttach(activity);
try
{
// Get reference to Activity's implementation of listener
onCustomActionBarItemSelectedListener = (OnCustomActionBarItemSelectedListener) activity;
}
catch (ClassCastException e)
{
// If Activity doesn't implement listener, throw exception explaining error
throw new ClassCastException(activity.toString() + " must implement OnCustomActionBarItemSelectedListener");
}
}
// New instance - keep the creation within the class in one place
public static Fragment_Example1_ActionBar newInstance(String initialTitle)
{
// Package the title up in a bundle
Bundle titleBundle = new Bundle();
titleBundle.putString(App.ACTION_BAR_TITLE_KEY, initialTitle);
Fragment_Example1_ActionBar fragmentActionBar = new Fragment_Example1_ActionBar();
fragmentActionBar.setArguments(titleBundle);
return fragmentActionBar;
}
// New instance - keep the creation within the class in one place
public static Fragment_Example1_ActionBar newInstance()
{
// Package the title up in a bundle
Bundle titleBundle = new Bundle();
titleBundle.putString(App.ACTION_BAR_TITLE_KEY, "");
Fragment_Example1_ActionBar fragmentActionBar = new Fragment_Example1_ActionBar();
fragmentActionBar.setArguments(titleBundle);
return fragmentActionBar;
}
}
干杯!