繁体   English   中英

Android:如何使用选取框从 Textview 中删除结尾空白

[英]Android: How to remove end blank space from Textview with marquee

我已经创建了带有选取框的 TextView,但我想删除 end 之间的空格并再次开始显示文本。

这是屏幕

http://i.stack.imgur.com/dfdT8.png

这是我的布局

<TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:text="dkfjdkf jdfjfsfjkfa asdfjakjfdkasf sfdjaskfjdksf sfdjsfjk gfhgfhfai ggfghgf" />

利用 :

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

如果通过空格你指的是TextView之前和之后的那些黑色条纹,你可以将你的布局调整为android:layout_width="match_parent"

<TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:text="dkfjdkf jdfjfsfjkfa asdfjakjfdkasf sfdjaskfjdksf sfdjsfjk gfhgfhfai ggfghgf" />

此外,请确保该 TextView 的父布局未应用任何边距

API 28引入对非 SDK 接口的限制时,此解决方案一直有效。


我遇到了同样的问题,我在网上找不到解决方案。 通过查看TextView 的源代码并参考 其他提供控制滚动速度选项的答案,我自己设法解决了这个问题。

查看源代码,它将间隙或空白空间设置为 TextView 大小的 1/3。 因此,如果您的 TextView 是 600 像素宽,它将在消息的开头和结尾之间创建 200 像素的间隙。 该解决方案旨在使该值可配置。

棘手的部分是您需要覆盖的逻辑都在超类的私有类、字段和方法中。 这使得解决方案变得不那么简单。

将此类添加到您的项目中... CustomTextView.java

public class CustomTextView extends AppCompatTextView {

    private static final float NEW_GAP = 0F;

    Object marqueeObject;
    Field mStatusField;
    Field mGhostStartField;
    Field mMaxScrollField;
    Field mGhostOffsetField;
    Field mFadeStopField;
    Field mMaxFadeScrollField;

    public CustomTextView(Context context) {
        super(context);
        setSelected(true);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setSelected(true);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setSelected(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        try {
            initMarqueeObject();

            if (didMarqueeRestart()) {
                // We need to update the values each time it restarts
                updateMarqueeFieldValues();
            }
        }
        catch(Exception exception) {
            exception.printStackTrace();
        }

        super.onDraw(canvas);
    }

    private void initMarqueeObject() throws Exception {
        if (marqueeObject == null) {
            Field marqueeField = getClass().getSuperclass().getSuperclass().getDeclaredField("mMarquee"); // use if extending from AppCompatTextView
            // Field marqueeField = getClass().getSuperclass().getDeclaredField("mMarquee"); // use if extending from TextView
            marqueeField.setAccessible(true);
            marqueeObject = marqueeField.get(this);
            initMarqueeFields();
        }
    }

    private void initMarqueeFields() throws Exception {
        mStatusField = marqueeObject.getClass().getDeclaredField("mStatus");
        mStatusField.setAccessible(true);
        mGhostStartField = marqueeObject.getClass().getDeclaredField("mGhostStart");
        mGhostStartField.setAccessible(true);
        mMaxScrollField = marqueeObject.getClass().getDeclaredField("mMaxScroll");
        mMaxScrollField.setAccessible(true);
        mGhostOffsetField = marqueeObject.getClass().getDeclaredField("mGhostOffset");
        mGhostOffsetField.setAccessible(true);
        mFadeStopField = marqueeObject.getClass().getDeclaredField("mFadeStop");
        mFadeStopField.setAccessible(true);
        mMaxFadeScrollField = marqueeObject.getClass().getDeclaredField("mMaxFadeScroll");
        mMaxFadeScrollField.setAccessible(true);
    }

    private boolean didMarqueeRestart() throws Exception {
        byte currentState = mStatusField.getByte(marqueeObject);
        return currentState == 0x1; // 0x1 is the byte object for the MARQUEE_STARTING state
    }

    private void updateMarqueeFieldValues() throws Exception {
        float textWidth = getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
        float originalGap = textWidth / 3.0F;
        // We have to calculate the lineWidth based on the original value
        float originalValueStartValue = mGhostStartField.getFloat(marqueeObject);
        float lineWidth = originalValueStartValue + textWidth - originalGap;
        float mGhostStart = lineWidth - textWidth + NEW_GAP;
        mGhostStartField.setFloat(marqueeObject, mGhostStart);
        mMaxScrollField.setFloat(marqueeObject, mGhostStart + textWidth);
        mGhostOffsetField.setFloat(marqueeObject, lineWidth + NEW_GAP);
        mFadeStopField.setFloat(marqueeObject, lineWidth);
        mMaxFadeScrollField.setFloat(marqueeObject, mGhostStart + lineWidth + lineWidth);
    }
}

您现在可以使用NEW_GAP变量轻松调整额外的空白空间。 在本例中,它设置为 0 像素。 将该常数设置为您希望使用的任何像素值。

注意:此解决方案是从AppCompatTextView扩展而来的。 如果您从TextView扩展,您应该取消注释initMarqueeObject()方法中的相关代码。

然后只需使用这个新类代替 XML 中的旧 TextView ......

<com.yourpackagename.CustomTextView
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:singleLine="true"
    android:scrollHorizontally="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

无需在代码中调用setSelected(true) ,因为这是在新类内部完成的。

这可能不会永远有效,因为如果他们重命名某些变量或在未来版本中更改TextView的逻辑,它将中断。 但它在我测试过的所有版本上都运行良好。

希望这会有所帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM