Настройка настраиваемого имени ActionBar из фрагмента

В моей главной 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, я хочу, чтобы заголовок изменился. Я не уверен, как получить доступ к Main 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>

Ответ 1

В вашей деятельности:

public void setActionBarTitle(String title) {
    getSupportActionBar().setTitle(title);
}

И в вашем фрагменте:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    // Set title bar
    ((MainFragmentActivity) getActivity())
            .setActionBarTitle("Your title");

}

=== Обновление 10 апреля 2015 г. ===

Вы должны использовать прослушиватель для обновления заголовка панели действий

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);
}

}

И Действия:

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

Ответ 2

То, что вы делаете, правильно. Fragments не имеют доступа к API-интерфейсам ActionBar, поэтому вам нужно позвонить 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);
}

В вашем фрагменте:

((MainFragmentActivity) getActivity()).setActionBarTitle(YOUR_TITLE);

Docs:

Activity.getTitle

Activity.setTitle

Кроме того, вам не нужно вызывать this.whatever в коде, который вы указали, просто подсказку.

Ответ 3

Примеры 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");
    }
}

Ответ 4

Настройка Activity s title из Fragment помешает уровню ответственности. Fragment содержится в Activity, поэтому это Activity, который должен установить свой собственный заголовок в соответствии с типом Fragment, например.

Предположим, что у вас есть интерфейс:

interface TopLevelFragment
{
    String getTitle();
}

Fragment, который может влиять на заголовок 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 объединяются, что вполне возможно на планшете.

Ответ 5

В Фрагменте мы можем так использовать, Он отлично работает для меня.

getActivity().getActionBar().setTitle("YOUR TITLE");

Ответ 6

На всякий случай, если у вас возникли проблемы с кодом, попробуйте поместить getSupportActionBar().setTitle(title) внутри onResume() вашего фрагмента вместо onCreateView(...) i.e

В MainActivity.java:

public void setActionBarTitle(String title) {
    getSupportActionBar().setTitle(title);
}

В фрагменте:

 @Override
 public void onResume(){
     super.onResume();
     ((MainActivity) getActivity()).setActionBarTitle("Your Title");
 }

Ответ 7

Используйте следующее:

getActivity().setTitle("YOUR_TITLE");

Ответ 8

Я не думаю, что принятый ответ является идеальным ответом на это. Поскольку все виды деятельности, которые используют

Панель инструментов

расширяются с помощью

AppCompatActivity

вызываемые из него фрагменты могут использовать указанный ниже код для изменения заголовка.

((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");

Ответ 9

Если у вас есть основное действие со многими фрагментами, которые вы вставляете, обычно используйте 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, в соответствии с позицией, нажатой в списке. Так что позиция - это то, что я фиксирую по тегу:

    fragmentManager.beginTransaction().
replace(R.id.frame_container, fragment).addToBackStack(position).commit();

Теперь, 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>

Ответ 10

Сохранить ur Ответ в String [] и установить его OnTabChange() в MainActivity как 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));
}

Ответ 11

Вот мое решение для установки заголовка ActionBar из фрагментов при использовании NavigationDrawer. Это решение использует интерфейс, поэтому фрагментам не нужно напрямую ссылаться на родительскую активность:

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; 
}

Ответ 12

Недостаток вашего подхода к такому выбору

((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
        catTitle);

заключается в том, что ваш фрагмент больше не может использоваться повторно за пределами MainActivityFragment. Если вы не планируете использовать его за пределами этой деятельности, тогда проблем нет. Лучшим подходом было бы условно установить заголовок в зависимости от активности. Поэтому внутри вашего фрагмента вы должны написать:

if (getActivity() instanceof ActionBarActivity) {
    ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title");
}

Ответ 13

если вы используете стабильный шаблон для Android версии 1.4, предоставленный Google, чем просто, вам пришлось написать следующий код в onNavigationItemSelected методе в котором ваш связанный фрагмент вызывает условие.

 setTitle("YOUR FRAGMENT TITLE");

Ответ 14

Я получаю очень простое решение установить заголовок ActionBar в любом фрагменте или любой деятельности без головной боли.

Просто измените XML, где определена Панель инструментов, как показано ниже:

<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> 

1) Если вы хотите установить панель действий во фрагменте, то:

Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);

Чтобы использовать его из любого места, вы можете определить метод в деятельности

public void setActionBarTitle(String title) {
        toolbarTitle.setText(title);
    }

Чтобы вызвать этот метод в действии, просто вызовите его.

setActionBarTitle("Your Title")

Чтобы вызвать этот метод из фрагмента действия, просто вызовите его.

((MyActivity)getActivity()).setActionBarTitle("Your Title");

Ответ 15

Чтобы добавить выбранный ответ, вы также можете добавить второй метод к своей основной деятельности. Таким образом, в вашем основном действии вы получите следующие методы:

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(), так как он позволяет вам передать идентификатор ресурса.

Ответ 16

Существует много способов, как описано выше. Вы также можете сделать это в 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);
    }
}

Ответ 17

По крайней мере, для меня был простой ответ (после многократного поиска) на изменение заголовка вкладки во время выполнения:

TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); tabLayout.getTabAt(MyTabPos).setText( "Мой новый текст" );

Ответ 18

Если вы используете ViewPager (например, мой случай), вы можете использовать:

getSupportActionBar().setTitle(YOURE_TAB_BAR.getTabAt(position).getText());

в onPageSelected метод вашего VIEW_PAGER.addOnPageChangeListener

Ответ 19

Лучшее событие для названия изменения 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);
}

Ответ 20

В вашей основной деятельности под onCreate:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

И в вашем фрагменте активности под onResume:

getActivity().setTitle(R.string.app_name_science);

Необязательно: - если они показывают предупреждение о нулевой ссылке

Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);


Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);

Ответ 21

Простой пример Kotlin

Предполагая, что эти 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!"
    }


    }