在我的主FragmentActivity
中,我设置了这样的自定义ActionBar
标题:
LayoutInflater inflator = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.custom_titlebar, null);
TextView tv = (TextView) v.findViewById(R.id.title);
Typeface tf = Typeface.createFromAsset(this.getAssets(),
"fonts/capsuula.ttf");
tv.setTypeface(tf);
tv.setText(this.getTitle());
actionBar.setCustomView(v);
这很完美。但是,一旦我打开其他Fragments
,我希望标题发生变化。我不确定如何访问Main Activity
来执行此操作?在过去,我这样做了:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
有人可以就正确的方法提出建议吗?
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" >
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:ellipsize="end"
android:maxLines="1"
android:text=""
android:textColor="#fff"
android:textSize="25sp" />
</RelativeLayout>
答案 0 :(得分:146)
你所做的是正确的。 Fragments
无法访问ActionBar
API,因此您必须致电getActivity
。除非您的Fragment
是静态内部类,否则您应该为父级创建WeakReference
并从那里调用Activity。getActionBar
。
要设置ActionBar
的标题,在使用自定义布局时,在Fragment
中,您需要致电getActivity().setTitle(YOUR_TITLE)
。
您拨打setTitle
的原因是因为您将getTitle
称为ActionBar
的标题。 getTitle
会返回Activity
的标题。
如果您不想接听电话getTitle
,则需要创建一个公共方法,设置TextView
中承载Activity
的{{1}}的文字{1}}。
在您的活动中:
Fragment
在您的片段中:
public void setActionBarTitle(String title){
YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title);
}
<强>文档:强>
此外,您无需在提供的代码中致电((MainFragmentActivity) getActivity()).setActionBarTitle(YOUR_TITLE);
,只需提示。
答案 1 :(得分:71)
在您的活动中:
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
在你的片段中:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Set title bar
((MainFragmentActivity) getActivity())
.setActionBarTitle("Your title");
}
=== 2015年4月10日更新===
您应该使用监听器来更新操作栏标题
片段:
public class UpdateActionBarTitleFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public UpdateActionBarTitleFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mListener != null) {
mListener.onFragmentInteraction("Custom Title");
}
return inflater.inflate(R.layout.fragment_update_action_bar_title2, container, false);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(String title);
}
}
活动:
public class UpdateActionBarTitleActivity extends ActionBarActivity implements UpdateActionBarTitleFragment.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_action_bar_title);
}
@Override
public void onFragmentInteraction(String title) {
getSupportActionBar().setTitle(title);
}
}
在此处阅读更多内容:https://developer.android.com/training/basics/fragments/communicating.html
答案 2 :(得分:25)
Google示例倾向于在片段中使用此功能。
private ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
该片段将属于ActionBarActivity,这是对操作栏的引用。这是更清晰的,因为片段不需要确切地知道它是什么活动,它只需要属于实现ActionBarActivity的活动。这使得片段更加灵活,可以像往常一样添加到多个活动中。
现在,您需要在片段中完成所有操作。
getActionBar().setTitle("Your Title");
如果您有一个片段继承而不是正常片段类的基本片段,那么这种方法很有效。
public abstract class BaseFragment extends Fragment {
public ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
}
然后在你的片段中。
public class YourFragment extends BaseFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActionBar().setTitle("Your Title");
}
}
答案 3 :(得分:7)
从Fragment
设置Fragment
的标题会增加责任级别。 Activity
包含Activity
,因此这是Fragment
,例如,应根据interface TopLevelFragment
{
String getTitle();
}
的类型设置自己的标题。
假设您有一个界面:
Fragment
可以影响Activity
标题的@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getFragmentManager();
fm.beginTransaction().add(0, new LoginFragment(), "login").commit();
}
@Override
public void onAttachFragment(Fragment fragment)
{
super.onAttachFragment(fragment);
if (fragment instanceof TopLevelFragment)
setTitle(((TopLevelFragment) fragment).getTitle());
}
然后实现此接口。在您写的托管活动中:
Activity
以这种方式TopLevelFragment
始终控制着要使用的标题,即使合并了多个sonar.jacoco.reportMissing.force.zero=true
,这在平板电脑上也是如此。
答案 4 :(得分:5)
在Fragment中我们可以像这样使用,它对我来说很好。
getActivity().getActionBar().setTitle("YOUR TITLE");
答案 5 :(得分:4)
如果您遇到代码问题,请尝试将getSupportActionBar().setTitle(title)
放在您片段的onResume()
内,而不是onCreateView(...)
,即
在 MainActivity.java :
中public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
在片段中:
@Override
public void onResume(){
super.onResume();
((MainActivity) getActivity()).setActionBarTitle("Your Title");
}
答案 6 :(得分:2)
使用以下内容:
getActivity().setTitle("YOUR_TITLE");
答案 7 :(得分:2)
我不认为接受的答案是一个完美的答案。由于所有使用
的活动工具栏
使用
进行扩展AppCompatActivity
,从中调用的片段可以使用下面提到的代码来更改标题。
((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");
答案 8 :(得分:1)
在String []对象中保存你的答案,并在MainActivity中将其设置为OnTabChange(),如下面的
String[] object = {"Fragment1","Fragment2","Fragment3"};
public void OnTabChange(String tabId)
{
int pos =mTabHost.getCurrentTab(); //To get tab position
actionbar.setTitle(object.get(pos));
}
//Setting in View Pager
public void onPageSelected(int arg0) {
mTabHost.setCurrentTab(arg0);
actionbar.setTitle(object.get(pos));
}
答案 9 :(得分:1)
这是我使用NavigationDrawer时从片段设置ActionBar标题的解决方案。 此解决方案使用接口,因此片段不需要直接引用父活动:
1)创建一个接口:
public interface ActionBarTitleSetter {
public void setTitle(String title);
}
2)在Fragment的 onAttach 中,将活动强制转换为Interface类型并调用SetActivityTitle方法:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((ActionBarTitleSetter) activity).setTitle(getString(R.string.title_bubbles_map));
}
3)在活动中,实施 ActionBarTitleSetter 界面:
@Override
public void setTitle(String title) {
mTitle = title;
}
答案 10 :(得分:1)
你的投射方式的缺点如此
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
是您的片段不再可以在MainActivityFragment之外重复使用。如果您不打算在该活动之外使用它,那么没有问题。更好的方法是根据活动有条件地设置标题。所以在你的片段中,你会写:
if (getActivity() instanceof ActionBarActivity) {
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title");
}
答案 11 :(得分:1)
如果您有一个包含许多片段的主要活动,通常使用navigationDrawer。你有一系列的标题为你的片段,当你按回来,让他们改变,把它放在包含片段的主要行为
@Override
public void onBackPressed() {
int T=getSupportFragmentManager().getBackStackEntryCount();
if(T==1) { finish();}
if(T>1) {
int tr = Integer.parseInt(getSupportFragmentManager().getBackStackEntryAt(T-2).getName());
setTitle(navMenuTitles[tr]); super.onBackPressed();
}
}
这假设对于每个片段,您可以根据列表中按下的位置为其提供一个标记,通常是在将片段添加到navigationDrawer列表时的某个位置。所以这个位置是我在标签上捕获的位置:
fragmentManager.beginTransaction().
replace(R.id.frame_container, fragment).addToBackStack(position).commit();
现在,你在onCreate上加载了navMenuTitles
// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
array xml是strings.xml上的数组类型字符串资源
<!-- Nav Drawer Menu Items -->
<string-array name="nav_drawer_items">
<item>Title one</item>
<item>Title Two</item>
</string-array>
答案 12 :(得分:1)
如果你使用google提供的android studio 1.4稳定模板而不是简单你必须在%
方法中编写以下代码
其中你的相关片段调用if条件。
onNavigationItemSelected
答案 13 :(得分:1)
我得到了一个非常简单的解决方案,可以在任一位置设置ActionBar标题 碎片或任何活动而没有任何头痛。
只需修改定义了工具栏的xml,如下所示:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimaryDark"
app:popupTheme="@style/AppTheme.PopupOverlay" >
<TextView
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
1)如果要在片段中设置操作栏,则:
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
要在任何地方使用它,您可以在活动中定义一个方法
public void setActionBarTitle(String title) {
toolbarTitle.setText(title);
}
要在活动中调用此方法,只需对其进行调用。
setActionBarTitle("Your Title")
要从活动片段中调用此方法,只需对其进行调用。
((MyActivity)getActivity()).setActionBarTitle("Your Title");
答案 14 :(得分:0)
基于 Ashish 答案的 Java 解决方案
private void setUI(){
mainToolbar = findViewById(R.id.mainToolbar);
setSupportActionBar(mainToolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_messaging, R.id.nav_me)
.setDrawerLayout(drawer)
.build();
navController = Navigation.findNavController(this, R.id.nav_host_fragment);
navController.addOnDestinationChangedListener(navDestinationChange);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
private NavController.OnDestinationChangedListener navDestinationChange = new NavController.OnDestinationChangedListener(){
@Override
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
if(R.id.nav_home==destination.getId()){
destination.setLabel("News");
}
}
};
答案 15 :(得分:0)
一个简单的Kotlin示例
假设这些gradle部门在您的项目中匹配或更高版本:
kotlin_version = '1.3.41'
nav_version_ktx = '2.0.0'
使其适应您的片段类:
/**
* A simple [Fragment] subclass.
*
* Updates the action bar title when onResume() is called on the fragment,
* which is called every time you navigate to the fragment
*
*/
class MyFragment : Fragment() {
private lateinit var mainActivity: MainActivity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//[...]
mainActivity = this.activity as MainActivity
//[...]
}
override fun onResume() {
super.onResume()
mainActivity.supportActionBar?.title = "My Fragment!"
}
}
答案 16 :(得分:0)
在您的MainActivity中,onCreate:
下
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
在onResume
下的片段活动中:
getActivity().setTitle(R.string.app_name_science);
可选:-如果它们显示空引用警告
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);
答案 17 :(得分:0)
更改标题的最佳活动onCreateOptionsMenu
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.general, container,
setHasOptionsMenu(true); // <-Add this line
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If use specific menu
menu.clear();
inflater.inflate(R.menu.path_list_menu, menu);
// If use specific menu
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your Fragment");
super.onCreateOptionsMenu(menu, inflater);
}
答案 18 :(得分:0)
如果你正在使用ViewPager
(就像我的情况一样),你可以使用:
getSupportActionBar().setTitle(YOURE_TAB_BAR.getTabAt(position).getText());
onPageSelected
VIEW_PAGER.addOnPageChangeListener
方法
答案 19 :(得分:0)
至少对我来说,在运行时更改标签标题有一个简单的答案(经过多次挖掘):
TabLayout tabLayout =(TabLayout)findViewById(R.id.tabs); tabLayout.getTabAt(MyTabPos).setText(“我的新文本”);
答案 20 :(得分:0)
如上所述,有许多方法。您也可以在onNavigationDrawerSelected()
DrawerActivity
中执行此操作
public void setTitle(final String title){
((TextView)findViewById(R.id.toolbar_title)).setText(title);
}
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
fragment = null;
String title = null;
switch(position){
case 0:
fragment = new HomeFragment();
title = "Home";
break;
case 1:
fragment = new ProfileFragment();
title = ("Find Work");
break;
...
}
if (fragment != null){
FragmentManager fragmentManager = getFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.container,
fragment).commit();
//The key is this line
if (title != null && findViewById(R.id.toolbar_title)!= null ) setTitle(title);
}
}
答案 21 :(得分:0)
只是要添加到所选答案,您可能还想在主要活动中添加第二种方法。因此,您最终会在主要活动中使用以下方法:
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
public void setActionBarTitle(int resourceId) {
setActionBarTitle(getResources().getString(resourceId);
}
这将允许您从strings变量以及来自strings.xml文件的资源ID(例如R.id.this_is_a_string
)设置标题。这也可以更像getSupportActionBar().setTitle()
的工作方式,因为它允许您传入资源ID。