No meu Main FragmentActivity
, eu configurei meu ActionBar
título personalizado assim:
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);
Isso funciona perfeitamente. No entanto, depois de abrir outro Fragments
, quero que o título mude. Não tenho certeza de como acessar o Main Activity
para fazer isso? No passado, eu fazia isso:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
Alguém pode aconselhar sobre o método adequado?
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
fonte
fonte
Respostas:
=== Atualização em 30 de outubro de 2019 ===
Como temos novos componentes, como ViewModel e LiveData , podemos ter uma maneira diferente / mais fácil de atualizar Activity Title de Fragment usando ViewModel e Live Data
Atividade
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") } }
E MainModelView:
class MainViewModel : ViewModel() { private val _title = MutableLiveData<String>() val title: LiveData<String> get() = _title fun updateActionBarTitle(title: String) = _title.postValue(title) }
E então você pode atualizar o título da atividade do Fragment usando
viewModel.updateActionBarTitle("Custom Title From Fragment")
=== Atualização de 10 de abril de 2015 ===
Você deve usar o listener para atualizar o título da barra de ação
Fragmento:
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); } }
E atividade:
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); } }
Leia mais aqui: https://developer.android.com/training/basics/fragments/communicating.html
fonte
onAttach(Context)
método se a atividade do host passada implementa a interface necessária (recuperar a atividade do host viacontext.getActivity()
).O que você está fazendo está correto.
Fragments
não tem acesso àsActionBar
APIs, então você precisa chamargetActivity
. A menos queFragment
seja uma classe interna estática, nesse caso você deve criar umWeakReference
para o pai e chamar Activity.getActionBar
de lá.Para definir o título do seu
ActionBar
, ao usar um layout personalizado,Fragment
você precisará chamargetActivity().setTitle(YOUR_TITLE)
.A razão de você ligar
setTitle
é porque você está ligandogetTitle
como o título de seuActionBar
.getTitle
retorna o título para issoActivity
.Se você não quiser receber uma chamada
getTitle
, precisará criar um método público que defina o texto do seuTextView
noActivity
que hospeda oFragment
.Em sua atividade :
public void setActionBarTitle(String title){ YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title); }
Em seu fragmento :
Docs:
Activity.getTitle
Activity.setTitle
Além disso, você não precisa chamar
this.whatever
o código fornecido, apenas uma dica.fonte
XML
e também removi "este". Sem alterações ... E não, não é umastatic
classe interna.ActionBar
de aFragment
. Além disso, eu não estava oferecendo a remoçãothis.whatever
como solução para nada, era apenas uma dica de formatação de código.menu_act
) fiz "mTitle" global e, em um fragmento, primeiro atribuo um título a "mTitle" (( (menu_act) getActivity() ).mTitle = "new_title"
), e imediatamente o faço( (menu_act) getActivity() ).restoreActionBar();
. Dentro de "restoreActionBar ()" eu tenho "actionBar.setTitle (mTitle);".Os exemplos do Google tendem a usar isso nos fragmentos.
private ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); }
O fragmento pertencerá a uma ActionBarActivity e é aí que está a referência à actionbar. Isso é mais limpo porque o fragmento não precisa saber exatamente qual atividade é, ele só precisa pertencer a uma atividade que implemente ActionBarActivity. Isso torna o fragmento mais flexível e pode ser adicionado a várias atividades como deveriam.
Agora, tudo que você precisa fazer no fragmento é.
getActionBar().setTitle("Your Title");
Isso funciona bem se você tiver um fragmento de base do qual seus fragmentos herdam em vez da classe de fragmento normal.
public abstract class BaseFragment extends Fragment { public ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); } }
Então, em seu fragmento.
public class YourFragment extends BaseFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActionBar().setTitle("Your Title"); } }
fonte
Definir
Activity
o título de umaFragment
bagunça os níveis de responsabilidade.Fragment
está contido em umActivity
, então este é oActivity
, que deve definir seu próprio título de acordo com o tipo deFragment
por exemplo.Suponha que você tenha uma interface:
interface TopLevelFragment { String getTitle(); }
Os
Fragment
s que podem influenciar oActivity
título de então implementam essa interface. Durante a atividade de hospedagem, você escreve:@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()); }
Desta forma,
Activity
está sempre no controle de qual título usar, mesmo se váriosTopLevelFragment
s forem combinados, o que é perfeitamente possível em um tablet.fonte
Não acho que a resposta aceita seja uma resposta perfeita para isso. Uma vez que todas as atividades que usam
são estendidos usando
, os fragmentos chamados a partir dele podem usar o código mencionado abaixo para alterar o título.
((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");
fonte
No Fragment podemos usar assim, está funcionando bem para mim.
getActivity().getActionBar().setTitle("YOUR TITLE");
fonte
Apenas no caso, se você está tendo problemas com o código, tente colocar
getSupportActionBar().setTitle(title)
dentroonResume()
do seu fragmento em vez deonCreateView(...)
ieEm MainActivity.java :
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); }
Em Fragmento:
@Override public void onResume(){ super.onResume(); ((MainActivity) getActivity()).setActionBarTitle("Your Title"); }
fonte
((MainActivity) getActivity()).setTitle("title")
bastou. Em Kotlin, meu fragmento simactivity!!.title = "title
.Use o seguinte:
getActivity().setTitle("YOUR_TITLE");
fonte
Aqui está minha solução para definir o título da ActionBar a partir de fragmentos, ao usar o NavigationDrawer. Esta solução usa uma interface para que os fragmentos não precisem fazer referência à atividade pai diretamente:
1) Crie uma interface:
public interface ActionBarTitleSetter { public void setTitle(String title); }
2) No onAttach do Fragment , lance a atividade para o tipo de interface e chame o método SetActivityTitle:
@Override public void onAttach(Activity activity) { super.onAttach(activity); ((ActionBarTitleSetter) activity).setTitle(getString(R.string.title_bubbles_map)); }
3) Na atividade, implemente a interface ActionBarTitleSetter :
@Override public void setTitle(String title) { mTitle = title; }
fonte
Melhor evento para mudar o título
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); }
fonte
Um exemplo simples de Kotlin
Supondo que essas dependências gradle correspondam ou sejam uma versão superior em seu projeto:
kotlin_version = '1.3.41' nav_version_ktx = '2.0.0'
Adapte isso às suas classes de fragmento:
/** * 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!" } }
fonte
Se você tem uma atividade principal com muitos fragmentos inseridos, geralmente usando o navigationDrawer. E você tem uma série de títulos para seus fragmentos, quando você pressiona para trás, para que eles mudem, coloque isso na atividade principal que contém os fragmentos
@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(); } }
Isso pressupõe que para cada fragmento você dê a ele uma tag, geralmente em algum lugar quando você adiciona os fragmentos à lista do navigationDrawer, de acordo com a posição pressionada na lista. Portanto, essa posição é o que capturo na tag:
Agora, o navMenuTitles é algo que você carrega no onCreate
// load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
O array xml é um recurso de string do tipo array em strings.xml
<!-- Nav Drawer Menu Items --> <string-array name="nav_drawer_items"> <item>Title one</item> <item>Title Two</item> </string-array>
fonte
Salve sua resposta no objeto String [] e defina-o OnTabChange () em MainActivity como 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)); }
fonte
A desvantagem de sua abordagem de elenco assim
é que seu fragmento não pode mais ser reutilizado fora de MainActivityFragment. Se você não planeja usá-lo fora dessa atividade, não há problema. Uma abordagem melhor seria definir condicionalmente o título, dependendo da atividade. Portanto, dentro do seu fragmento, você escreveria:
if (getActivity() instanceof ActionBarActivity) { ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title"); }
fonte
Se você estiver usando o modelo estável do Android Studio 1.4 fornecido pelo Google, do que simples, você terá que escrever o seguinte código no
onNavigationItemSelected
método em que seu fragmento relacionado chama se condição.setTitle("YOUR FRAGMENT TITLE");
fonte
<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");
fonte
Apenas para adicionar na resposta selecionada, você também pode querer adicionar um segundo método à sua atividade principal. Então, você acabaria com os seguintes métodos em sua atividade principal:
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); } public void setActionBarTitle(int resourceId) { setActionBarTitle(getResources().getString(resourceId); }
Isso permitirá que você defina o título de uma variável String, bem como um ID de recurso, como
R.id.this_is_a_string
do arquivo strings.xml. Isso também funcionará um pouco mais comogetSupportActionBar().setTitle()
funciona, pois permite que você passe um ID de recurso.fonte
Existem muitas maneiras, conforme descrito acima. Você também pode fazer isso
onNavigationDrawerSelected()
em seuDrawerActivity
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); } }
fonte
Pelo menos para mim, houve uma resposta fácil (depois de muito pesquisar) para alterar o título de uma guia em tempo de execução:
TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); tabLayout.getTabAt (MyTabPos) .setText ("Meu Novo Texto");
fonte
Se você estiver usando
ViewPager
(como meu caso), você pode usar:no
onPageSelected
método do seuVIEW_PAGER.addOnPageChangeListener
fonte
Em sua MainActivity, em
onCreate:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
E em sua atividade de fragmento em
onResume
:Opcional: - se mostrarem aviso de referência nula
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);
fonte