문제

TextView에서 Marquee Effect를 사용하고 싶지만 TextView가 초점을 맞출 때만 텍스트가 스크롤됩니다. 내 경우에는 할 수 없기 때문에 그것은 문제입니다.

나는 사용 중입니다 :

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

TextView가 항상 텍스트를 스크롤하는 방법이 있습니까? 이 작업이 Android Market 앱에서 수행되는 것을 보았습니다. Android Market 앱에서 앱 이름이 초점을 맞추지 않더라도 제목 표시 줄에서 스크롤하는 것을 보았지만 API 문서에서 언급 될 수 없었습니다.

도움이 되었습니까?

해결책

나는 문제에 직면 해 왔으며 내가 생각해 낸 가장 짧은 해결책은 TextView에서 파생 된 새로운 수업을 만드는 것입니다. 수업은 세 가지 방법을 무시해야합니다 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 안드로이드 시장 응용 프로그램.

앱의 디테일 화면에서 제목을 보면 평원을 사용합니다. TextView. 그 속성을 검토하면 초점이 맞지 않는 것으로 나타났습니다. 할 수 없었습니다 초점을 맞추고 일반적으로 매우 평범했습니다. 선택된.

나중에 한 줄의 코드 라인과 나는 그것을 작동시켰다 :)

textView.setSelected(true);

이것은 무엇을 의미합니다 Javadoc은 말한다:

보기가 선택 될 수 있습니다. 선택은 초점과 동일하지 않습니다. 보기는 일반적으로 ListView 또는 GridView와 같은 어댑터의 맥락에서 선택됩니다.

즉, 마켓 앱에서와 같이 목록보기에서 항목을 스크롤하면 현재 선택 텍스트 시작 스크롤링. 그리고이 특별한 이후 TextView 집중할 수 없거나 클릭 할 수 없으므로 선택 상태를 잃지 않습니다.

불행히도, 내가 아는 한 레이아웃 XML에서 선택한 상태를 사전 설정할 방법은 없습니다.
그러나 위의 1 라이너는 나에게 잘 작동합니다.

이 매개 변수를 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의 차이의 모듈보다 더 큰 경우 텍스트는 화면 내에서 전체적으로 이동할 수 없으며 화면 내에서 이동할 수 없습니다.


예시

화면 크기가 320x240 pxs라고 가정 해 봅시다. 너비가 700px가있는 텍스트가있는 텍스트 뷰가 있으며 문구의 끝을 볼 수 있도록 텍스트를 "당기는"애니메이션을 만들고자합니다.

                                       (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의 활성화 된/onfocus 능력을 깨뜨리지 않고 ListView에서 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_Y 그리고 END_POS_Y ~이다 floatTICKER_DURATION 이다 int 나는 다른 상수로 선언했다.

그런 다음이 애니메이션을 텍스트 뷰에 적용 할 수 있습니다.

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

그리고 그게 다야. :)

내 애니메이션은 오른쪽 오프 스크린 (300F)에서 시작하여 왼쪽 오프 스크린 (-300F)에서 15 초 (15000)로 끝납니다.

Marquee Text 항목이 포함 된 ListView에 대한 다음 코드를 작성했습니다. 위에서 설명한 SetSelected 솔루션을 기반으로합니다. 기본적으로 Arrayadapter 클래스를 확장하고 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);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top