2012-02-23 5 views
6

Ho una galleria personalizzata. La galleria rappresenta elementi che sono il layout della cornice. Ci sono un imageView e un textView sopra di esso.Scorrimento orizzontale automatico in TextView

Se il testo in textView è troppo lungo, è necessario scorrere automaticamente. È una riga di testo e deve essere fatta scorrere orizzontalmente.

ho trovato questo frammento di codice:

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"/> 

Funziona nel mio test app con un solo testo in vista di esso. Ma non funziona nella mia galleria. Notando che succede, il testo resta fermo.

Qualsiasi aiuto?

+0

mi sono imbattuto in questo comportamento una volta e, infine, risolto il problema chiamando .SetFocus() sul textView. Non era in una galleria quindi non sono sicuro che tu stia avendo lo stesso problema ma è una soluzione semplice quindi vale la pena provare! – ByteMe

risposta

1

Ho provato di tutto, e alla fine ho trovato questo. Questo funziona per me ... spero che questo ti possa aiutare un giorno. Saluti.

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, questa classe com.media_player.AndroidMediaPlayerActivity è mancante, puoi completare questa classe di errore? – exequielc

+0

AndroidMediaPlayerActivity contiene un campo statico pubblico che contiene la larghezza dello schermo del dispositivo. – Veljko

6

L'effetto di selezione su un TextView è progettato per funzionare solo quando la vista è a fuoco o selezionata. Il codice XML che hai provato a rendere lo TextView concentrato sempre. Sfortunatamente, dal momento che solo una vista può essere focalizzata in qualsiasi momento e dal momento che hai più viste nella galleria, questo approccio non funzionerà per te.

Il modo più semplice per ottenerlo in caso contrario è di selezionare sempre TextViews. Più TextViews può mantenere lo stato selezionato in una volta. La selezione è pensata per essere utilizzata per un elemento attivo di un AdapterView, ma funziona ancora al di fuori di uno. Innanzitutto, rimuovi gli attributi che modificano lo stato attivo dall'XML e quindi chiama lo TextView.setSelected(true) qualche volta dopo l'inizializzazione della visualizzazione, ad es. in Activity.onCreate(Bundle) (non esiste alcun attributo XML per questo). Se si forniscono le viste da un adattatore, è possibile chiamare TextView.setSelected(true) durante il metodo getView() dopo aver gonfiato la vista.

Here è un progetto di esempio che mostra un riquadro che funziona per più TextView e il comportamento all'interno di una Galleria.

+0

Puoi scrivermi cosa devo inserire nel file xml? TextView android: text = "Visualizza testo a riga singola che scorre automaticamente" android: SingleLine = "true" android: ellipsize = "tendone" android: marqueeRepeatLimit = "marquee_forever" android: scrollHorizontally = "true" android: layout_width = "wrap_content" android: layout_height = "wrap_content" /> Ho digitato questo, e in un metodo getView mettere setSelected (true) ma ancora non succede nulla. – Veljko

+0

Usando questi parametri, posso ottenere che il riquadro di testo di TextView funzioni in una Galleria a parte il primo elemento, che non scorre fino a quando non si passa a un altro elemento e quindi scorrono tutti automaticamente. È questo quello che vedi? Non so come risolverlo per una Gallery, ma questo approccio funziona bene per far sì che più TextView siano visualizzati come se fossero solo nel layout dell'attività. – antonyt

+0

Ho fatto quello che hai detto, ma nessuno degli elementi sta scorrendo ... rimangono immobili. :/Dammi un codice di esempio ... se puoi ... – Veljko

12

Prova questa classe TextView personalizzato:

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

e impostare i seguenti attributi XML:

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

Questo funziona in modo bello nei miei apps del dizionario in cui più voci possono avere bisogno di scorrimento automatico contemporaneamente da visualizzare contenuto completo.

0

Mi sono imbattuto in questo problema una volta e finalmente risolto il problema chiamando .setFocus() sul textView.

0

Ciao Hai tag nel file xml stesso. E usa anche la proprietà Scrollview di FOCUS_DOWN nel file java ... Spero che ti sia d'aiuto ...

0

Questo codice funziona correttamente per me.

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" 
       />