我想在TextView上使用选取框效果,但只有在TextView获得焦点时才会滚动文本。这是一个问题,因为在我的情况下,它不能。
我正在使用:
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
有没有办法让TextView始终滚动文本?我已经看到这是在Android Market应用程序中完成的,其中应用程序名称将在标题栏中滚动,即使它没有获得焦点,但我无法在API文档中找到这一点。
答案 0 :(得分:116)
我今天终于遇到了这个问题,因此在Android Market应用程序中激起了hierarchyviewer
。
在应用的详细信息屏幕上查看标题,他们使用普通的TextView
。检查它的属性表明它没有集中注意力,无法集中注意力并且通常非常普通 - 除了它被标记为选择这一事实。
后面的一行代码,我让它工作了:)
textView.setSelected(true);
考虑到the Javadoc says:
,这是有道理的可以选择或不选择视图。请注意,选择与焦点不同。视图通常在AdapterView(如ListView或GridView)的上下文中选择。
即。当您在列表视图中滚动项目时(例如在市场应用程序中),只有那时现在选择的文本才会开始滚动。由于此特定TextView
不可聚焦或可点击,因此它永远不会失去其选择状态。
不幸的是,据我所知,没有办法从布局XML中预先设置所选状态 但上面的单线程对我来说很好。
答案 1 :(得分:72)
只需将这些参数放入TextView即可。它有效:)
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
答案 2 :(得分:61)
我一直面临着这个问题,我提出的最简单的解决方案是创建一个从TextView派生的新类。 该类应覆盖三种方法 onFocusChanged , onWindowFocusChanged 和 isFocused ,以使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;
}
答案 3 :(得分: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像素。我们有一个TextView,其文本宽度为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。 (在该方案中由&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&nbsp;
tXDelta = 700 - 320 = 380
我们如何计算屏幕宽度和文字宽度?
以Zarah Snippet为出发点:
/**
* @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;
}
可能有更简单的方法来执行此操作,但这适用于您能够想到并且可重复使用的每个视图。如果您想要在ListView中为TextView设置动画而不破坏textView的enabled / onFocus功能,这将非常有用。即使视图没有聚焦,它也会连续滚动。
答案 4 :(得分: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_X
,END_POS_X
,START_POS_Y
和END_POS_Y
为float
个值,而TICKER_DURATION
是我声明的int
我的其他常数。
然后,您现在可以将此动画应用于TextView:
TextView tickerText = (TextView) findViewById(R.id.ticker);
tickerText.setAnimation(mAnimation);
就是这样。 :)
我的动画在屏幕右侧(300f)开始,在屏幕左侧(-300f)结束,持续时间为15s(15000)。
答案 5 :(得分: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;
}
}
答案 6 :(得分:2)
这是我谷歌搜索顶部弹出的答案,所以我想我可以在这里发布一个有用的答案,因为我很难经常记住这个。 无论如何,这对我有用,需要XML属性和A 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);
}
}
});
答案 7 :(得分:1)
// xml
ng build --prod && sw-precache --root=dist --config=precache-config.js
//在Java中
<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" />