同一LinearLayout中更改另一个TextView时,TextView重新启动跑马灯效果

8

我有一个LinearLayout,里面有两个TextView都有跑马灯效果。当我更新第一个TextView的文本时,第二个TextView会重新开始跑马灯效果。

            <LinearLayout
                android:id="@+id/panel"
                android:layout_width="320dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="2dp"
                android:layout_marginRight="2dp"
                android:gravity="center_vertical"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/first"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:ellipsize="marquee"
                    android:gravity="bottom|center_horizontal"
                    android:marqueeRepeatLimit="marquee_forever"
                    android:singleLine="true" />

                <TextView
                    android:id="@+id/second"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:ellipsize="marquee"
                    android:gravity="top|center_horizontal"
                    android:marqueeRepeatLimit="marquee_forever"
                    android:singleLine="true"
                      />
            </LinearLayout>

我发现如果我为 R.id.firstR.id.second 设置layout_width="320dp",就不会产生效果。 但是我想设置android:layout_width="match_parent",有什么解决方法吗?
我发现了类似的问题,但没有解决方案: Android中,当在同一RelativeLayout中更改ImageView时,RelativeLayout会重新启动Marquee-TextView。
3个回答

13

您应该避免将两个跑马灯放在同一个ViewGroup中。 在您的情况下,您可以使用LinearLayout包装每个跑马灯TextView(如果使用RelativeLayout,则无法使用此方法)。


2
最佳答案。解决问题最简单、最合乎逻辑的方式。这应该是被采纳的答案。 - Hamza Khurshid
1
这个完全可行。我只是把我的TextView放在了一个LinearLayout里面。 - Mateus Pires

12

我有一个类似的问题,解决方法是为TextView设置固定大小。

那么为什么不通过编程来实现呢?在我的情况下,这种方式解决了问题。下面是我的详细解决方案:

布局有点复杂,有很多变化的值。这里是有趣的部分:

layout.xml:

<!-- The height and visibility values change programatically -->
<RelativeLayout 
    android:layout_width="fill_parent"
    android:layout_height="30dp" 
    android:layout_alignParentBottom="true"
    android:visibility="gone" >

    <FrameLayout>
        ...
        // some code
        ...
    </FrameLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal" >

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

        <!-- My scrolling textview. see below. -->
        <!-- The size will be set when -->
        <!-- the layout will be draw, -->
        <!-- after the Activity.onCreate(). -->
        <!-- I removed ALL THE UNECESSARY (I mean  -->
        <!-- scrollHorizontally, focusable and focusableInTouchMode. -->
        <!-- You don't need it !!!!) -->
        <fr.cmoatoto.android.widget.ScrollingTextView 
            android:id="@+id/text"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever" />

        <ImageView
            ...
            // some code
            ... />
    </LinearLayout>
</RelativeLayout>

这个回答中定义了ScrollingTextView。

以下是代码:

ScrollingTextView.java:

public class ScrollingTextView extends TextView {

    public ScrollingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

    public ScrollingTextView(Context context) {
        super(context);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

最后是Activity。如我之前所说,您需要设置固定的宽度和高度,因此我们将在onCreate()中使用监听器以编程方式实现:
MyActivity.java:
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.layout);


    TextView textView = ((TextView) findViewById(R.id.home_trafic_text));
    textView.setText(getString(R.string.loading));
    textView.setEnabled(true); // Thanks to Romain Guy
    textView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right,
                int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            LayoutParams params = v.getLayoutParams();
            params.width = right - left;
            params.height = bottom - top;
            params.weight = 0;
            v.removeOnLayoutChangeListener(this);
            v.setLayoutParams(params);
        }
    });
}

如果你需要改变方向或类似的东西,请小心,但对我来说它工作得很好!

----针对API-11之前版本的编辑---

由于OnLayoutChangeListener仅存在于Api v11中,因此有一个解决方法(它可以工作,但我认为它不太好):

从你的活动中删除OnLayoutChangeListener

MyActivity.java:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.layout);

    TextView textView = ((TextView) findViewById(R.id.home_trafic_text));
    textView.setText(getString(R.string.loading));
    textView.setEnabled(true); // Thanks to Romain Guy
}

请在 ScrollingTextView 中添加一个 onSizeChanged 方法:
ScrollingTextView.java:
public class ScrollingTextView extends TextView {

    ...
    // Same code as before
    ...

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    LayoutParams params = (LayoutParams) getLayoutParams();
        params.width = w;
        params.height = h;
        params.weight = 0;
        setLayoutParams(params);
    }
}

我希望你能帮到您!


我失去了我的早晨,但找到了这个。太完美了! - leegor

4

只需要一个简单的修复..:) 不用太担心...只需将TextView的宽度设置为800dp或更高即可。这将解决重置问题。


你救了我一命。只需将TextView的宽度设置为特定数量的dp,而不是使用“wrap_content”。 - Binh Le

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接