В своем главном 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>
java
android
android-fragments
android-actionbar
android-fragmentactivity
TheLettuceMaster
источник
источник
Ответы:
=== Обновление 30 октября 2019 г. ===
Поскольку у нас есть новые компоненты, такие как ViewModel и LiveData , у нас может быть другой / более простой способ обновления заголовка действия из фрагмента с помощью ViewModel и Live Data.
Деятельность
class MainActivity : AppCompatActivity() { private lateinit var viewModel: MainViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) if (savedInstanceState == null) { supportFragmentManager.beginTransaction() .replace(R.id.container, MainFragment.newInstance()) .commitNow() } viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) viewModel.title.observe(this, Observer { supportActionBar?.title = it }) } }
MainFragment
class MainFragment : Fragment() { companion object { fun newInstance() = MainFragment() } private lateinit var viewModel: MainViewModel override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { return inflater.inflate(R.layout.main_fragment, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) activity?.run { viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) } ?: throw Throwable("invalid activity") viewModel.updateActionBarTitle("Custom Title From Fragment") } }
И MainModelView:
class MainViewModel : ViewModel() { private val _title = MutableLiveData<String>() val title: LiveData<String> get() = _title fun updateActionBarTitle(title: String) = _title.postValue(title) }
И затем вы можете обновить заголовок действия из фрагмента, используя
viewModel.updateActionBarTitle("Custom Title From Fragment")
=== Обновление от 10 апреля 2015 г. ===
Вы должны использовать слушателя для обновления заголовка панели действий
Фрагмент:
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
источник
onAttach(Context)
метода, реализует ли переданная активность хоста требуемый интерфейс (получение активности хоста черезcontext.getActivity()
).То, что вы делаете, правильно.
Fragments
у вас нет доступа кActionBar
API, поэтому вам нужно позвонитьgetActivity
. Если вашFragment
внутренний класс не является статическим, в этом случае вы должны создатьWeakReference
родительский класс и вызвать Activity.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); }
В вашем фрагменте :
Документы:
Activity.getTitle
Activity.setTitle
Кроме того, вам не нужно вызывать
this.whatever
код, который вы предоставили, просто подсказку.источник
XML
и также удалил «это». Никаких изменений ... И нет, это неstatic
внутренний класс.ActionBar
from aFragment
. Кроме того, я не предлагал удалениеthis.whatever
как решение чего-либо, это был всего лишь совет по форматированию кода.menu_act
действии панели навигации ( ) я сделал глобальный "mTitle", и в фрагмент, сначала я присваиваю заголовок «mTitle» (( (menu_act) getActivity() ).mTitle = "new_title"
), и сразу же делаю это( (menu_act) getActivity() ).restoreActionBar();
. Внутри «restoreActionBar ()» у меня есть «actionBar.setTitle (mTitle);».В примерах 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"); } }
источник
Постановка
Activity
титула изFragment
разряда перепутанных уровней ответственности.Fragment
содержится внутриActivity
, поэтому это тотActivity
, который должен устанавливать свой собственный заголовок в соответствии с типомFragment
например.Предположим, у вас есть интерфейс:
interface TopLevelFragment { String getTitle(); }
Значения
Fragment
s, которые могут влиять на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
объединены, что вполне возможно на планшете.источник
Я не думаю, что принятый ответ - идеальный ответ. Поскольку все действия, которые используют
расширены с использованием
, вызываемые из него фрагменты могут использовать указанный ниже код для изменения заголовка.
((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");
источник
Во фрагменте мы можем использовать вот так: у меня он работает нормально.
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"); }
источник
((MainActivity) getActivity()).setTitle("title")
хватило. В Котлине есть мой фрагментactivity!!.title = "title
.Используйте следующее:
getActivity().setTitle("YOUR_TITLE");
источник
Вот мое решение для установки заголовка ActionBar из фрагментов при использовании NavigationDrawer. В этом решении используется интерфейс, поэтому фрагментам не нужно напрямую ссылаться на родительский Activity:
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; }
источник
Лучшее мероприятие для смены названия
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); }
источник
Простой пример Котлина
Предполагая, что эти gradle deps совпадают или имеют более высокую версию в вашем проекте:
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!" } }
источник
Если у вас есть основное действие с большим количеством вставленных фрагментов, обычно с помощью 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, в соответствии с позицией, нажатой в списке. Итак, эта позиция - это то, что я фиксирую на теге:
Теперь navMenuTitles - это то, что вы загружаете в onCreate
// load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
Массив xml - это строковый ресурс типа массива в strings.xml.
<!-- Nav Drawer Menu Items --> <string-array name="nav_drawer_items"> <item>Title one</item> <item>Title Two</item> </string-array>
источник
Сохраните ur Answer в объекте String [] и установите его OnTabChange () в MainActivity, как показано ниже.
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)); }
источник
Обратная сторона вашего подхода к кастингу
заключается в том, что ваш фрагмент больше не может использоваться повторно за пределами MainActivityFragment. Если вы не планируете использовать его за пределами этой деятельности, тогда нет проблем. Лучше было бы условно задать заголовок в зависимости от активности. Итак, внутри вашего фрагмента вы должны написать:
if (getActivity() instanceof ActionBarActivity) { ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title"); }
источник
Если вы используете стабильный шаблон android studio 1.4, предоставленный google, вам нужно было написать следующий код в
onNavigationItemSelected
методе, в котором связанный фрагмент вызывает условие if.setTitle("YOUR FRAGMENT TITLE");
источник
<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>
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
из вашего файла strings.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
(как в моем случае), вы можете использовать:в
onPageSelected
методе вашегоVIEW_PAGER.addOnPageChangeListener
источник
В вашем MainActivity под
onCreate:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
И в вашей активности фрагмента под
onResume
:Необязательно: - если они показывают предупреждение о нулевой ссылке
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);
источник