2012-02-23 72 views
6

我有自定义图库。 图库代表框架布局的项目。 上面有一个imageView和textView。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"/> 

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

任何帮助?

+0

我碰到这种行为来过一次,最后通过在TextView的调用.SETFOCUS()解决了这一问题。这不是在画廊,所以我不知道你是否有同样的问题,但它是一个简单的修复,所以这是值得一试! – ByteMe 2012-03-16 00:54:10

回答

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); 
} 
} 
+0

Veljko,这个类com.media_player.AndroidMediaPlayerActivity失踪了,你能完成这个mising类吗? – exequielc 2012-12-12 15:21:28

+0

AndroidMediaPlayerActivity包含公共静态字段,其中包含设备的屏幕宽度。 – Veljko 2013-06-21 09:57:26

6

TextView上的选取框效果仅用于在焦点或选择视图时工作。您试图使TextView始终处于关注状态的XML代码。不幸的是,由于只有一个视图可以随时关注,并且由于您在图库中有多个视图,因此这种方法对您不起作用。

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

Here是一个示例项目,显示了适用于多个TextView的选框以及一个库中的行为。

+0

你可以写我什么我应该放入XML文件? 的TextView 机器人:文本= “单行文本认为自动滚动” 机器人:SINGLELINE = “真” 机器人:ellipsize = “字幕” 机器人:marqueeRepeatLimit = “marquee_forever” 机器人:scrollHorizo​​ntally = “真” android:layout_width =“wrap_content” android:layout_height =“wrap_content”/> 我输入了这个,并在一个getView方法把setSelected(true)但仍然没有任何反应。 – Veljko 2012-03-11 08:26:02

+0

使用这些参数,我可以让TextView选框在第一个元素旁边的Gallery中工作,除非您转到另一个元素,否则它们不会滚动,然后它们都会自动滚动。这是你看到的吗?我不知道如何修复它的一个图库,但是这种方法在获取多个TextView的时候可以正常工作,只要它们在您的活动布局中。 – antonyt 2012-03-11 10:20:22

+0

我已经完成了你所说的,但没有任何元素正在滚动......他们只是保持不动。 :/给我一些示例代码...如果你可以... – Veljko 2012-03-11 13:10:14

12

试试这个定制的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" 

这精美的作品在我的字典应用程序在多个条目可能需要自动滚动同时显示完整的内容。

0

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

0

嗨你有在XML文件本身的标记。并在java文件中使用FOCUS_DOWN的Scrollview属性...希望它有助于你...

0

此代码适用于我。

scrollview =(ScrollView)findViewById(R.id.scrollview1); tb2。setTextSize(30);

tb2.setMovementMethod(new ScrollingMovementMethod()); 
    scrollview.post(new Runnable() { 
    public void run() { 
     scrollview.fullScroll(View.FOCUS_DOWN); 
     } 
    }); 
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" 
       />