14

在我的应用程序中,我从显示的每个片段更改了 ActionBar 中的标题。当我第一次启动我的应用程序时,我得到了一个请求列表,所以我的标题是“我的请求 (20)”。

然后,当您单击该列表中的一个项目时,它正在替换我的 Activity 中的一个片段,并将标题设置为“Action”。

当我回到第一个视图(总是在同一个活动中)时,我将标题重置为“我的请求(20)”,但 android 决定截断它。所以结果是“我的请求......”。

经过多次测试,当我在其中放入较小的文本时,Android 似乎正在缩小我的标题。但是当我放一个较长的文本时它并没有放大它,即使有足够的空间。

我能做些什么来解决这个问题?我想要一个比在短标题末尾添加空格更好的解决方案:)

这是我用来更改 ActionBar 标题的代码:

getActivity().getActionBar().setTitle(title);   
4

13 回答 13

5

我知道这个问题是很久以前发布的,但我最近遇到了这个问题,它引起了极大的头痛。我正在开发 Galaxy Note 10.1,我的标题是“BidItems”,而我只看到了动作溢出项目,但有时,“BidItems”变成了“BidIt...”,这太荒谬了。经过大量测试,我发现我的应用程序中出现这种截断行为的原因是我正在使用((MyActivity) getApplication()).setTitle();我的一个片段中的方法调用一个方法。我的 Activity 中的setTitle()方法调用getActionBar().setTitle(). 一旦我调用了这个方法,我的标题就被无缘无故地截断了。但只需从我的活动中调用setTitle()就可以了。

我真的希望这可以减轻人们的头痛。

于 2013-09-05T22:43:28.457 回答
4

我想这个问题可以通过刷新操作栏 UI 来解决。

所以我用下面的代码解决了。

ActionBar actionBar = getActivity().getActionBar();
actionBar.setTitle(title);

// for refreshing UI
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
于 2015-05-14T07:09:19.980 回答
4

在我的特殊情况下,我正在开发一个具有复杂原生菜单结构的混合应用程序。从混合内容调用深度链接时,我会间歇性地看到此问题,该链接将更新所选菜单选项并设置标题。

我尝试了几个建议的修复方法,但运气不佳。但是设置自定义视图产生了一个奇怪的结果,让我感觉我正在处理一个竞争条件。

事实证明这是真的。我发现只需覆盖活动的 setTitle 函数并将对 super 的调用包装在 postDelay 可运行文件中即可为我解决此问题:

@Override
public void setTitle(final CharSequence title) {
    toolBar.postDelayed(new Runnable() {
        @Override
        public void run() {
            MainActivity.super.setTitle(title);
        }
    }, 200);
}

我使用工具栏的 postDelayed 作为一种方便的方法。但是你当然可以在这里使用处理程序。希望这可以帮助。

于 2017-01-14T02:56:13.143 回答
3

put setTitle()inonCreateOptionsMenu帮助我解决了这个问题。

在您的片段setHasOptionsMenu(true);中添加onCreateView(){}

然后覆盖onCreateOptionsMenu().

例子:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    // put getActivity in onCreateOptionsMenu will not return null
    if (getActivity() != null) {
        getActivity().setTitle(getResources().getString(R.string.Studies));
    }
}

参考:如何在不发生截断的情况下显示 android actionbar 标题

于 2016-09-26T23:09:24.093 回答
2

如本文所述,我使用自定义标题解决了这个问题。

这是我用来在选项卡更改时更改标题的代码

((TextView) actionBar.getCustomView().findViewById(R.id.title)).setText(someTitle); 

请注意,当使用操作栏选项卡时,此解决方案将标题放置在横向模式下的选项卡右侧。

于 2013-07-02T13:44:15.520 回答
2

在我的情况下,文本被截断但没有省略号(...),最后一个字符总是被截断,如下所示:

截屏

我发现将工具栏宽度从“wrap_content”更改为“match_parent”可以解决问题:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_weight="1"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />
于 2016-02-26T22:57:06.590 回答
1

我要补充一点,您完全可以在 2 行上使用操作栏标题来获得更多空间:

//Set the title over 2 lines if needed:
    int titleId = Resources.getSystem()
            .getIdentifier("action_bar_title", "id", "android");
    if (titleId > 0) {
        TextView title = (TextView) findViewById(titleId);
        title.setSingleLine(false);
        title.setMaxLines(2);
        //          title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    }

我在我的应用程序上使用它,我很满意 :)

归功于这篇文章

于 2013-09-18T08:14:40.393 回答
1

您应该会发现我在这里发布的问题是类似的问题,并且我也发布了解决方案。

为什么我的 Android ActionBar 在显式更改时不更新

于 2014-06-06T19:18:57.717 回答
1

您的 AndroidManifest.xml 具有您的活动定义,如下所示

<activity
        android:name="com.example.DetailsView"
        android:label="Details">
</activity>

如果您更改android:label="Whatever"android:label=" ",

它会工作的。我假设发生这种情况是因为 android 创建了一个 TextView 来显示标签,并且在调用 setTitle 时宽度没有重新调整大小。因此,通过将初始标题设置为具有比您设置标题更多的字符,它不会被截断。

于 2014-07-10T15:49:22.647 回答
1

因为ListView/GridView/RecyclerView同时调用notifyDataSetChanged()。由于某种原因,这会导致布局更新,我猜这会导致操作栏标题的布局更新混乱。

基本上,你可以 postDelay() 来更新标题来解决这个问题,但我不喜欢这种方式。

我决定重写 BaseAdapter.notifyDateSetChanged() 并手动更新项目视图。有用:

public abstract class BaseListAdapter<BEAN extends Unique, VH extends BaseListViewHolder<BEAN>> extends BaseAdapter {
    // data
    private List<BEAN> mList;
    // view holder
    private List<VH> mViewHolderList = new ArrayList<>();

    protected abstract void onBindViewHolder(VH holder, int position);

    protected abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

    ...

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        VH viewHolder;
        if (convertView == null) {
            viewHolder = onCreateViewHolder(parent, getItemViewType(position));
            convertView = viewHolder.itemView;
            convertView.setTag(viewHolder);
            mViewHolderList.add(viewHolder);
        } else {
            //noinspection unchecked
            viewHolder = (VH) convertView.getTag();
        }

        viewHolder.setData(getItem(position));
        viewHolder.setPosition(position);
        onBindViewHolder(viewHolder, position);

        return convertView;
    }

    @Override
    public void notifyDataSetChanged() {
        if (mViewHolderList.size() == 0) {
            super.notifyDataSetChanged();
        } else {
            for (VH vh : mViewHolderList) {
                onBindViewHolder(vh, vh.getPosition());
            }
        }
    }

}

public class BaseListViewHolder<T> {
    public View itemView;
    private T data;

    private int position;

    public BaseListViewHolder(View itemView) {
        this.itemView = itemView;
    }

    @Override
    public T getData() {
        return data;
    }

    @Override
    public void setData(T data) {
        this.data = data;
    }

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }
}

对不起,我的英语不好。

于 2017-08-20T04:37:03.493 回答
1

2013年的一个问题,仍然是一件事。

好吧,对于那些偶尔看到这种情况仍然感到震惊的人,即使你很高兴地使用 Androidx、所有最近的工件等。我找到了修复它的东西,它不需要自定义标题或任何特殊的东西。

请记住,这可能不是您的情况,但它似乎在瞬间神奇地解决了这个问题。

而言,Toolbar, 像往常一样设置supportActionBar,它包含在CoordinatorLayout+AppBar中。起初我会责怪那些,因为为什么不这样做,但在这样做之前,我决定检查工具栏的源代码并调试正在发生的事情。

我不知道(但我确实找到了导致此省略号的代码):

/**
 * Set the title of this toolbar.
 *
 * <p>A title should be used as the anchor for a section of content. It should
 * describe or name the content being viewed.</p>
 *
 * @param title Title to set
 */
public void setTitle(CharSequence title) {
    if (!TextUtils.isEmpty(title)) {
        if (mTitleTextView == null) {
            final Context context = getContext();
            mTitleTextView = new AppCompatTextView(context);
            mTitleTextView.setSingleLine();
            mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
            if (mTitleTextAppearance != 0) {
                mTitleTextView.setTextAppearance(context, mTitleTextAppearance);
            }
            if (mTitleTextColor != null) {
                mTitleTextView.setTextColor(mTitleTextColor);
            }
        }
        if (!isChildOrHidden(mTitleTextView)) {
            addSystemView(mTitleTextView, true);
        }
    } else if (mTitleTextView != null && isChildOrHidden(mTitleTextView)) {
        removeView(mTitleTextView);
        mHiddenViews.remove(mTitleTextView);
    }
    if (mTitleTextView != null) {
        mTitleTextView.setText(title);
    }
    mTitleText = title;
}

这直接来自最新的 Toolbar.java appCompat 1.1.0(最新的时间是 2019 年 10 月)。

没什么特别的,但是您可以看到,当 TitleTextView 首次创建时,它设置为 singleLine 并在 END... 处使用 Ellipsize...(或在 LTR 语言中正确)。

但是,我注意到,当我调用 setTitle 时,代码并没有这样想,大概是因为之前创建了 titleTextView(当时使用 Ellipsis 设置为 singleLine);当我调用 setTitle 时,所有代码都在做mTitleTextView.setText(title). 工具栏上没有多少invalidate(), forceLayout(),requestLayout()可以解决这个问题。

经过进一步检查,我注意到我的布局(协调器布局)包含在RelativeLayout.

视图层次结构看起来像:

<RelativeLayout>
   <CoordinatorLayout>
       <AppBarLayout>
          <androidx.appcompat.widget.Toolbar />
       </AppBarLayout>
       <androidx.viewpager2.widget.ViewPager2 />
       <com.google.android.material.bottomnavigation.BottomNavigationView />
   </CoordinatorLayout>
</RelativeLayout>

从不喜欢RelativeLayout,一开始我认为这是一个糟糕的设计,但自从我记得以来,它也面临着各种问题,而且它在处理它的孩子方面非常糟糕。

为了好玩,我决定:“如果我把这个 RelativeLayout 改成一个 ConstraintLayout 会怎样?”

我在 Android Studio 可视化编辑器的 RelativeLayout 中“右键单击”-> 转换为 ConstraintLayout,下一步,完成(没有触及默认值)。

现在看起来像这样:

<ConstraintLayout>
   <CoordinatorLayout>
       <AppBarLayout>
          <androidx.appcompat.widget.Toolbar />
       </AppBarLayout>
       <androidx.viewpager2.widget.ViewPager2 />
       <com.google.android.material.bottomnavigation.BottomNavigationView />
   </CoordinatorLayout>
</ConstraintLayout>

相同,但 ROOT 不再是相对布局。

我对生成的 XML 进行了两次手动更改:

这是 CoordinatorLayout 在转换后的样子:

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent">

它在预览中看起来不错,但它引起了我的注意,因为一个 _should not use match_parentin child of ConstraintLayout ...所以...我将其更改为:

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/coordinatorLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

这和我之前的完全一样(协调器布局占据了整个屏幕)。

这要归功于新的 ConstraintLayout 具有这些:

    android:layout_width="match_parent"
    android:layout_height="match_parent"

神奇地一劳永逸地解决了我被截断的标题。

tl;博士

2019 年以后不要再使用 RelativeLayouts,从很多角度来看它们都是不好的。如果您的工具栏包含在相对布局中,请考虑迁移到 ConstraintLayout 或任何其他 ViewGroup。

于 2019-10-18T16:37:26.167 回答
0

我认为您对此无能为力。似乎操作栏标题的宽度相当有限,并且任何超过它的东西都会被截断。

我想一种方法是显示:“我的请求(20)”而不是“我的请求(20)”,但我明白这并不理想。

于 2013-03-22T16:59:15.227 回答
0

如果有人在 2 年后仍然对正确答案感兴趣,我最近也遇到了这个问题,并意识到原因是我从后台线程更新了标题。在 Kotlin 中使用supportActionBar?.title = <abc>.
由于某种原因,该应用程序没有像通常那样崩溃,但有一个例外是您正在触摸 UI 线程之外的视图。相反,它会设置新文本,但会跳过布局传递,从而导致文本换行。
所以要么使用Activity.runOnUiThreadorView.post要么,当我像我一样使用协程时,使用withContext(Dispatchers.Main)来触发更新标题的代码。

于 2019-09-24T09:57:27.097 回答