In my Main FragmentActivity
, I setup my custom ActionBar
title like this:
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);
This works perfect. However, once I open other Fragments
, I want the title to change. I am not sure how to access the Main Activity
to do this? In the past, I did this:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle( catTitle);
Can someone advise on the proper method?
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>
you can change the title by overriding the onResume method. And for the safe side, you can also override setUserVisibleHint and change the title when fragment isVisibleToUser .
To set the title for your ActionBar , while using a custom layout, in your Fragment you'll need to call getActivity(). setTitle(YOUR_TITLE) .
What you're doing is correct. Fragments
don't have access to the ActionBar
APIs, so you have to call getActivity
. Unless your Fragment
is a static inner class, in which case you should create a WeakReference
to the parent and call Activity.getActionBar
from there.
To set the title for your ActionBar
, while using a custom layout, in your Fragment
you'll need to call getActivity().setTitle(YOUR_TITLE)
.
The reason you call setTitle
is because you're calling getTitle
as the title of your ActionBar
. getTitle
returns the title for that Activity
.
If you don't want to get call getTitle
, then you'll need to create a public method that sets the text of your TextView
in the Activity
that hosts the Fragment
.
In your Activity:
public void setActionBarTitle(String title){ YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title); }
In your Fragment:
((MainFragmentActivity) getActivity()).setActionBarTitle(YOUR_TITLE);
Docs:
Activity.getTitle
Activity.setTitle
Also, you don't need to call this.whatever
in the code you provided, just a tip.
===Update October, 30, 2019===
Since we have new components such as ViewModel and LiveData, we can have a different/easier way to update Activity Title from Fragment by using ViewModel and Live Data
Activity
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") } }
And MainModelView:
class MainViewModel : ViewModel() { private val _title = MutableLiveData<String>() val title: LiveData<String> get() = _title fun updateActionBarTitle(title: String) = _title.postValue(title) }
And then you can update the Activity title from Fragment using viewModel.updateActionBarTitle("Custom Title From Fragment")
===Update April, 10, 2015===
You should use listener to update your action bar title
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); } }
And Activity:
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); } }
Read more here: https://developer.android.com/training/basics/fragments/communicating.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With