常にellipsize =「マーキー」を作るにスクロールする方法はありますか?

StackOverflow https://stackoverflow.com/questions/1827751

  •  11-09-2019
  •  | 
  •  

質問

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

私が使用しています:

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

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

役に立ちましたか?

解決

私は、問題と、私はTextViewのから派生した新しいクラスを作成することですが出ている最短のソリューションに直面してきました。 クラスは、TextViewにはすべて集中させるために3つの方法onFocusChanged のを、onWindowFocusChanged をisFocused ののをオーバーライドする必要があります。

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

他のヒント

私は最終的に、今日、この問題に対して、上がってきたので、 hierarchyviewer <を解雇しました/> Androidマーケットのアプリでます。

アプリの詳細画面上のタイトルを見て、彼らは昔ながらのTextViewを使用しています。 を選択したとして、それがマークされたという事実を除いて

はは集中することができませんでしたし、一般的に非常に普通でした。 >

1行のコード、後、私はそれが働いていた:)

textView.setSelected(true);

これは理にかなって、与えられたものを Javadocが言います

  

ビューは、選択されたか否かをすることができます。選択が焦点と同じではないことに注意してください。ビューは、典型的には、リストビューまたはGridViewのようなAdapterViewの関連で選択される。

すなわち。あなたは(マーケットアプリのように)リストビューにアイテムの上にスクロールすると、だけにして、が今、選択されたのテキストのスクロールを開始しません。この特定のTextViewがフォーカス可能かクリックできないので、それはその選択状態を失うことはありません。

残念ながら、私の知る限りでは、レイアウトのXMLから選択された状態をあらかじめ設定する方法はありません。
しかし、上記のワンライナーは、私のために正常に動作します。

ちょうどあなたのTextViewにこれらのパラメータを置きます。それは動作します:)

    android:singleLine="true" 
    android:ellipsize="marquee"
    android:marqueeRepeatLimit ="marquee_forever"
    android:scrollHorizontally="true"
    android:focusable="true"
    android:focusableInTouchMode="true" 

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の差のモジュールは、テキストはば完全とcompeltely画面内に移動することはできないということも大きい場合ます。

<時間>

私たちの画面サイズは320×240 PXSであると仮定しましょう。私たちは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値を把握する必要があります。所望の効果を達成するために、我々は、テキストが画面の外にまたがるまったく同じピクセルを「プル」する必要があります。私達のテキスト700の幅を有しているので(スキーム中<<<< X PXの>>>>で表される)、及び可視領域が320ピクセル(画面幅)であり、我々が設定します。

tXDelta = 700 - 320 = 380

そして、どのように我々は、画面の幅とテキストの幅を把握しますか。

<時間>

コード

の出発点としてツアラースニペットを取る

    /**
     * @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の有効/のonFocus能力を壊すことなく、リストビュー内のTextViewをアニメーション化する場合は、特別に便利です。また、ビューがフォーカスされていない場合でも、継続的にスクロールします。

あなたはまだ答えを必要とする場合、私は知りませんが、私はこれを行うための簡単な方法を見つけます。

そのようなあなたのアニメーションを設定します:

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_Xは、私は他の定数を宣言しEND_POS_Xいる間に

START_POS_YEND_POS_YfloatTICKER_DURATIONは、int値です。

そして、あなたが今、あなたのTextViewにこのアニメーションを適用することができます:

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

そして、それはそれです。 :)

私のアニメーションは、オフスクリーン(300F)の右側に開始し、15秒の持続時間(15000)と、オフスクリーン(-300f)左側に終了する。

私はマーキーテキスト項目と、リストビューのために、次のコードを書きました。なお、上述するsetSelected溶液に基づくものです。基本的に、私はArrayAdapterクラスを拡張し、それを返す前のTextViewを選択するために、GetViewメソッドをオーバーライドしています:

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

        }
    }

これは、私はかなり頻繁にこのことを思い出して苦労するので、私はここに便利な答えを投稿できると思っていたので、私のGoogle検索のトップにポップアップする答えがあります。 とにかく、これは私のために働き、XML属性を必要としonFocusChangeListenerます。

//XML
        <TextView
            android:id="@+id/blank_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:layout_gravity="center_horizontal|center_vertical"
            android:background="#a4868585"
            android:textColor="#fff"
            android:textSize="15sp"
            android:singleLine="true"
            android:lines="1"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit ="marquee_forever"
            android:scrollHorizontally="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            tools:ignore="Deprecated" />

//JAVA
    titleText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                titleText.setSelected(true);
            }
        }
    });

// XML

 <TextView
            android:id="@+id/tvMarque"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="marquee"
            android:layout_gravity="center_horizontal"
            android:fadingEdge="horizontal"
            android:marqueeRepeatLimit="marquee_forever"
            android:scrollHorizontally="true"
            android:padding="5dp"
            android:textSize="16sp"
            android:text=""
            android:textColor="@color/colorSyncText"
            android:visibility="visible" />

// Javaでは

        mtvMarque.setEllipsize(TextUtils.TruncateAt.MARQUEE);
        mtvMarque.setSelected(true);
        mtvMarque.setSingleLine(true);
scroll top