代码之家  ›  专栏  ›  技术社区  ›  mxk

有没有办法让Ellipsize=“Marquee”始终滚动?

  •  88
  • mxk  · 技术社区  · 15 年前

    我想在文本视图上使用字幕效果,但只有当文本视图获得焦点时,文本才会滚动。这是个问题,因为在我的情况下,它不能。

    我正在使用:

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

    有没有办法让textView始终滚动其文本?我在Android Market应用程序中看到过这种情况,应用程序名称将在标题栏中滚动,即使它没有获得焦点,但我在API文档中找不到这一点。

    8 回复  |  直到 6 年前
        1
  •  61
  •   Andrew Wyld    12 年前

    我一直面临着这个问题,我想到的最短的解决方案是创建一个从textview派生的新类。 类应重写三个方法 聚焦改变 , 在WindowFocusChanged上 聚焦的 使文本视图全部集中。

    @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;
    }
    
        2
  •  115
  •   Christopher Orr    14 年前

    我今天终于解决了这个问题,所以很兴奋 hierarchyviewer 在Android市场应用程序上。

    在应用程序的详细屏幕上,他们使用一个简单的 TextView . 检查它的性能表明它没有聚焦, 不能 注意力集中,一般都很普通——除了它被标记为 挑选出来的 .

    一行代码之后,我让它工作了:)

    textView.setSelected(true);
    

    这是有道理的,因为 the Javadoc says :

    是否可以选择视图。请注意,选择与焦点不同。视图通常是在adapterview的上下文中选择的,如listview或gridview。

    也就是说,当您在列表视图中滚动某个项目(如在Market应用程序中)时,只有这样 现在选择 文本开始滚动。因为这个特别的 文本框 不可聚焦或不可点击,它将永远不会失去选择状态。

    不幸的是,据我所知,无法从布局XML预先设置所选状态。
    但是上面的那条线对我来说很好。

        3
  •  72
  •   Paresh Mayani jeet    12 年前

    只需将这些参数放入文本视图。它的工作原理是:

        android:singleLine="true" 
        android:ellipsize="marquee"
        android:marqueeRepeatLimit ="marquee_forever"
        android:scrollHorizontally="true"
        android:focusable="true"
        android:focusableInTouchMode="true" 
    
        4
  •  13
  •   Tivie    12 年前

    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和toxidelta之间的差异模块,则文本将无法在屏幕内完全和强制移动。


    例子

    假设我们的屏幕大小是320x240像素。我们有一个文本视图,它的文本宽度为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 这样移动就没有起始偏移。现在我们需要计算toxydelta值。为了达到预期的效果,我们需要将文本“拉”出与它在屏幕上所跨越的像素完全相同的像素。(方案中以<<<<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的已启用/未聚焦功能的情况下,在listview中对textview进行动画处理,则特别有用。即使视图没有聚焦,它也会连续滚动。

        5
  •  12
  •   Zarah    14 年前

    我不知道你是否还需要答案,但我找到了一个简单的方法。

    像这样设置动画:

    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 float 价值观 TICKER_DURATION 是一个 int 我用其他常量声明。

    然后,您现在可以将此动画应用于文本视图:

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

    就这样。:)

    我的动画开始于屏幕右侧(300F),结束于屏幕左侧(300F),持续时间为15秒(15000)。

        6
  •  5
  •   smichak    13 年前

    我为一个带有字幕文本项的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;
    
            }
        }
    
        7
  •  2
  •   Thunderstick    8 年前

    这是出现在我的谷歌搜索顶部的答案,所以我想我可以在这里发布一个有用的答案,因为我很难经常记住这一点。 无论如何,这对我很有效,需要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);
                }
            }
        });
    
        8
  •  0
  •   Soni Kumar    6 年前

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

    在爪哇

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