【问题标题】:TextView setSelected(false) Does Not Stop MarqueeTextView setSelected(false) 不停止选取框
【发布时间】:2025-12-30 01:10:07
【问题描述】:

我在CardFragment 中使用了TextView,在GridViewPager 中。 TextView 设置为永远显示。但是当TextView 并没有真正被用户看到时,我希望它停止滚动。

<TextView
    android:id"@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:singleLine="true"/>

为了让TextView 真正开始滚动,我调用setSelected(true),但是当我在片段的onPause() 方法中调用setSelected(false) 时,没有任何反应,文本继续滚动。我知道 onPause() 正在被调用,当我在 TextView 上调用 isSelected() 时,它确实返回 false。

只有当我离开两页以上时,文本才会停止滚动。我相信这是因为片段实际上在不靠近当前页面时被销毁,然后在它重新发挥作用时重新创建。

如何让TextView 停止滚动(而不实际破坏片段)?我也尝试过setMarqueeRepeatLimit(0)(以及再次选择setMarqueeRepeatLimit(-1)),但这也不起作用。

编辑:当前 xml 代码:

<TextView
    android:id"@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="end"
    android:marqueeRepeatLimit="marquee_forever"
    android:singleLine="true"/>

片段代码:

public class MyCardFragment extends CardFragment {
    private static final String TAG = MyCardFragment.class.getSimpleName();

    private String mText;

    private Context mContext;

    private TextView mTextView;

    public static MyCardFragment create(String text) {
        mText = text;
    }

    @OVerride
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getActivity().getApplicationContext();
    }

    @Override
    public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.card_fragment, container, false);

        mTextView = (TextView) view.findViewById(R.id.text);
        mTextView.setText(mText);
        mTextView.setSelected(true);

        return view;
    }

    @Override
    public void onPause() {
        super.onPause();
        mTextView.setEllipsize(TextUtils.TruncateAt.END);
        Log.d(TAG, "text: " + mTextView.getText() + " ellipsize: " + mTextView.getEllipsize());
    }

    public void onSelected() {
        mTextView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
        Log.d(TAG, "text: " + mTextView.getText() + " ellipsize: " + mTextView.getEllipsize());
    }
}

而我的活动实现GridViewPager.OnPageChangeListener 调用onSelected()

public class MainActivity implements GridViewPager.OnPageChangeListener {

    ...

    @Override
    public void onPageSelected(int row, int column) {
        MyCardFragment fragment = (MyCardFragment) mPagerAdapter.findExistingFragment(row, column);
        fragment.onSelected();
    }
}

【问题讨论】:

    标签: android android-fragments android-viewpager textview


    【解决方案1】:

    您可以使用 setEllipsize() 将 ellipsize 属性设置为无。

    以下代码对我有用:

    public class MainActivity extends AppCompatActivity {
    
        private TextView textView;
        private TextUtils.TruncateAt noneEllipsize;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = (TextView) findViewById(R.id.title);
            noneEllipsize = textView.getEllipsize(); // activity_main.xml has ellipsize property set to 'none'.
            textView.setSelected(true);
        }
    
        public void btnToggleMarqueeClick(View view) {
            if ( textView.getEllipsize() != noneEllipsize ) {
                textView.setEllipsize(noneEllipsize);
            } else {
                textView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
            }
        }
    }
    

    这是我的 activity_main.xml 文件:

    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity">
    
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="none"
        android:marqueeRepeatLimit="marquee_forever"
        android:text="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        android:singleLine="true"/>
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start"
        android:id="@+id/btnToggleMarquee"
        android:onClick="btnToggleMarqueeClick"/>
    </LinearLayout>
    

    建议对您的代码进行以下更改

    如下更新布局xml

    <TextView
    android:id"@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="none"
    android:marqueeRepeatLimit="marquee_forever"
    android:singleLine="true"/>
    

    更新片段代码如下:

    public class MyCardFragment extends CardFragment {
        private static final String TAG = MyCardFragment.class.getSimpleName();
    
        private String mText;
    
        private Context mContext;
    
        private TextView mTextView;
    
        private TextUtils.TruncateAt noneEllipsize;
    
        public static MyCardFragment create(String text) {
            mText = text;
        }
    
        @OVerride
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mContext = getActivity().getApplicationContext();
        }
    
        @Override
        public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.card_fragment, container, false);
    
            mTextView = (TextView) view.findViewById(R.id.text);
            noneEllipsize = mTextView.getEllipsize();
            mTextView.setText(mText);
            mTextView.setSelected(true);
    
            return view;
        }
    
        @Override
        public void onPause() {
            super.onPause();
            mTextView.setEllipsize(noneEllipsize);
            Log.d(TAG, "text: " + mTextView.getText() + " ellipsize: " + mTextView.getEllipsize());
        }
    
        public void onSelected() {
            mTextView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
            Log.d(TAG, "text: " + mTextView.getText() + " ellipsize: " + mTextView.getEllipsize());
        }
    }
    

    MainActivity 中的 onPageSelected() 方法保持原样。

    【讨论】:

    • 仍然无法正常工作,即使我登录 mTextView.getEllipize() 并打印 NONE,文本仍会继续滚动。我也尝试将其设置为TextUtil.TruncateAt.END,但没有运气。
    • 我刚刚在问题的编辑中添加了当前代码。
    • 谢谢。我更新了答案以建议对您的代码进行编辑。如果有帮助,请告诉我。
    【解决方案2】:
    textView.setEllipsize(null)
    

    来自文档:

    导致文本中长于视图宽度的单词 椭圆形而不是在中间折断。您可能还想 setSingleLine() 或 setHorizo​​ntallyScrolling(boolean) 来约束 文本到单行。 使用null 关闭省略号。如果 setMaxLines(int) 已用于设置两行或多行,只有 END 和 支持 MARQUEE(其他省略号类型不会做任何事情)。

    【讨论】: