Marquee title in toolbar / ActionBar on Android with Lollipop SDK?

I tried several different approaches, including the one found here (which in turn prompted me to try both of the top answers to this question), and also use reflection to access the TextView and set the appropriate methods. Both attempts failed, the first of which did not result in the text being assigned no title at all (and I set the text to the corresponding textview element), the last set the text and deleted the ellipse, but did not divide it at all. Below is my attempt at reflection.

import android.content.Context;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Field;

public class MarqueeToolbar extends Toolbar {

    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) {
        if (!reflected) {
            reflected = reflectTitle();
        }
        super.setTitle(title);
    }

    @Override
    public void setTitle(int resId) {
        if (!reflected) {
            reflected = reflectTitle();
        }
        super.setTitle(resId);
    }

    boolean reflected = false;
    private boolean reflectTitle() {
        try {
            Field field = Toolbar.class.getDeclaredField("mTitleTextView");
            field.setAccessible(true);
            TextView titleView = (TextView) field.get(this);
            titleView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
            titleView.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;
        }
    }
}
+7
5

, , , TextViews, , . MarqueeToolbar, , Gist: https://gist.github.com/InsanityOnABun/95c0757f2f527cc50e39

+3

TextView TextView Toolbar class .

    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) {
    }
+9

TextView :

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

ActionBar / :

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null); // or, setDisplayShowTitleEnabled(false)
+6

:

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

}
0

Kotlin MARQUEE MARQUEE :

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
}

(android.support.v7.widget.Toolbar androidx.appcompat.widget.Toolbar) XML.

, AppCompat:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
0

All Articles