Настройка пользовательского заголовка панели действий из фрагмента
внутри 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);
может ли кто-нибудь посоветовать правильный метод?
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>
19 ответов:
В вашей деятельности:
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"); }
===Обновление 10 Апреля 2015 Года===
вы должны использовать listener для обновления заголовка панели действий
фрагмент:
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
то, что вы делаете, правильно.
Fragments
не имеют доступа кActionBar
API, так что вы должны позвонитьgetActivity
. Если только вашFragment
является статическим внутренним классом, в этом случае вы должны создатьWeakReference
к родительской и вызов активности.getActionBar
оттуда.чтобы установить название для вашего
ActionBar
, при использовании пользовательского макета, в вашемFragment
нужно позвонитьgetActivity().setTitle(YOUR_TITLE)
.причина позвонить
setTitle
- это потому, что ты называешьgetTitle
как название вашActionBar
.getTitle
возвращает название для этогоActivity
.если вы не хотите, чтобы получить вызов
getTitle
, то вам нужно будет создать открытый метод, который устанавливает текст вашегоTextView
наActivity
что хозяеваFragment
.в работе:
public void setActionBarTitle(String title){ YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title); }
в вашей Фрагмент:
((MainFragmentActivity) getActivity()).setActionBarTitle(YOUR_TITLE);
документы:
кроме того, вам не нужно звонить
this.whatever
в коде, который вы предоставили, просто подсказка.
примеры Google, как правило, используют это в фрагментах.
private ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); }
фрагмент будет принадлежать ActionBarActivity, и именно там находится ссылка на actionbar. Это чище, потому что фрагмент не должен точно знать, что это за действие, он должен принадлежать только к действию, которое реализует 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"); } }
задание
Activity
' s title from aFragment
портит уровень ответственности.Fragment
содержится вActivity
, этоActivity
, который должен установить свой собственный заголовок в соответствии с типомFragment
например.Предположим, у вас есть интерфейс:
interface TopLevelFragment { String getTitle(); }
The
Fragment
s, которые могут влиять наActivity
’s название затем реализовать этот интерфейс. В то время как в активности хостинга вы пишете:@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
is всегда контролируйте, какое название использовать, даже если несколькоTopLevelFragment
s комбинируются, что вполне возможно на планшете.
в фрагменте, который мы можем использовать, как это, он отлично работает для меня.
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"); }
Я не думаю, что принятый ответ является идеальным ответом для него. Так как все действия, которые используют
панели инструментов
продлены с помощью
AppCompatActivity
, фрагменты, вызванные из него, могут использовать приведенный ниже код для изменения заголовка.
((AppCompatActivity) context).getSupportActionBar().setTitle("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();
теперь navmenutles-это то, что вы загружаете на onCreate
// load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
массив xml является строковым ресурсом типа массива в строках.xml
<!-- Nav Drawer Menu Items --> <string-array name="nav_drawer_items"> <item>Title one</item> <item>Title Two</item> </string-array>
сохраните ответ ur в String [] object и установите его OnTabChange () в MainActivity как Belowwww
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)); }
вот мое решение для установки заголовка ActionBar из фрагментов, при использовании NavigationDrawer. Это решение использует интерфейс, поэтому фрагменты не должны ссылаться на родительскую активность напрямую:
1) создать интерфейс:
public interface ActionBarTitleSetter { public void setTitle(String title); }
2) в фрагменте onAttach, приведите действие к типу интерфейса и вызовите метод 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 studio 1.4 стабильный шаблон, предоставленный google, чем просто вы должны были написать следующий код в
onNavigationItemSelected
methode в котором ваш связанный фрагмент вызывает условие if.setTitle("YOUR FRAGMENT TITLE");
Я получаю очень простое решение для установки заголовка 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);
для использования его из любого места, вы можете определить метод в activity
public void setActionBarTitle(String title) { toolbarTitle.setText(title); }
назвать это метод в деятельности, просто вызовите его.
setActionBarTitle("Your Title")
чтобы вызвать этот метод из фрагмента действия, просто вызовите его.
((MyActivity)getActivity()).setActionBarTitle("Your Title");
просто чтобы добавить к выбранному ответу, вы также можете добавить второй метод к своей основной деятельности. Таким образом, вы получите следующие методы в своей основной деятельности:
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); } public void setActionBarTitle(int resourceId) { setActionBarTitle(getResources().getString(resourceId); }
Это позволит вам установить заголовок как из строковой переменной, так и из идентификатора ресурса, такого как
R.id.this_is_a_string
от ваших строк.XML-файл. Это также будет работать немного больше, какgetSupportActionBar().setTitle()
работает, так как он позволяет передавать идентификатор ресурса.
есть много способов, как описано выше. Вы также можете сделать это в
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); } }
по крайней мере, для меня был простой ответ (после долгого копания) на изменение названия вкладки во время выполнения:
TabLayout tabLayout = (TabLayout) findViewById(R. id. tabs); tabLayout.getTabAt(MyTabPos).setText ("мой новый текст");
если вы используете
ViewPager
(как и в моем случае) вы можете использовать:getSupportActionBar().setTitle(YOURE_TAB_BAR.getTabAt(position).getText());
на
onPageSelected
методVIEW_PAGER.addOnPageChangeListener
Лучшее событие для изменения названия
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); }