You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免TextView在Handler.postDelayed时自动滚动从头开始?

Hey there! Let's dig into why your scrolling TextView resets every time you update the SeekBar with Handler.postDelayed()—and how to fix it.

The core issue here is that updating the SeekBar is likely triggering a layout redraw or state change in your TextView, which resets the default marquee (horizontal scroll) position. Let's walk through practical solutions:

Fixes to Keep Your TextView Scrolling Smoothly

1. Lock Down the TextView's Marquee Configuration

First, make sure your TextView has all the right attributes to maintain its scroll state. Your existing XML was cut off, so here's the complete, stable setup:

<TextView
    android:id="@+id/titre"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/play"
    android:textColor="@color/textColor"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:scrollHorizontally="true"
    android:freezesText="true" />

The critical lines here:

  • android:freezesText="true": This tells the TextView to save its current scroll position when it's redrawn, preventing a reset.
  • android:focusable="true" + android:focusableInTouchMode="true": Ensures the TextView retains focus, which the default marquee needs to keep running.

2. Isolate SeekBar Updates From TextView Layout

Double-check your postDelayed logic—make sure you're not accidentally triggering a full layout refresh that affects the TextView. For example:

  • Don't call requestLayout() or invalidate() on the TextView or its parent view when updating the SeekBar.
  • If your layout is complex, wrap the TextView in a FrameLayout to limit the scope of any redraws caused by the SeekBar.

3. Manually Save and Restore Scroll Position

If the above config doesn't work, you can explicitly track the TextView's scroll offset and reset it after updating the SeekBar:

private int savedScrollOffset = 0;
private TextView titreTextView;
private Handler updateHandler = new Handler();

private Runnable updateSeekBarTask = new Runnable() {
    @Override
    public void run() {
        // Save current scroll position before updating SeekBar
        savedScrollOffset = titreTextView.getScrollX();
        
        // Your existing SeekBar update logic
        seekBar.setProgress(getCurrentMediaProgress());
        
        // Restore the scroll position immediately
        titreTextView.scrollTo(savedScrollOffset, titreTextView.getScrollY());
        
        // Schedule the next update
        updateHandler.postDelayed(this, 1000);
    }
};

This acts as a safety net—no matter what triggers a redraw, you force the TextView back to its previous scroll spot.

4. Build a Custom Scrolling TextView (For Full Control)

If the default marquee is too fragile, create a custom TextView with your own scroll logic. This way, layout changes from the SeekBar won't interfere:

public class PersistentScrollTextView extends AppCompatTextView {
    private Handler scrollHandler = new Handler();
    private Runnable scrollRunnable;
    private int scrollSpeed = 2; // Adjust pixels per frame for speed

    public PersistentScrollTextView(Context context) {
        super(context);
        initScrollLogic();
    }

    public PersistentScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initScrollLogic();
    }

    private void initScrollLogic() {
        setSingleLine(true);
        setEllipsize(null); // Disable default marquee
        scrollRunnable = new Runnable() {
            @Override
            public void run() {
                scrollBy(scrollSpeed, 0);
                // Loop back to start when end is reached
                if (getScrollX() >= getLayout().getLineWidth(0) - getWidth()) {
                    scrollTo(0, 0);
                }
                scrollHandler.postDelayed(this, 16); // ~60fps
            }
        };
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        scrollHandler.post(scrollRunnable);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        scrollHandler.removeCallbacks(scrollRunnable);
    }
}

Then use it in your XML like any other TextView—this custom implementation runs independently of system layout changes.

内容的提问来源于stack exchange,提问作者Paul Noiré

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:44:36