96

TextView でマーキー効果を使用したいのですが、TextView がフォーカスを取得したときにのみテキストがスクロールされます。私の場合はできないので、それは問題です。

私は使っている:

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

TextView に常にテキストをスクロールさせる方法はありますか? これが Android マーケット アプリで行われているのを見たことがあります。このアプリでは、フォーカスがなくてもアプリ名がタイトル バーでスクロールされますが、API ドキュメントでこれが言及されているのを見つけることができませんでした。

4

8 に答える 8

122

私はついに今日この問題に直面したのでhierarchyviewer、Androidマーケットアプリケーションに火をつけました。

アプリの詳細画面でタイトルを見ると、彼らは昔ながらのを使用していますTextView。そのプロパティを調べると、フォーカスされていない、フォーカスされていない、一般的に非常に普通であることがわかりました。ただし、選択済みとしてマークされているという事実があります。

1行後のコードで、動作させました:)

textView.setSelected(true);

Javadocの内容を考えると、これは理にかなっています。

ビューを選択することも、選択しないこともできます。選択はフォーカスと同じではないことに注意してください。ビューは通常、ListViewやGridViewなどのAdapterViewのコンテキストで選択されます。

つまり、リストビュー(マーケットアプリなど)でアイテムをスクロールすると、選択したテキストのスクロールが開始されます。また、この特定TextViewのものはフォーカス可能またはクリック可能ではないため、選択状態が失われることはありません。

残念ながら、私が知る限り、レイアウトXMLから選択した状態を事前に設定する方法はありません。
しかし、上記のワンライナーは私にとってはうまく機能します。

于 2010-09-13T13:06:04.057 に答える
76

これらのパラメータを TextView に入れるだけです。できます :)

    android:singleLine="true" 
    android:ellipsize="marquee"
    android:marqueeRepeatLimit ="marquee_forever"
    android:scrollHorizontally="true"
    android:focusable="true"
    android:focusableInTouchMode="true" 
于 2010-08-18T09:58:38.937 に答える
63

私は問題に直面しており、思いついた最短の解決策は、TextView から派生した新しいクラスを作成することです。クラスはonFocusChangedonWindowFocusChangedisFocusedの 3 つのメソッドをオーバーライドして、TextView をすべてフォーカスする必要があります。

@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;
}
于 2010-03-24T01:45:48.823 に答える
13

TranslateAnimation指定された量だけビューを一方向に「引っ張る」ことによって機能します。この「引っ張り」を開始する場所と終了する場所を設定できます。

TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);

fromXDelta は、X 軸の移動の開始位置のオフセットを設定します。

fromXDelta = 0 //no offset. 
fromXDelta = 300 //the movement starts at 300px to the right.
fromXDelta = -300 //the movement starts at 300px to the left

toXDelta は、X 軸の移動のオフセット終了位置を定義します。

toXDelta = 0 //no offset. 
toXDelta = 300 //the movement ends at 300px to the right.
toXDelta = -300 //the movement ends at 300px to the left.

テキストの幅が fromXDelta と toXDelta の差のモジュールよりも大きい場合、テキストは画面内で完全に完全に移動することができません。


画面サイズが 320x240 ピクセルであるとします。幅 700px のテキストを含む TextView があり、フレーズの終わりが見えるようにテキストを「引っ張る」アニメーションを作成したいと考えています。

                                       (screen)
                             +---------------------------+
                             |<----------320px---------->|
                             |                           |
                             |+---------------------------<<<< X px >>>>
               movement<-----|| some TextView with text that goes out...
                             |+---------------------------
                             |  unconstrained size 700px |
                             |                           |
                             |                           |
                             +---------------------------+


                             +---------------------------+
                             |                           |
                             |                           |
               <<<< X px >>>>---------------------------+|
movement<----- some TextView with text that goes out... ||
                             ---------------------------+|
                             |                           |
                             |                           |
                             |                           |
                             +---------------------------+

まずfromXDelta = 0、動きに開始オフセットがないように設定します。次に、toXDelta 値を計算する必要があります。目的の効果を得るには、テキストが画面の外に広がるのとまったく同じ px だけテキストを「引き出す」必要があります。(スキームでは <<<< X px >>>> で表されます) テキストの幅が 700 で、表示領域が 320px (画面幅) であるため、次のように設定します。

tXDelta = 700 - 320 = 380

また、画面の幅とテキストの幅はどのように計算するのでしょうか?


コード

Zarah スニペットを出発点として取り上げます。

    /**
     * @param view The Textview or any other view we wish to apply the movement
     * @param margin A margin to take into the calculation (since the view
     *               might have any siblings in the same "row")
     *
     **/
public static Animation scrollingText(View view, float margin){

    Context context = view.getContext(); //gets the context of the view

            // measures the unconstrained size of the view
            // before it is drawn in the layout
    view.measure(View.MeasureSpec.UNSPECIFIED, 
                         View.MeasureSpec.UNSPECIFIED); 

            // takes the unconstrained wisth of the view
    float width = view.getMeasuredWidth();

            // gets the screen width
    float screenWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();


            // perfrms the calculation
    float toXDelta = width - (screenWidth - margin);

            // sets toXDelta to 0 if the text width is smaller that the screen size
    if (toXDelta < 0) {toXDelta = 0; } else { toXDelta = 0 - toXDelta;}

            // Animation parameters
    Animation mAnimation = new TranslateAnimation(0, toXDelta, 0, 0);
    mAnimation.setDuration(15000); 
    mAnimation.setRepeatMode(Animation.RESTART);
    mAnimation.setRepeatCount(Animation.INFINITE);

    return mAnimation;
}

これを実行する簡単な方法があるかもしれませんが、これは考えられるすべてのビューで機能し、再利用可能です。textView の enabled/onFocus 機能を壊さずに ListView で TextView をアニメーション化する場合に特に便利です。ビューがフォーカスされていない場合でも、継続的にスクロールします。

于 2010-12-09T10:48:29.770 に答える
12

まだ答えが必要かどうかはわかりませんが、これを行う簡単な方法を見つけました。

アニメーションを次のように設定します。

Animation mAnimation = new TranslateAnimation(START_POS_X, END_POS_X, 
                START_POS_Y, END_POS_Y);
mAnimation.setDuration(TICKER_DURATION); 
mAnimation.setRepeatMode(Animation.RESTART);
mAnimation.setRepeatCount(Animation.INFINITE);

START_POS_XEND_POS_XSTART_POS_YおよびEND_POS_Yfloat値であり、は他の定数で宣言されTICKER_DURATIONたI です。int

次に、このアニメーションを TextView に適用できます。

TextView tickerText = (TextView) findViewById(R.id.ticker);
tickerText.setAnimation(mAnimation);

以上です。:)

私のアニメーションは、画面外の右側 (300f) で始まり、画面外の左側 (-300f) で終了し、持続時間は 15 秒 (15000) です。

于 2010-08-12T07:13:18.723 に答える
5

マーキー テキスト項目を含む ListView の次のコードを作成しました。これは、上記の setSelected ソリューションに基づいています。基本的に、ArrayAdapter クラスを拡張し、getView メソッドをオーバーライドして TextView を選択してから返します。

    // Create an ArrayAdapter which selects its TextViews before returning      
    // them. This would enable marqueeing while still making the list item
    // clickable.
    class SelectingAdapter extends ArrayAdapter<LibraryItem>
    {
        public
        SelectingAdapter(
            Context context, 
            int resource, 
            int textViewResourceId, 
            LibraryItem[] objects
        )
        {
            super(context, resource, textViewResourceId, objects);
        }

        @Override
        public
        View getView(int position, View convertView, ViewGroup parent)
        {
            View view = super.getView(position, convertView, parent);
            TextView textview = (TextView) view.findViewById(
                R.id.textview_playlist_item_title
            );
            textview.setSelected(true);
            textview.setEnabled(true);
            textview.setFocusable(false);
            textview.setTextColor(0xffffffff);
            return view;

        }
    }
于 2012-01-19T10:09:21.843 に答える