在Android的片段中从工具栏设置标题

34
我一直在使用来自AppCompatv7库的最新工具栏。我在ToolBar ViewGroup中放置了一个TextView,并希望从我的Activity的片段中将标题设置到此TextView中。对于自定义操作栏,((ActionBarActivity)getActivity).setcustomView(..) 可以完成此工作。但由于使用了这个ToolBar,我无法使用它。同时,我已经在我的BaseActivity中实现了一个方法,该方法被所有Activity继承。这个BaseActivity包含我的初始化向左滑动抽屉的方法。我必须在Activity中初始化initDrawerLayout()方法,否则抽屉不会被初始化。如果我在片段中进行初始化,则会得到所有空结果,既不是抽屉的切换按钮,也不是自定义标题被设置。
这是我的initDrawer代码...
public void initDrawerLayout(String toolbar_text) {
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerRelative = (RelativeLayout) findViewById(R.id.drawer_relative);
        if (mDrawerLayout != null) {
            findViewById(R.id.drawer_btn_a).setOnClickListener(this);
            findViewById(R.id.drawer_btn_b).setOnClickListener(this);
            findViewById(R.id.drawer_btn_c).setOnClickListener(this);
            findViewById(R.id.drawer_btn_d).setOnClickListener(this);
            findViewById(R.id.drawer_btn_e).setOnClickListener(this);
            findViewById(R.id.drawer_btn_f).setOnClickListener(this);
            findViewById(R.id.drawer_btn_g).setOnClickListener(this);
            findViewById(R.id.drawer_btn_h).setOnClickListener(this);
            findViewById(R.id.drawer_btn_i).setOnClickListener(this);
            findViewById(R.id.drawer_btn_j).setOnClickListener(this);
            findViewById(R.id.drawer_btn_k).setOnClickListener(this);
            findViewById(R.id.drawer_btn_l).setOnClickListener(this);
            findViewById(R.id.my_layout).setOnClickListener(this);





            Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
            toolbar.setBackground(getResources().getDrawable(R.drawable.icn_actionbar_background));
            TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
            mTitle.setText(toolbar_text);
            mTitle.setTypeface(Typeface.DEFAULT_BOLD);
            if (toolbar != null) {
                setSupportActionBar(toolbar);
                 getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            }
            toolbar.setNavigationIcon(R.drawable.ic_drawer);

             mDrawerToggle = new ActionBarDrawerToggle(
                    this,  mDrawerLayout, toolbar,
                    R.string.drawer_open, R.string.drawer_close
                );
                mDrawerLayout.setDrawerListener(mDrawerToggle);


            toolbar.setNavigationOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
                        mDrawerLayout.closeDrawer(Gravity.LEFT);
                    } else {
                        mDrawerLayout.openDrawer(Gravity.LEFT);
                    }
                }
            });
            mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
                    GravityCompat.START);

            mDrawerLayout.setScrimColor(getResources().getColor(
                    android.R.color.transparent));
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setHomeButtonEnabled(true);
            getSupportActionBar().setDisplayShowTitleEnabled(false);

        }
    }

以下是我的片段代码:

((FirstActivity) getActivity()).initDrawerLayout(mFirst.name); 其中mFirst是Person类的一个对象。

注意工具栏代码:

<android.support.v7.widget.Toolbar
            android:id="@+id/my_awesome_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize">
           <TextView
                android:id="@+id/toolbar_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:text="Toolbar Title"
                android:textColor="@color/action_text-color"
                android:textSize="18sp"
                android:textStyle="bold" /> 

            </android.support.v7.widget.Toolbar>

请帮帮我,各位...


7
给这个帖子点踩的人,请在点踩之前回答一下问题,我在搜索了很多后才提出了这个问题。 - AndroidMech
18个回答

63

我这样做: 从片段调用

getActivity().setTitle("your title");

但是您在调用它时的位置很重要,因为如果每个片段都有自己的标题,那么一个可能会意外覆盖另一个,可以像这样防止这种情况:

@Override
public void onResume() {
    super.onResume();

    Activity activity = getActivity();
    if (activity != null) {
        activity.setTitle(getString(R.string.my_title));
    }
}

例如,同一Pager的两个Fragment不能同时处于恢复状态。

您还可以“投射”(cast)来调用父Activity的任何函数,像这样:

YourActivity mYourActiviy = (YourActivity) getActivity();
mYourActivity.yourActivityFunction(yourParameters);

28
在 Kotlin 中。 在 Fragment 中:
(activity as YourActivity).supportActionBar?.title = getString(R.string.your_title)

活动中:

setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)

14
如果您在活动中使用了 setSupportActionBar,则可以轻松地从片段更改工具栏标题。
((YourActivity) getActivity()).getSupportActionBar().setTitle("Your Title");

12
为了让 Fragment 向其 Activity 通信(以设置工具栏标题),您可以在 Fragment 类中定义一个接口,并在 Activity 中实现它,如此处所述:与其他 Fragment 通信

10

答案写在片段的oncreateview方法中,如下所示:

getActivity().setTitle("your name");

7

您可以在Fragment内创建接口。请查看以下内容:

public class MyFragment extends Fragment {
    OnMyFragmentListener mListener;

    // Where is this method called??
    public void setOnMyFragmentListener(OnMyFragmentListener listener) {
        this.mListener = listener;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnMyFragmentListener) {
            mListener = (OnMyFragmentListener) context;
            mListener.onChangeToolbarTitle("My Fragment"); // Call this in `onResume()`
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onResume(){
        super.onResume();
        mListener.onChangeToolbarTitle("My Fragment");
    }


    // This interface can be implemented by the Activity, parent Fragment,
    // or a separate test implementation.
    public interface OnMyFragmentListener {
        public void onChangeToolbarTitle(String title);
    }

}

在Activity中:-
public class MyActivity extends AppCompatActivity implements MyFragment.OnMyFragmentListener {

    @Override
    public void onChangeToolbarTitle(String title){
        toolbar.setTitle(title);
    }

}

这对我有效。 :)

除了我建议您只使用onAttach(Context context)来初始化listener并使用onResume()调用监听器的方法之外,它运作得非常好。 - Mitch
它不应该很难或很复杂。 - withoutOne

5

我在Kotlin中试过这个方法。将以下代码放入你的Fragment类中:

if (activity != null) {
        (activity as MainActivity).supportActionBar?.title = getString(R.string.action_history)
    }

4

如果有人遇到这个问题,下面的内容可能会有所帮助。

基本上你有4个选项来处理这个问题:

  • 使用接口与你的活动或其他方便的方法(如事件总线)进行通信。

  • 调用getActivity().setTitle("Title"),但在这种情况下,你需要通过在你的活动中调用setSupportActionBar()将你的Toolbar附加到ActionBar

  • 你可以拥有一个公共的Toolbar实例,并从片段中访问该实例。

  • 最后,如果你需要你的Toolbar实例(你可能想要做其他事情),你可以直接这样获取:

    Toolbar bar = Toolbar.class.cast(getActivity().findViewById(R.id.toolbar));

嗯,最后一种选择只有在Toolbar没有被传递给setSupportActionBar方法时才能解决问题。

如果已经传递了,那么你需要在你的活动中调用这个方法:

supportActionBar.setDisplayShowTitleEnabled(false)

这将解决问题。

然而,我建议使用ButterKnife,这将使代码更加简洁,以下是一个示例:

  Toolbar actionBar=findById(getActivity(),R.id.actionBar);
  actionBar.setTitle("Title");

你知道你在做什么。非常好的回答,谢谢。 - Emmanuel Aliji

4
在Kotlin中,我使用
fun onAttach(...){
..
activity?.title = "My Title"
}

3
这对我有用:
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.id_toolbar);

toolbar.setTitle("New Title");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接