I am working on an Android application whose main purpose is to display CNN-style slogans in the style of news at the bottom of the screen and some photos. I created two custom views, one for displaying photos and one for displaying a string. It displays one image for a certain period of time and swaps the current image with the next from the queue.
To animate the text in the bottom pane, I used canvas, onDraw () and handler.postDelayed. This solution gives poor results. The movement of the text is not smooth, especially when it comes to swap images.
What should I use instead of canvas? Is there an OpenGL-based library that could make this task relatively painless? I tried to use AndEngine, but the lack of documentation and threading issues did not allow me to work with it anymore.
public class Infobar extends View { private List<Message> messages; private Handler handler; private Paint boxPaint; private Paint defaultTextPaint; private Paint importantTextPaint; private long offset = 0; private long maxOffset = 1000; private int textWidth = 1000; private int textHeight = 50; private int measuredWidth; private int measuredHeight; private Runnable animateRunnable = new Runnable() { public void run() { animateMessage(); } }; long startTime = new Date().getTime(); private int backgroundCol = Color.parseColor("#ffff00"); private int textColor = Color.parseColor("#000000"); private static final int FRAME_DELAY = 10; private static final int FRAME_SHIFT = 3; private static final int EMPTY_SPACE = 2; private static final String SEPARATOR = " ✩ "; private static final int TEXT_SIZE = 35; public Infobar(Context context, AttributeSet attrs) { super(context, attrs); handler = new Handler(); messages = new ArrayList<Message>(); boxPaint = new Paint(); defaultTextPaint = new Paint(); defaultTextPaint.setColor(getResources().getColor(R.color.info_bar_default_text_color)); importantTextPaint = new Paint(); importantTextPaint.setColor(getResources().getColor(R.color.info_bar_important_text_color)); handler.postDelayed(animateRunnable, FRAME_DELAY); } public void setMessagesList(List<Message> list) { messages = list; } public void setBackgroundColor(String color) { backgroundCol = Color.parseColor(color); } public void setTextColor(String color) { textColor = Color.parseColor(color); } public List<Message> getMessagesList() { return messages; } private String getMessagesString() { StringBuilder builder = new StringBuilder(); for(Message message : messages) { builder.append(message.content); if(messages.indexOf(message) != (messages.size() - 1)) { builder.append(SEPARATOR); } } return builder.toString(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); measuredWidth = getMeasuredWidth(); measuredHeight = getMeasuredHeight(); } @Override protected void onDraw(Canvas canvas) { drawBackground(canvas, false); drawMessage(canvas, getMessagesString()); super.onDraw(canvas); } private void drawBackground(Canvas canvas, boolean important) { boxPaint.setColor(backgroundCol) ; canvas.drawRect(0, 0, measuredWidth, measuredHeight, boxPaint); } private void drawMessage(Canvas canvas, String message) { defaultTextPaint.setTextSize(TEXT_SIZE); Rect bounds = new Rect(); defaultTextPaint.getTextBounds(message, 0, message.length(), bounds); defaultTextPaint.setColor(textColor); textWidth = bounds.width(); textHeight = bounds.height(); int positionX = measuredWidth - (int)offset; int positionY = measuredHeight - textHeight/2; if(offset > (measuredWidth + textWidth)) { offset = 0; positionX = measuredWidth; } canvas.drawText(message, positionX, positionY, defaultTextPaint); } private void animateMessage() { offset += FRAME_SHIFT;
source share