Android按钮文本垂直滚动
我正在开发一个android应用程序,在一个屏幕上我有10个方形按钮。某些按钮上的文本太长,无法显示,因此目前仅显示部分内容。我想做的是让按钮的文本在按钮不对焦时自动垂直滚动(在按钮内)。因此,屏幕将加载,文本将无限滚动。每次到达末尾时,它都应该从文本的开头开始,然后再次向下滚动。我知道有一个选框属性,这可以水平实现,但我需要垂直。我研究了scrollTo方法,但它会立即滚动到底部。我会发布一些代码,但我拥有的都是其他SO发布的代码。任何帮助都将不胜感激 @brokenstar提供了一个真正帮助我的链接。为了满足我的特殊需求,我不得不做一些修改,所以这里是修改后的代码Android按钮文本垂直滚动,android,button,scroll,Android,Button,Scroll,我正在开发一个android应用程序,在一个屏幕上我有10个方形按钮。某些按钮上的文本太长,无法显示,因此目前仅显示部分内容。我想做的是让按钮的文本在按钮不对焦时自动垂直滚动(在按钮内)。因此,屏幕将加载,文本将无限滚动。每次到达末尾时,它都应该从文本的开头开始,然后再次向下滚动。我知道有一个选框属性,这可以水平实现,但我需要垂直。我研究了scrollTo方法,但它会立即滚动到底部。我会发布一些代码,但我拥有的都是其他SO发布的代码。任何帮助都将不胜感激 @brokenstar提供了一个真正帮助
public class SquareButtonVScrolling extends SquareButton {
private boolean stop;
private boolean isNotDrawn = true;
private final Activity activity;
private long duration;
private int pixelYOffSet;
public SquareButtonVScrolling(Context context, AttributeSet attrs) {
super(context, attrs);
this.activity = (Activity) context;
}
public SquareButtonVScrolling(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.activity = (Activity) context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = View.MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, width);
}
public void init() {
// If there are more lines than can be displayed startMarquee, otherwise don't do anything
if ((SquareButtonVScrolling.this).getLineCount() > (SquareButtonVScrolling.this).getHeight() / (SquareButtonVScrolling.this).getLineHeight()) {
setDuration(65l);
setPixelYOffSet(1);
stop = false;
startMarquee();
}
}
/**
* @return Returns the (long) duration in milliseconds between calls to the
* next scrollBy(0, pixelYOffSet).
*/
public long getDuration() {
return duration;
}
/**
* @param duration
* Sets the (long) duration in milliseconds between calls to the
* next scrollBy(0, pixelYOffSet). Defaults to 65L if value is
* less than or equal to 0.
*/
public void setDuration(long duration) {
if (duration <= 0) {
this.duration = 65l;
} else {
this.duration = duration;
}
}
/**
* @return Returns the (int) amount of Y pixels to scroll by.
*/
public int getPixelYOffSet() {
return pixelYOffSet;
}
/**
* @param pixelYOffSet
* Sets the (int) amount of Y pixels to scroll by. Defaults to 1
* if value is less.
*/
public void setPixelYOffSet(int pixelYOffSet) {
if (pixelYOffSet < 1) {
this.pixelYOffSet = 1;
} else {
this.pixelYOffSet = pixelYOffSet;
}
}
/**
* Starts the marquee
*/
private void startMarquee() {
new AutoScrollSquareButton().executeOnExecutor(Utils.CUSTOM_THREAD_POOL_EXECUTOR);
}
/**
* Stop the marquee.
*/
public void stopMarquee() {
stop = true;
}
private class AutoScrollSquareButton extends AsyncTask<Void, Void, Void> {
private int pixelCount;
@Override
protected Void doInBackground(Void... params) {
// Check to see if the VMSB has been drawn to get proper sizing.
while (squareButtonNotDrawn()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (!stop) {
// Sleep duration amount between scrollBy pixelYOffSet
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// if VMSB has reached or exceeded the last
// Y pixel scroll back to top
if ((SquareButtonVScrolling.this).getScrollY() >= pixelCount) {
(SquareButtonVScrolling.this).scrollTo(0, 0);
} else { // Otherwise scroll by the pixelYOffSet
(SquareButtonVScrolling.this).scrollBy(0, pixelYOffSet);
}
(SquareButtonVScrolling.this).invalidate();
}
});
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
private boolean squareButtonNotDrawn() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// Checks to see if VMSB has been drawn.
if ((SquareButtonVScrolling.this).isShown()) {
// Calculate the total pixel height that needs to be scrolled.
// May need additional calculations if there is additional padding.
pixelCount = (SquareButtonVScrolling.this).getLineHeight() * (SquareButtonVScrolling.this).getLineCount();
isNotDrawn = false;
}
}
});
return isNotDrawn;
}
}
20毫秒的小延迟就足够了。另外,因为我有多达30个垂直自动滚动按钮,所以我需要使用executeOnExecutor启动带有自定义线程池的异步任务(以便同时滚动多个按钮)。以下是我使用的定义:
/**
* A custom {@link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor CUSTOM_THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(30, 30, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(128));
/**
*可用于并行执行任务的自定义{@link Executor}。
*/
public static final Executor CUSTOM_THREAD_POOL_Executor=new ThreadPoolExecutor(30,30,1,TimeUnit.SECONDS,new LinkedBlockingQueue(128));
希望这对别人有帮助 你试过这个吗?谢谢brokenstar!我会试一试,然后再报告。
/**
* A custom {@link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor CUSTOM_THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(30, 30, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(128));