Java 用棒棒糖SDK在Android的工具栏/操作栏中选框标题?

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.

我尝试了几种不同的方法,包括找到的方法(这反过来又让我尝试了问题的两个最重要答案),以及使用反射来访问TextView并设置相关方法。两次尝试都失败了,前者导致根本没有文本被设置为标题(我将文本设置为正确的textview元素),后者设置文本并删除椭圆,但根本没有选框。下面是我的反思尝试

导入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">