W moim menu głównym FragmentActivity
konfiguruję ActionBar
tytuł niestandardowy w następujący sposób:
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);
To działa idealnie. Jednak gdy otworzę inne Fragments
, chcę zmienić tytuł. Nie jestem pewien, jak uzyskać dostęp do strony głównej, Activity
aby to zrobić? W przeszłości robiłem to:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
Czy ktoś może doradzić właściwą metodę?
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
źródło
źródło
Odpowiedzi:
=== Aktualizacja, 30 października 2019 r. ===
Ponieważ mamy nowe komponenty, takie jak ViewModel i LiveData , możemy mieć inny / łatwiejszy sposób aktualizowania tytułu działania z fragmentu za pomocą ViewModel i Live Data
Czynność
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") } }
Oraz MainModelView:
class MainViewModel : ViewModel() { private val _title = MutableLiveData<String>() val title: LiveData<String> get() = _title fun updateActionBarTitle(title: String) = _title.postValue(title) }
Następnie możesz zaktualizować tytuł działania z Fragment za pomocą
viewModel.updateActionBarTitle("Custom Title From Fragment")
=== Aktualizacja, 10 kwietnia 2015 ===
Do aktualizacji tytułu paska akcji należy użyć listenera
Fragment:
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); } }
I aktywność:
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); } }
Przeczytaj więcej tutaj: https://developer.android.com/training/basics/fragments/communicating.html
źródło
onAttach(Context)
metody, czy przekazana aktywność hosta implementuje wymagany interfejs (pobierz aktywność hosta za pośrednictwemcontext.getActivity()
).To, co robisz, jest poprawne.
Fragments
nie masz dostępu doActionBar
interfejsów API, więc musisz zadzwonićgetActivity
. O ile twoja nieFragment
jest statyczną klasą wewnętrzną, w takim przypadku powinieneś utworzyćWeakReference
do rodzica i wywołać Activity.getActionBar
stamtąd.Aby ustawić tytuł dla swojego
ActionBar
, korzystając z niestandardowego układu,Fragment
musisz zadzwonićgetActivity().setTitle(YOUR_TITLE)
.Powodem, dla którego dzwonisz,
setTitle
jest to, że dzwoniszgetTitle
jako tytuł swojegoActionBar
.getTitle
zwraca tytuł tegoActivity
.Jeśli nie chcesz odbierać połączenia
getTitle
, musisz utworzyć publiczną metodę, która ustawia tekst twojegoTextView
wActivity
hostującymFragment
.W Twojej aktywności :
public void setActionBarTitle(String title){ YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title); }
W swoim fragmencie :
Dokumenty:
Activity.getTitle
Activity.setTitle
Nie musisz też wywoływać
this.whatever
podanego kodu, wystarczy napiwek.źródło
XML
i również usunąłem „to”. Bez zmian ... I nie, to nie jeststatic
klasa wewnętrzna.ActionBar
pliku z plikuFragment
. Ponadto nie oferowałem usuwaniathis.whatever
jako rozwiązania czegokolwiek, to była tylko wskazówka dotycząca formatowania kodu.menu_act
) stworzyłem globalny „mTitle” i fragment, najpierw przypisuję tytuł do „mTitle” (( (menu_act) getActivity() ).mTitle = "new_title"
) i od razu to robię( (menu_act) getActivity() ).restoreActionBar();
. Wewnątrz "restoreActionBar ()" mam "actionBar.setTitle (mTitle);".Przykłady Google zwykle używają tego we fragmentach.
private ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); }
Fragment będzie należał do ActionBarActivity i tam znajduje się odniesienie do paska akcji. Jest to czystsze, ponieważ fragment nie musi dokładnie wiedzieć, jakie to jest działanie, musi tylko należeć do działania, które implementuje ActionBarActivity. To sprawia, że fragment jest bardziej elastyczny i można go dodać do wielu działań, tak jak powinien.
Teraz wszystko, co musisz zrobić we fragmencie, to.
getActionBar().setTitle("Your Title");
Działa to dobrze, jeśli masz fragment podstawowy, z którego dziedziczą Twoje fragmenty zamiast normalnej klasy fragmentów.
public abstract class BaseFragment extends Fragment { public ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); } }
Następnie w swoim fragmencie.
public class YourFragment extends BaseFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActionBar().setTitle("Your Title"); } }
źródło
Ustawienie
Activity
tytułu zFragment
pomieszania poziomów odpowiedzialności.Fragment
jest zawarty w elemencieActivity
, więc to jestActivity
, który powinien ustawić własny tytuł zgodnie z typemFragment
na przykład.Załóżmy, że masz interfejs:
interface TopLevelFragment { String getTitle(); }
Te,
Fragment
które mogą mieć wpływ naActivity
tytuł, implementują ten interfejs. Prowadząc działalność hostingową piszesz:@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()); }
W ten sposób
Activity
zawszeTopLevelFragment
masz kontrolę nad tym, jakiego tytułu użyć, nawet jeśli łączy się kilka tytułów , co jest całkiem możliwe na tablecie.źródło
Nie sądzę, aby zaakceptowana odpowiedź była na to doskonałą odpowiedzią. Ponieważ wszystkie czynności, które używają
są przedłużane za pomocą
, wywołane z niej fragmenty mogą użyć poniższego kodu do zmiany tytułu.
((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");
źródło
We fragmencie, którego możemy użyć w ten sposób, działa dobrze dla mnie.
getActivity().getActionBar().setTitle("YOUR TITLE");
źródło
Na wszelki wypadek, jeśli masz problemy z kodem, spróbuj umieścić
getSupportActionBar().setTitle(title)
wewnątrzonResume()
swojego fragmentu zamiastonCreateView(...)
npW MainActivity.java :
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); }
Fragmentowo:
@Override public void onResume(){ super.onResume(); ((MainActivity) getActivity()).setActionBarTitle("Your Title"); }
źródło
((MainActivity) getActivity()).setTitle("title")
wystarczyło. W Kotlinie mój fragment takactivity!!.title = "title
.Użyj następujących:
getActivity().setTitle("YOUR_TITLE");
źródło
Oto moje rozwiązanie do ustawiania tytułu ActionBar z fragmentów podczas korzystania z NavigationDrawer. To rozwiązanie używa interfejsu, więc fragmenty nie muszą bezpośrednio odwoływać się do działania nadrzędnego:
1) Utwórz interfejs:
public interface ActionBarTitleSetter { public void setTitle(String title); }
2) W onAttach fragmentu rzutuj działanie na typ Interface i wywołaj metodę SetActivityTitle:
@Override public void onAttach(Activity activity) { super.onAttach(activity); ((ActionBarTitleSetter) activity).setTitle(getString(R.string.title_bubbles_map)); }
3) W działaniu zaimplementuj ActionBarTitleSetter interfejs :
@Override public void setTitle(String title) { mTitle = title; }
źródło
Najlepsze wydarzenie dla zmiany tytułu
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); }
źródło
Prosty przykład Kotlina
Zakładając, że te deps gradle pasują do twojego projektu lub są w wyższej wersji:
kotlin_version = '1.3.41' nav_version_ktx = '2.0.0'
Dostosuj to do swoich klas fragmentów:
/** * 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!" } }
źródło
Jeśli masz główne zadanie z wieloma fragmentami, które wstawiłeś, zwykle za pomocą navigationDrawer. I masz szereg tytułów dla swoich fragmentów, kiedy naciskasz, aby je zmienić, umieść to w głównym akcie, który zawiera fragmenty
@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(); } }
Zakłada się, że każdemu fragmentowi nadajesz mu tag, zwykle gdzieś, kiedy dodajesz fragmenty do listy navigationDrawer, zgodnie z pozycją wciśniętą na liście. Więc ta pozycja jest tym, co przechwytuję na tagu:
Teraz navMenuTitles jest czymś, co ładujesz w pliku onCreate
// load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
Tablica xml jest zasobem ciągu typu tablica w strings.xml
<!-- Nav Drawer Menu Items --> <string-array name="nav_drawer_items"> <item>Title one</item> <item>Title Two</item> </string-array>
źródło
Zapisz odpowiedź ur w obiekcie String [] i ustaw ją OnTabChange () w MainActivity jak poniżejwww
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)); }
źródło
Wadą twojego podejścia do rzucania w ten sposób
polega na tym, że Twój fragment nie nadaje się już do ponownego użycia poza MainActivityFragment. Jeśli nie planujesz używać go poza tą aktywnością, nie ma problemu. Lepszym podejściem byłoby warunkowe ustawienie tytułu w zależności od czynności. Więc wewnątrz swojego fragmentu napisałbyś:
if (getActivity() instanceof ActionBarActivity) { ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title"); }
źródło
jeśli używasz stabilnego szablonu Android Studio 1.4 dostarczonego przez Google niż prosty, musisz napisać następujący kod w
onNavigationItemSelected
metodzie, w której Twój powiązany fragment wywołuje warunek if.setTitle("YOUR FRAGMENT TITLE");
źródło
<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");
źródło
Aby dodać do wybranej odpowiedzi, możesz również dodać drugą metodę do głównego zadania. Więc skończyłbyś z następującymi metodami w swojej głównej działalności:
public void setActionBarTitle(String title) { getSupportActionBar().setTitle(title); } public void setActionBarTitle(int resourceId) { setActionBarTitle(getResources().getString(resourceId); }
Umożliwi to ustawienie tytułu zarówno na podstawie zmiennej typu String, jak i identyfikatora zasobu, na przykład
R.id.this_is_a_string
z pliku strings.xml. Będzie to również działać trochę bardziej tak, jakgetSupportActionBar().setTitle()
działa, ponieważ umożliwia przekazanie identyfikatora zasobu.źródło
Jak opisano powyżej, istnieje wiele sposobów. Możesz to również zrobić
onNavigationDrawerSelected()
w swoimDrawerActivity
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); } }
źródło
Przynajmniej dla mnie istniała łatwa odpowiedź (po wielu poszukiwaniach) na zmianę tytułu karty w czasie wykonywania:
TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); tabLayout.getTabAt (MyTabPos) .setText ("Mój nowy tekst");
źródło
Jeśli używasz
ViewPager
(jak mój przypadek), możesz użyć:w
onPageSelected
swojej metodzieVIEW_PAGER.addOnPageChangeListener
źródło
W Twojej MainActivity pod
onCreate:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
A w Twojej działalności fragmentowej pod
onResume
:Opcjonalnie: - jeśli pokazują ostrzeżenie o zerowym odwołaniu
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);
źródło