TextView中的自动水平滚动

时间:2012-02-23 20:12:05

标签: android scroll textview gallery

我有自定义图库。 图库表示框架布局的项目。 它上面有一个imageView和textView。

如果textView中的文本太长,我需要它自动滚动。 它是一行文本,需要水平滚动。

我找到了这段代码:

TextView
    android:text="Single-line text view that scrolls automatically"       
    android:singleLine="true" 
    android:ellipsize="marquee"
    android:marqueeRepeatLimit ="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true" 
    android:scrollHorizontally="true"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/>   

它适用于我的测试应用程序,其中只有一个文本视图。 但它在我的画廊中不起作用。注意到,文字只是保持不动。

任何帮助?

9 个答案:

答案 0 :(得分:14)

尝试使用此自定义TextView类:

public class AutoScrollingTextView extends TextView {
    public AutoScrollingTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

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

    public AutoScrollingTextView(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;
    }
}

并设置以下XML属性:

android:scrollHorizontally="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"

这在我的词典应用程序中非常有效,其中多个条目可能需要同时自动滚动以显示完整内容。

答案 1 :(得分:6)

TextView上的选取框效果仅适用于聚焦或选择视图时的效果。您尝试使用的XML代码始终关注TextView。不幸的是,由于任何时候都只能关注一个视图,并且由于您在图库中有多个视图,因此这种方法对您无效。

实现此目的的最简单方法是始终选择TextViews。多个TextViews可以一次保持所选状态。选择意味着用于AdapterView的活动元素,但仍然可以在一个外部工作。首先,从XML中删除修改焦点的属性,然后在初始化视图后的某个时间调用TextView.setSelected(true),例如,在Activity.onCreate(Bundle)中(没有XML属性)。如果您要从适配器提供视图,则可以在向视图膨胀后在TextView.setSelected(true)方法期间调用getView()

Here是一个示例项目,显示了多个TextView的marquee工作以及Gallery中的行为。

答案 2 :(得分:1)

尝试使用ViewPager而不是图库。这在Android支持包中可用。 http://android-developers.blogspot.in/2011/08/horizontal-view-swiping-with-viewpager.html

答案 3 :(得分:1)

我已经尝试了一切,最后想出了这个。这对我有用......希望有一天这会对你有所帮助。欢呼声。

 package com.gui.custom_views;

 import android.content.Context;
 import android.graphics.Paint;
 import android.graphics.Typeface;
 import android.text.TextUtils; 
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.Animation;
 import android.view.animation.LinearInterpolator;
 import android.view.animation.TranslateAnimation;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 import android.widget.TextView;

 import com.media_player.AndroidMediaPlayerActivity;

 /**
 * Custom Automatic Scrollable Text View
 * 
 * @author Veljko Ilkic
 * 
 */
 public class AutomaticScrollTextView extends LinearLayout {

// Context of application
Context context;
// TextView
private TextView mTextField1;

// Horizontal scroll
private ScrollView mScrollView1;

// Animation on start
private Animation mMoveTextOnStart = null;
// Out animation
private Animation mMoveText1TextOut = null;

// Duration of animation on start
private int durationStart;
// Duration of animation
private int duration;

// Pain for drawing text
private Paint mPaint;

// Text current width
private float mText1TextWidth;

/**
 * Control the speed. The lower this value, the faster it will scroll.
 */
public static final int MS_PER_PX = 80;

/**
 * Control the pause between the animations. Also, after starting this
 * activity.
 */
public static final int PAUSE_BETWEEN_ANIMATIONS = 0;
private boolean mCancelled = false;

// Layout width
private int mWidth;
// Animation thread
private Runnable mAnimation1StartRunnable;

public AutomaticScrollTextView(Context context) {
    super(context);
    init(context);
    this.context = context;
}

public AutomaticScrollTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
    this.context = context;
}

private void init(Context context) {
    initView(context);

    // init helper
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(1);
    mPaint.setStrokeCap(Paint.Cap.ROUND);

}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    mWidth = getMeasuredWidth();

    // Calculate
    prepare();

    // Setup
    setupText1Marquee();

}

@Override
public void setOnClickListener(OnClickListener l) {
    super.setOnClickListener(l);

    mTextField1.setOnClickListener(l);
}

// Method to finally start the marquee.
public void startMarquee() {
    prepare();
    prepareTextFields();

    startTextField1Animation();

    mCancelled = false;
}

private void startTextField1Animation() {
    mAnimation1StartRunnable = new Runnable() {
        public void run() {
            mTextField1.setVisibility(View.VISIBLE);
            mTextField1.startAnimation(mMoveTextOnStart);
        }
    };
    postDelayed(mAnimation1StartRunnable, PAUSE_BETWEEN_ANIMATIONS);
}

public void reset() {

    mCancelled = true;

    if (mAnimation1StartRunnable != null) {
        removeCallbacks(mAnimation1StartRunnable);
    }

    mTextField1.clearAnimation();

    prepareTextFields();

    mMoveTextOnStart.reset();
    mMoveText1TextOut.reset();

    mScrollView1.removeView(mTextField1);
    mScrollView1.addView(mTextField1);

    mTextField1.setEllipsize(TextUtils.TruncateAt.END);

    invalidate();
}

public void prepareTextFields() {
    mTextField1.setEllipsize(TextUtils.TruncateAt.END);
    mTextField1.setVisibility(View.INVISIBLE);
    expandTextView(mTextField1);
}

private void setupText1Marquee() {

    // Calculate duration of animations
    durationStart = (int) ((mWidth + mText1TextWidth) * MS_PER_PX);
    duration = (int) (2 * mWidth * MS_PER_PX);

    // On start animation
    mMoveTextOnStart = new TranslateAnimation(0, -mWidth - mText1TextWidth,
            0, 0);

    mMoveTextOnStart.setDuration(durationStart);
    mMoveTextOnStart.setInterpolator(new LinearInterpolator());
    mMoveTextOnStart.setFillAfter(true);

    // Main scrolling animation
    mMoveText1TextOut = new TranslateAnimation(mWidth, -mWidth
            - mText1TextWidth, 0, 0);

    mMoveText1TextOut.setDuration(duration);
    mMoveText1TextOut.setInterpolator(new LinearInterpolator());
    mMoveText1TextOut.setFillAfter(true);
    mMoveText1TextOut.setRepeatCount(Animation.INFINITE);

    // Animation listeners
    mMoveTextOnStart
            .setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    invalidate();
                    mTextField1.invalidate();

                }

                public void onAnimationEnd(Animation animation) {

                    if (mCancelled) {
                        return;
                    }

                    mTextField1.startAnimation(mMoveText1TextOut);

                }

                public void onAnimationRepeat(Animation animation) {
                    invalidate();
                    mTextField1.invalidate();
                }
            });

    mMoveText1TextOut
            .setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    invalidate();
                    mTextField1.invalidate();

                }

                public void onAnimationEnd(Animation animation) {

                    if (mCancelled) {
                        return;
                    }

                }

                public void onAnimationRepeat(Animation animation) {
                    invalidate();
                    mTextField1.invalidate();
                }
            });

}

private void prepare() {

    // Measure
    mPaint.setTextSize(mTextField1.getTextSize());
    mPaint.setTypeface(mTextField1.getTypeface());
    mText1TextWidth = mPaint.measureText(mTextField1.getText().toString());

    setupText1Marquee();

}

private void initView(Context context) {
    setOrientation(LinearLayout.VERTICAL);
    setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.FILL_PARENT, Gravity.LEFT));
    setPadding(0, 0, 0, 0);

    // Scroll View 1
    LayoutParams sv1lp = new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT);
    sv1lp.gravity = Gravity.CENTER_HORIZONTAL;
    mScrollView1 = new ScrollView(context);

    // Scroll View 1 - Text Field
    mTextField1 = new TextView(context);
    mTextField1.setSingleLine(true);
    mTextField1.setEllipsize(TextUtils.TruncateAt.END);
    mTextField1.setTypeface(null, Typeface.BOLD);

    mScrollView1.addView(mTextField1, new ScrollView.LayoutParams(
            mTextField1.getWidth(), LayoutParams.WRAP_CONTENT));

    addView(mScrollView1, sv1lp);
}

public void setText1(String text) {

    String temp = "";
    if (text.length() < 10) {
        temp = "         " + text + "         ";
    } else {
        temp = text;
    }
    mTextField1.setText(temp);

}

public void setTextSize1(int textSize) {
    mTextField1.setTextSize(textSize);
}

public void setTextColor1(int textColor) {

    mTextField1.setTextColor(textColor);
}

private void expandTextView(TextView textView) {
    ViewGroup.LayoutParams lp = textView.getLayoutParams();
    lp.width = AndroidMediaPlayerActivity.getScreenWidth();
    textView.setLayoutParams(lp);
}
}

答案 4 :(得分:0)

我遇到过这个问题,最后通过在textView上调用.setFocus()来解决问题。

答案 5 :(得分:0)

您好,您在xml文件中有Tag。并且还在java文件中使用FOCUS_DOWN的Scrollview属性...希望它对你有帮助...

答案 6 :(得分:0)

此代码适用于我。

滚动视图=(滚动型)findViewById(R.id.scrollview1);         tb2.setTextSize(30);

    tb2.setMovementMethod(new ScrollingMovementMethod());
    scrollview.post(new Runnable() { 
    public void run() { 
        scrollview.fullScroll(View.FOCUS_DOWN);  
        }
    });

答案 7 :(得分:0)

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

 <com.test.autoscroll.ScrollingTextView
                android:id="@+id/actionbar_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="10dip"
                android:paddingRight="10dip"
                android:textSize="16dip"
                android:textStyle="bold"
                android:lines="1"
                android:scrollHorizontally="true"
                android:ellipsize="marquee"
                 android:text="autoscrollable textview without focus to textview...working...."
                android:marqueeRepeatLimit="marquee_forever"
                />

答案 8 :(得分:0)

将此代码添加到自己的代码中

findViewById(R.id.yourtextviewid).setSelected(true);

也许您的问题已解决。