从片段设置自定义ActionBar标题
在我的主要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
,我希望标题改变。 我不知道如何访问主要Activity
来做到这一点? 在过去,我这样做了:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle( catTitle);
有人可以build议正确的方法吗?
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>
你在做什么是正确的。 Fragments
无法访问ActionBar
API,因此您必须调用getActivity
。 除非你的Fragment
是一个静态的内部类,在这种情况下,你应该为父对象创build一个WeakReference
并且调用Activity。 从那里getActionBar
。
要设置你的ActionBar
的标题,而使用自定义布局,在你的Fragment
你需要调用getActivity().setTitle(YOUR_TITLE)
。
你调用setTitle
的原因是因为你调用getTitle
作为你的ActionBar
的标题。 getTitle
返回该Activity
的标题。
如果您不想调用getTitle
,那么您需要创build一个公共方法,在托pipeFragment
的Activity
中设置TextView
的文本。
在您的活动中 :
public void setActionBarTitle(String title){ YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title); }
在你的片段 :
((MainFragmentActivity) getActivity()).setActionBarTitle(YOUR_TITLE);
文档:
Activity.getTitle
Activity.setTitle
而且,你不需要调用this.whatever
你提供的代码是什么,只是一个提示。
在你的活动中:
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
谷歌的例子倾向于在片段中使用这个。
private ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); }
该片段将属于一个ActionBarActivity,这是对操作栏的引用。 这是更清洁的,因为片段不需要确切地知道它是什么活动,它只需要属于实现ActionBarActivity的活动。 这使得片段更加灵活,可以添加到多个活动中。
现在,你需要做的是片段。
getActionBar().setTitle("Your Title");
如果你有一个你的分片inheritance的基片段,而不是普通的片段类,这个效果很好。
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"); } }
从Fragment
设置Activity
的标题会扰乱责任级别。 Fragment
包含在一个Activity
,所以这就是Activity
,它应该根据Fragment
的types来设置自己的标题。
假设你有一个接口:
interface TopLevelFragment { String getTitle(); }
可以影响Activity
标题的Fragment
然后实现这个接口。 在主持活动中你写道:
@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()); }
以这种方式,即使几个TopLevelFragment
被组合在一起, Activity
总是在控制使用什么标题,这在平板电脑上是完全可能的。
在片段中我们可以这样使用,对我来说工作得很好。
getActivity().getActionBar().setTitle("YOUR TITLE");
以防万一,如果你有问题的代码,尝试把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"); }
如果你有一个主要的活动有很多片段,通常使用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();
现在,navMenuTitles是你在onCreate上加载的东西
// load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
数组xml是strings.xml上的数组typesstring资源
<!-- Nav Drawer Menu Items --> <string-array name="nav_drawer_items"> <item>Title one</item> <item>Title Two</item> </string-array>
保存在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)); }
使用以下内容:
getActivity().setTitle("YOUR_TITLE");
这里是我使用NavigationDrawer设置ActionBar标题的解决scheme。 这个解决scheme使用一个接口,所以这些片段不需要直接引用父Activity:
1)创build一个接口:
public interface ActionBarTitleSetter { public void setTitle(String title); }
2)在Fragment的onAttach中 ,将活动转换为Interfacetypes并调用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; }
你的铸造方法的缺点就像这样
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle( catTitle);
是你的片段不再可以在MainActivityFragment之外重用。 如果你不打算在这个活动之外使用它,那么没有问题。 更好的方法是根据活动条件设置标题。 所以在你的片段中,你会写:
if (getActivity() instanceof ActionBarActivity) { ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title"); }
如果你正在使用android提供的稳定模板比谷歌提供的简单,你必须在onNavigationItemSelected
方法中写下面的代码,其中你的相关片段调用if条件。
setTitle("YOUR FRAGMENT TITLE");
只要添加到选定的答案,您可能还想要添加第二个方法到您的主要活动。 所以你最终会在你的主要活动中使用以下方法:
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); } public void setActionBarTitle(int resourceId) { setActionBarTitle(getResources().getString(resourceId); }
这将允许您从R.id.this_is_a_string
文件中设置来自Stringvariables以及诸如R.id.this_is_a_string
类的资源ID的标题。 这也会像getSupportActionBar().setTitle()
工作,因为它允许你传入一个资源ID。
如上所述,有许多方法。 你也可以在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); } }
至less对我来说,在运行时更改标签标题有一个简单的答案(经过深思熟虑后):
TabLayout tabLayout =(TabLayout)findViewById(R.id.tabs); tabLayout.getTabAt(MyTabPos).setText(“My New Text”);
如果你使用ViewPager
(就像我的情况),你可以使用:
getSupportActionBar().setTitle(YOURE_TAB_BAR.getTabAt(position).getText());
在onPageSelected
方法中
最好的事件更改标题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); }