En mi Main FragmentActivity
, configuro mi ActionBar
título personalizado así:
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);
Esto funciona perfecto. Sin embargo, una vez que abro otro Fragments
, quiero que cambie el título. ¿No estoy seguro de cómo acceder a Main Activity
para hacer esto? En el pasado, hice esto:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
¿Alguien puede asesorar sobre el método adecuado?
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
fuente
fuente
Respuestas:
=== Actualización 30 de octubre de 2019 ===
Dado que tenemos nuevos componentes como ViewModel y LiveData , podemos tener una forma diferente / más fácil de actualizar el título de la actividad desde Fragment utilizando ViewModel y Live Data
Actividad
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") } }
Y MainModelView:
class MainViewModel : ViewModel() { private val _title = MutableLiveData<String>() val title: LiveData<String> get() = _title fun updateActionBarTitle(title: String) = _title.postValue(title) }
Y luego puede actualizar el título de la actividad desde Fragmento usando
viewModel.updateActionBarTitle("Custom Title From Fragment")
=== Actualización 10 de abril de 2015 ===
Debes usar el oyente para actualizar el título de tu barra de acciones.
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); } }
Y actividad:
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); } }
Lea más aquí: https://developer.android.com/training/basics/fragments/communicating.html
fuente
onAttach(Context)
método si la actividad del host pasada implementa la interfaz requerida (recupere la actividad del host mediantecontext.getActivity()
).Lo que estás haciendo es correcto.
Fragments
no tiene acceso a lasActionBar
API, por lo que debe llamargetActivity
. A menos queFragment
sea una clase interna estática, en cuyo caso debe crear unWeakReference
al padre y llamar a Activity.getActionBar
desde allí.Para establecer el título de su
ActionBar
, mientras usa un diseño personalizado, en suFragment
deberá llamargetActivity().setTitle(YOUR_TITLE)
.La razón por la que llama
setTitle
es porque está llamandogetTitle
como el título de suActionBar
.getTitle
devuelve el título para esoActivity
.Si no desea recibir una llamada
getTitle
, deberá crear un método público que establezca el texto de suTextView
en elActivity
que aloja elFragment
.En tu actividad :
public void setActionBarTitle(String title){ YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title); }
En tu Fragmento :
Documentos:
Activity.getTitle
Activity.setTitle
Además, no es necesario que ingrese
this.whatever
el código que proporcionó, solo un consejo.fuente
XML
y también eliminé "esto". Sin cambios ... Y no, no es unastatic
clase interna.ActionBar
from aFragment
. Además, no estaba ofreciendo la eliminaciónthis.whatever
como una solución a nada, eso era solo una sugerencia de formato de código.menu_act
) hice global "mTitle", y, en un fragmento, primero le asigno un título a "mTitle" (( (menu_act) getActivity() ).mTitle = "new_title"
), e inmediatamente lo hago( (menu_act) getActivity() ).restoreActionBar();
. Dentro de "restoreActionBar ()" tengo "actionBar.setTitle (mTitle);".Los ejemplos de Google tienden a usar esto dentro de los fragmentos.
private ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); }
El fragmento pertenecerá a una ActionBarActivity y ahí es donde está la referencia a la barra de acciones. Esto es más limpio porque el fragmento no necesita saber exactamente qué actividad es, solo necesita pertenecer a una actividad que implemente ActionBarActivity. Esto hace que el fragmento sea más flexible y se puede agregar a múltiples actividades como deben.
Ahora, todo lo que necesita hacer en el fragmento es.
getActionBar().setTitle("Your Title");
Esto funciona bien si tiene un fragmento base del que heredan sus fragmentos en lugar de la clase de fragmento normal.
public abstract class BaseFragment extends Fragment { public ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); } }
Luego en tu fragmento.
public class YourFragment extends BaseFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActionBar().setTitle("Your Title"); } }
fuente
Establecer
Activity
el título de unFragment
desordena los niveles de responsabilidad.Fragment
está contenido dentro deActivity
, por lo que este es elActivity
, que debe establecer su propio título de acuerdo con el tipo de,Fragment
por ejemplo.Suponga que tiene una interfaz:
interface TopLevelFragment { String getTitle(); }
Los
Fragment
s que pueden influir en elActivity
título de entonces implementan esta interfaz. Mientras se encuentra en la actividad de alojamiento, escribe:@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()); }
De esta manera,
Activity
siempre se tiene el control de qué título usar, incluso siTopLevelFragment
se combinan varios , lo cual es bastante posible en una tableta.fuente
No creo que la respuesta aceptada sea la respuesta perfecta. Dado que todas las actividades que utilizan
se extienden usando
, los fragmentos llamados desde él pueden usar el código mencionado a continuación para cambiar el título.
((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");
fuente
En el Fragmento que podemos usar así, funciona bien para mí.
getActivity().getActionBar().setTitle("YOUR TITLE");
fuente
En caso de que tenga problemas con el código, intente poner
getSupportActionBar().setTitle(title)
dentroonResume()
de su fragmento en lugar deonCreateView(...)
ieEn MainActivity.java :
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); }
En fragmento:
@Override public void onResume(){ super.onResume(); ((MainActivity) getActivity()).setActionBarTitle("Your Title"); }
fuente
((MainActivity) getActivity()).setTitle("title")
suficiente. En Kotlin, mi fragmento lo haceactivity!!.title = "title
.Utilice lo siguiente:
getActivity().setTitle("YOUR_TITLE");
fuente
Aquí está mi solución para configurar el título de ActionBar a partir de fragmentos, cuando se usa NavigationDrawer. Esta solución utiliza una interfaz, por lo que los fragmentos no necesitan hacer referencia a la actividad principal directamente:
1) Cree una interfaz:
public interface ActionBarTitleSetter { public void setTitle(String title); }
2) En onAttach del Fragmento, transmita la actividad al tipo de Interfaz y llame al método SetActivityTitle:
@Override public void onAttach(Activity activity) { super.onAttach(activity); ((ActionBarTitleSetter) activity).setTitle(getString(R.string.title_bubbles_map)); }
3) En la actividad, implemente la interfaz ActionBarTitleSetter :
@Override public void setTitle(String title) { mTitle = title; }
fuente
Mejor evento para cambiar de 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); }
fuente
Un simple ejemplo de Kotlin
Suponiendo que estas deps de Gradle coincidan o sean una versión superior en su proyecto:
kotlin_version = '1.3.41' nav_version_ktx = '2.0.0'
Adapte esto a sus clases de fragmentos:
/** * 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!" } }
fuente
Si tiene una actividad principal con muchos fragmentos, generalmente usa el navigationDrawer. Y tienes una serie de títulos para tus fragmentos, cuando presionas atrás, para que cambien, pon esto en la actividad principal que contiene los 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(); } }
Esto supone que para cada fragmento le da una etiqueta, generalmente en algún lugar cuando agrega los fragmentos a la lista de navigationDrawer, de acuerdo con la posición presionada en la lista. Entonces esa posición es lo que capturo en la etiqueta:
Ahora, navMenuTitles es algo que carga en onCreate
// load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
La matriz xml es un recurso de cadena de tipo matriz en strings.xml
<!-- Nav Drawer Menu Items --> <string-array name="nav_drawer_items"> <item>Title one</item> <item>Title Two</item> </string-array>
fuente
Guarde su respuesta en el objeto String [] y configúrelo en OnTabChange () en MainActivity como se muestra a continuaciónwww
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)); }
fuente
La desventaja de tu enfoque de casting como tal
es que su fragmento ya no es reutilizable fuera de MainActivityFragment. Si no planea usarlo fuera de esa actividad, entonces no hay problema. Un mejor enfoque sería establecer condicionalmente el título en función de la actividad. Entonces, dentro de su fragmento, escribiría:
if (getActivity() instanceof ActionBarActivity) { ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title"); }
fuente
Si está utilizando la plantilla estable de Android Studio 1.4 proporcionada por Google, entonces debe escribir el siguiente código en el
onNavigationItemSelected
método en el que su fragmento relacionado llama a la condición.setTitle("YOUR FRAGMENT TITLE");
fuente
<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");
fuente
Solo para agregar a la respuesta seleccionada, es posible que también desee agregar un segundo método a su actividad principal. Entonces terminaría con los siguientes métodos en su actividad principal:
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); } public void setActionBarTitle(int resourceId) { setActionBarTitle(getResources().getString(resourceId); }
Esto le permitirá establecer el título tanto de una variable de cadena como de un ID de recurso, como el
R.id.this_is_a_string
de su archivo strings.xml. Esto también funcionará un poco más comogetSupportActionBar().setTitle()
funciona, ya que le permite pasar un ID de recurso.fuente
Hay muchas formas como se describió anteriormente. También puede hacer esto
onNavigationDrawerSelected()
en suDrawerActivity
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); } }
fuente
Al menos para mí, hubo una respuesta fácil (después de mucho investigar) para cambiar el título de una pestaña en tiempo de ejecución:
TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); tabLayout.getTabAt (MyTabPos) .setText ("Mi nuevo texto");
fuente
Si está usando
ViewPager
(como mi caso) puede usar:en el
onPageSelected
método de tuVIEW_PAGER.addOnPageChangeListener
fuente
En su MainActivity, bajo
onCreate:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Y en su actividad de fragmentos en
onResume
:Opcional: - si muestran una advertencia de referencia nula
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);
fuente