Java 用棒棒糖SDK在Android的工具栏/操作栏中选框标题?
我尝试了几种不同的方法,包括找到的方法(这反过来又让我尝试了问题的两个最重要答案),以及使用反射来访问TextView并设置相关方法。两次尝试都失败了,前者导致根本没有文本被设置为标题(我将文本设置为正确的textview元素),后者设置文本并删除椭圆,但根本没有选框。下面是我的反思尝试Java 用棒棒糖SDK在Android的工具栏/操作栏中选框标题?,java,android,android-actionbar,android-5.0-lollipop,android-toolbar,Java,Android,Android Actionbar,Android 5.0 Lollipop,Android Toolbar,我尝试了几种不同的方法,包括找到的方法(这反过来又让我尝试了问题的两个最重要答案),以及使用反射来访问TextView并设置相关方法。两次尝试都失败了,前者导致根本没有文本被设置为标题(我将文本设置为正确的textview元素),后者设置文本并删除椭圆,但根本没有选框。下面是我的反思尝试 导入android.content.Context; 导入android.support.v7.widget.Toolbar; 导入android.text.TextUtils; 导入android.util.
导入android.content.Context;
导入android.support.v7.widget.Toolbar;
导入android.text.TextUtils;
导入android.util.AttributeSet;
导入android.widget.TextView;
导入android.widget.Toast;
导入java.lang.reflect.Field;
公共类选框工具栏扩展工具栏{
公共选框工具栏(上下文){
超级(上下文);
}
公共选框工具栏(上下文、属性集属性){
超级(上下文,attrs);
}
公共选框工具栏(上下文上下文、属性集属性、int-defStyleAttr){
super(上下文、attrs、defStyleAttr);
}
@凌驾
公共无效设置标题(字符序列标题){
如果(!反射){
反射=反射标题();
}
超级标题(标题);
}
@凌驾
公共无效集合标题(整数剩余){
如果(!反射){
反射=反射标题();
}
super.setTitle(剩余);
}
布尔值=假;
私有布尔反射标题(){
试一试{
Field=Toolbar.class.getDeclaredField(“mTitleTextView”);
字段。setAccessible(true);
TextView titleView=(TextView)field.get(this);
titleView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
titleView.SetMarquerePeatLimit(-1);
返回true;
}捕获(无此字段例外){
e、 printStackTrace();
返回false;
}捕获(非法访问例外e){
e、 printStackTrace();
返回false;
}捕获(NullPointerException e){
e、 printStackTrace();
返回false;
}
}
}
尝试在工具栏中放置文本视图:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" >
<TextView
android:id="@+id/toolbar_title"
android:text="This will run the marquee animation forever"
android:textSize="@dimen/abc_text_size_title_material_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:singleLine="true" />
</android.support.v7.widget.Toolbar>
findViewById<Toolbar>(R.id.action_bar)?.let {
setToolbarTextViewsMarquee(it)
}
fun setToolbarTextViewsMarquee(toolbar: Toolbar) {
for (child in toolbar.children) {
if (child is TextView) {
setMarquee(child)
}
}
}
fun setMarquee(textView: TextView) {
textView.ellipsize = TextUtils.TruncateAt.MARQUEE
textView.isSelected = true
textView.marqueeRepeatLimit = -1
}
最终我明白了,这是因为,据我所知,设置了字幕的文本视图需要在实际开始字幕之前被选中。我更新了我在问题中发布的MarqueeToolbar类,可以在下面的要点中找到:从
工具栏
类中声明的TextView
字段名中获取标题TextView
对象和工具栏的MarqueeToolbar标题
TextView titleTextView = null;
try {
Field f = toolbar.getClass().getDeclaredField("mTitleTextView");
f.setAccessible(true);
titleTextView = (TextView) f.get(toolbar);
titleTextView.setEllipsize(TruncateAt.MARQUEE);
titleTextView.setFocusable(true);
titleTextView.setFocusableInTouchMode(true);
titleTextView.requestFocus();
titleTextView.setSingleLine(true);
titleTextView.setSelected(true);
titleTextView.setMarqueeRepeatLimit(-1);
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
}
创建自定义工具栏并应用标题和副标题选框效果:
public class MarqueeToolbar extends Toolbar {
TextView title, subTitle;
public MarqueeToolbar(Context context) {
super(context);
}
public MarqueeToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarqueeToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setTitle(CharSequence title) {
reflected = reflectTitle();
super.setTitle(title);
selectTitle();
}
@Override
public void setTitle(int resId) {
if (!reflected) {
reflected = reflectTitle();
}
super.setTitle(resId);
selectTitle();
}
boolean reflected = false;
private boolean reflectTitle() {
try {
Field field = Toolbar.class.getDeclaredField("mTitleTextView");
field.setAccessible(true);
title = (TextView) field.get(this);
title.setEllipsize(TextUtils.TruncateAt.MARQUEE);
title.setMarqueeRepeatLimit(-1);
return true;
} catch (NoSuchFieldException e) {
e.printStackTrace();
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
public void selectTitle() {
if (title != null)
title.setSelected(true);
}
// ------------ for Subtitle ----------
@Override
public void setSubtitle(CharSequence subTitle) {
if (!reflectedSub) {
reflectedSub = reflectSubTitle();
}
super.setSubtitle(subTitle);
selectSubtitle();
}
@Override
public void setSubtitle(int resId) {
if (!reflected) {
reflectedSub = reflectSubTitle();
}
super.setSubtitle(resId);
selectSubtitle();
}
boolean reflectedSub = false;
private boolean reflectSubTitle() {
try {
Field field = Toolbar.class.getDeclaredField("mSubtitleTextView");
field.setAccessible(true);
subTitle = (TextView) field.get(this);
subTitle.setEllipsize(TextUtils.TruncateAt.MARQUEE);
subTitle.setMarqueeRepeatLimit(-1);
return true;
} catch (NoSuchFieldException e) {
e.printStackTrace();
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
public void selectSubtitle() {
if (subTitle != null)
subTitle.setSelected(true);
}
}
Kotlin解决方案为标题和副标题文本视图设置
选框
(它只会在工具栏中查找所有文本视图):
获取此信息:尝试在空对象引用上调用虚拟方法“void android.widget.TextView.setEllipsize(android.text.TextUtils$TruncateAt)”,在android 7.0上对我有效。在没有选项菜单但没有选项菜单代码的情况下有效,但在kitkat及以上版本中无效。还有什么我能做的吗?
findViewById<Toolbar>(R.id.action_bar)?.let {
setToolbarTextViewsMarquee(it)
}
fun setToolbarTextViewsMarquee(toolbar: Toolbar) {
for (child in toolbar.children) {
if (child is TextView) {
setMarquee(child)
}
}
}
fun setMarquee(textView: TextView) {
textView.ellipsize = TextUtils.TruncateAt.MARQUEE
textView.isSelected = true
textView.marqueeRepeatLimit = -1
}
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">