ScrollingTextView not working when clock is visible - android

I have a TextView in my application which shows the current time, i implemented it like this
private Handler handler = new Handler();
private Runnable runnable = new Runnable()
{
public void run()
{
batteryLevel();
if(clock_on == true) {
Handler clockUpdate = new Handler();
clockUpdate.postDelayed(new Runnable() {
public void run() {
executeClock();
}
}, 500);
}
handler.post(this);
}
public void executeClock() {
TextView timeTv = (TextView) findViewById(R.id.time);
long currentTime=System.currentTimeMillis();
Calendar cal=Calendar.getInstance();
cal.setTimeInMillis(currentTime);
String timeFormat24 = "%1$tH:%1$tM";
// String timeFormat12 = "%1$tI:%1$tM";
String showTime=String.format(timeFormat24,cal);
timeTv.setText(showTime);
}
In my app i have a ScrollingTextView aswell, ScrollingtextView.java
public class ScrollingTextView extends TextView {
public ScrollingTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ScrollingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollingTextView(Context context) {
super(context);
}
#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;
}
}
<com.doublep.example.ScrollingTextView
android:id="#+id/txt_lcd_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="#f82424"
android:textSize="30dp" />
The ScrollingTextView doesn't work if the clock TextView is visible, when i make the visibility of the clock GONE then the ScrollingTextView works perfectly
Why is this happening?
How can i fix it?
EDIT: if i delay the clock the ScrollingTextView starts working, but as soon as the clock TextView gets set to the current time, the ScrollingTextView stops working
UPDATE: after a bit of testing i noticed that the ScrollingTextView is working, but every time the executeClock() method runs, the ScrollingTextView animation gets reset and starts once again

Do you have your clock textview and scrolltextview in the same viewgroup?? so for example are they all child views of the same linear or relative layout?? Try to separate them and make them child of different viewgroups. That worked for me once and may work for you too

Related

How to create a a expandable view in android?

I want to expand the view on clicking the + button and this + sign changes to - when the view expanded.Again when i click the - button the view should be shrink.
Inside the view i have some TextView field.Please anyone suggest me.I am new to android.
This answer solves the question.
public class ExpandableTextView extends TextView implements OnClickListener
{
private static final int MAX_LINES = 5;
private int currentMaxLines = Integer.MAX_VALUE;
public ExpandableTextView(Context context)
{
super(context);
setOnClickListener(this);
}
public ExpandableTextView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setOnClickListener(this);
}
public ExpandableTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
setOnClickListener(this);
}
#Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter)
{
/* If text longer than MAX_LINES set DrawableBottom - I'm using '...' icon */
post(new Runnable()
{
public void run()
{
if (getLineCount()>MAX_LINES)
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, R.drawable.icon_more_text);
else
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
setMaxLines(MAX_LINES);
}
});
}
#Override
public void setMaxLines(int maxLines)
{
currentMaxLines = maxLines;
super.setMaxLines(maxLines);
}
/* Custom method because standard getMaxLines() requires API > 16 */
public int getMyMaxLines()
{
return currentMaxLines;
}
#Override
public void onClick(View v)
{
/* Toggle between expanded collapsed states */
if (getMyMaxLines() == Integer.MAX_VALUE)
setMaxLines(MAX_LINES);
else
setMaxLines(Integer.MAX_VALUE);
}
}
You can visible or gone particular layout on button click event at runtime like below code:
findViewById(R.id.yourButtonId).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mainView.setVisibility(View.GONE);
}
});

There is a way to start contentScrim animation sooner on CollapsingToolbarLayout?

In this example the contentScrim attribute is set with a color, but I can't figure out how to control when it starts. I woud like to start the color transition sooner.
Can you give me a hint? Thanks in advance.
You'd have to create a class that extends CollapsingToolbarLayout. Something like this (you might need to adjust that so it exactly fits your needs):
public class CustomCollapsingToolbarLayout extends CollapsingToolbarLayout {
public static interface Listener {
public void onContentScrimAnimationStarted(boolean showing);
}
private Listener mListener;
public CustomCollapsingToolbarLayout(Context context) {
super(context);
}
public CustomCollapsingToolbarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomCollapsingToolbarLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void setScrimsShown(boolean shown, boolean animate) {
super.setScrimsShown(shown, animate);
if (animate && mListener != null) {
mListener.onContentScrimAnimationStarted(shown);
}
}
public void setListener(Listener listener) {
mListener = listener;
}
}
And just call setListener on your CustomCollapsingToolbarLayout instance.
CustomCollapsingToolbarLayout mToolbarLayout =
(CustomCollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
mToolbarLayout.setListener(new Listener() {
#Override
public void onContentScrimAnimationStarted(boolean showing) {
//do what you want
}
});
EDIT (actually answering the question):
Modify the scrimVisibleHeightTrigger value (with the setScrimVisibleHeightTrigger method of the CollapsingToolbarLayout) to change the starting point of the animation.

How do I draw a drawable with its exact size in my custom view?

SOLVED: Solution below as answer.
I have a custom view with a TransitionDrawable and when I draw it in the onDraw() method it scales automatically to fill the whole parent layout, even when it's set in the xml to wrap_content. The picture is in mdpi and hdpi and my testing device (samsung galaxy s) I think it's no more than hdpi.
package com.adyrsoft.pronunciationtrainer;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class RecordButton extends View {
private static final String TAG = "RecordButton";
private TransitionDrawable mDrawable;
private boolean mActivated;
private OnClickListener mOnClickListenerInternal = new OnClickListener() {
#Override
public void onClick(View v) {
toggleState();
if(mOnClickListener != null) {
mOnClickListener.onClick(v);
}
}
};
private OnClickListener mOnClickListener = null;
public RecordButton(Context context) {
super(context);
init();
}
public RecordButton(Context context, AttributeSet attrib) {
super(context, attrib);
init();
}
public RecordButton(Context context, AttributeSet attrib, int defStyle) {
super(context, attrib, defStyle);
init();
}
public void setState(boolean activated) {
mActivated = activated;
if(mActivated){
mDrawable.startTransition(300);
}
else {
mDrawable.reverseTransition(300);
}
}
public void toggleState() {
if(mActivated) {
setState(false);
}
else {
setState(true);
}
}
#SuppressWarnings("deprecation")
private void init() {
mActivated = false;
mDrawable = (TransitionDrawable) getResources().getDrawable(R.drawable.btnrecord);
Log.d(TAG, "Drawable intrinsic width and height are: " +
Integer.toString(mDrawable.getIntrinsicWidth()) + " " +
Integer.toString(mDrawable.getIntrinsicHeight()));
mDrawable.setBounds(0,0,mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
Log.d(TAG, "The bounds for the button are: "+mDrawable.getBounds().flattenToString());
super.setBackgroundDrawable(mDrawable);
setClickable(true);
super.setOnClickListener(mOnClickListenerInternal);
invalidate();
}
public void setOnClickListener(View.OnClickListener listener) {
mOnClickListener = listener;
}
protected void onDraw (Canvas canvas) {
super.onDraw(canvas);
}
}
What am I doing wrong?
Thanks.
After hours trying to understand how I should use the drawables in a custom view in order to be displayed in its original size, I've figured out how to do it.
First a few things that I didn't know but are a must is:
The background drawable should be left to the parent class to be
drawn when using View as the parent. If not, the TransitionDrawable can't be seen fading between pictures.
Only if I am going to draw on the background drawable I should override onDraw() and do the drawing there.
And the last but not less important is that I should override onMeasure() to specify the size of the view. If I don't do it, it will fill all the free space in the parent layout, as it was happening to me.
I've passed the TransitionDrawable to the parent class with setBackgroundDrawable() and since I wasn't drawing in the background drawable, I've removed the onDraw() method. Also I've implemented onMeasure() with a quick and dirty solution specifying the size of the picture I am drawing.
This is the final result:
public class RecordButton extends View {
private static final String TAG = "RecordButton";
private static final int DESIRED_WIDTH = 180;
private static final int DESIRED_HEIGHT = 66;
private TransitionDrawable mDrawable;
private Rect mViewRect;
private boolean mActivated;
private OnClickListener mOnClickListenerInternal = new OnClickListener() {
#Override
public void onClick(View v) {
toggleState();
if(mOnClickListener != null) {
mOnClickListener.onClick(v);
}
}
};
private OnClickListener mOnClickListener = null;
public RecordButton(Context context) {
this(context, null, 0);
}
public RecordButton(Context context, AttributeSet attrib) {
this(context, attrib, 0);
}
public RecordButton(Context context, AttributeSet attrib, int defStyle) {
super(context, attrib, defStyle);
init();
}
public void setState(boolean activated) {
mActivated = activated;
if(mActivated){
mDrawable.startTransition(300);
}
else {
mDrawable.reverseTransition(300);
}
}
public void toggleState() {
if(mActivated) {
setState(false);
}
else {
setState(true);
}
}
#SuppressWarnings("deprecation")
private void init() {
mActivated = false;
mDrawable = (TransitionDrawable) getResources().getDrawable(R.drawable.btnrecord);
setBackgroundDrawable(mDrawable);
setClickable(true);
super.setOnClickListener(mOnClickListenerInternal);
invalidate();
}
public void setOnClickListener(View.OnClickListener listener) {
mOnClickListener = listener;
}
#Override
protected void onMeasure(int m, int n) {
setMeasuredDimension(DESIRED_WIDTH, DESIRED_HEIGHT);
}
}

Automatic horizontal scroll in TextView

I have custom gallery.
Gallery represents items that are frame layout.
There are one imageView and textView above it.
If text in textView is too long, i need it to be scrolled automatically.
It's one line of text, and it's needed to be scrolled horizontally.
I've found this snippet of code:
TextView
android:text="Single-line text view that scrolls automatically"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
It works in my test app with only one text view in it.
But it doesn't work in my gallery. Noting happens, text just stay still.
Any help?
Try this custom TextView class:
public class AutoScrollingTextView extends TextView {
public AutoScrollingTextView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public AutoScrollingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoScrollingTextView(Context context) {
super(context);
}
#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;
}
}
and set the following XML attributes:
android:scrollHorizontally="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
This works beautifully in my dictionary apps where multiple entries may need to auto-scroll simultaneously to display complete content.
The marquee effect on a TextView is only designed to work when the view is focused or selected. The XML code you have tries to make the TextView focused all the time. Unfortunately, since only one view can be focused at any time, and since you have multiple views in the gallery, this approach will not work for you.
The easiest way to accomplish this otherwise is to make the TextViews always be selected. Multiple TextViews can hold the selected state at one time. Selection is meant to be used for an active element of an AdapterView, but still works outside of one. Firstly, remove the attributes modifying the focus from the XML and then just call TextView.setSelected(true) sometime after the view is initialised, e.g. in Activity.onCreate(Bundle) (there is no XML attribute for this). If you are supplying the views from an adapter, then you can call TextView.setSelected(true) during the getView() method after you inflate the view.
Here is an example project showing marquee working for multiple TextViews, and the behaviour inside a Gallery.
Try using ViewPager instead of gallery. This is available in android support packages. http://android-developers.blogspot.in/2011/08/horizontal-view-swiping-with-viewpager.html
I've tried everything, and finally came up with this. This works for me...hope that this will help you someday. Cheers.
package com.gui.custom_views;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.media_player.AndroidMediaPlayerActivity;
/**
* Custom Automatic Scrollable Text View
*
* #author Veljko Ilkic
*
*/
public class AutomaticScrollTextView extends LinearLayout {
// Context of application
Context context;
// TextView
private TextView mTextField1;
// Horizontal scroll
private ScrollView mScrollView1;
// Animation on start
private Animation mMoveTextOnStart = null;
// Out animation
private Animation mMoveText1TextOut = null;
// Duration of animation on start
private int durationStart;
// Duration of animation
private int duration;
// Pain for drawing text
private Paint mPaint;
// Text current width
private float mText1TextWidth;
/**
* Control the speed. The lower this value, the faster it will scroll.
*/
public static final int MS_PER_PX = 80;
/**
* Control the pause between the animations. Also, after starting this
* activity.
*/
public static final int PAUSE_BETWEEN_ANIMATIONS = 0;
private boolean mCancelled = false;
// Layout width
private int mWidth;
// Animation thread
private Runnable mAnimation1StartRunnable;
public AutomaticScrollTextView(Context context) {
super(context);
init(context);
this.context = context;
}
public AutomaticScrollTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
this.context = context;
}
private void init(Context context) {
initView(context);
// init helper
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(1);
mPaint.setStrokeCap(Paint.Cap.ROUND);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mWidth = getMeasuredWidth();
// Calculate
prepare();
// Setup
setupText1Marquee();
}
#Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
mTextField1.setOnClickListener(l);
}
// Method to finally start the marquee.
public void startMarquee() {
prepare();
prepareTextFields();
startTextField1Animation();
mCancelled = false;
}
private void startTextField1Animation() {
mAnimation1StartRunnable = new Runnable() {
public void run() {
mTextField1.setVisibility(View.VISIBLE);
mTextField1.startAnimation(mMoveTextOnStart);
}
};
postDelayed(mAnimation1StartRunnable, PAUSE_BETWEEN_ANIMATIONS);
}
public void reset() {
mCancelled = true;
if (mAnimation1StartRunnable != null) {
removeCallbacks(mAnimation1StartRunnable);
}
mTextField1.clearAnimation();
prepareTextFields();
mMoveTextOnStart.reset();
mMoveText1TextOut.reset();
mScrollView1.removeView(mTextField1);
mScrollView1.addView(mTextField1);
mTextField1.setEllipsize(TextUtils.TruncateAt.END);
invalidate();
}
public void prepareTextFields() {
mTextField1.setEllipsize(TextUtils.TruncateAt.END);
mTextField1.setVisibility(View.INVISIBLE);
expandTextView(mTextField1);
}
private void setupText1Marquee() {
// Calculate duration of animations
durationStart = (int) ((mWidth + mText1TextWidth) * MS_PER_PX);
duration = (int) (2 * mWidth * MS_PER_PX);
// On start animation
mMoveTextOnStart = new TranslateAnimation(0, -mWidth - mText1TextWidth,
0, 0);
mMoveTextOnStart.setDuration(durationStart);
mMoveTextOnStart.setInterpolator(new LinearInterpolator());
mMoveTextOnStart.setFillAfter(true);
// Main scrolling animation
mMoveText1TextOut = new TranslateAnimation(mWidth, -mWidth
- mText1TextWidth, 0, 0);
mMoveText1TextOut.setDuration(duration);
mMoveText1TextOut.setInterpolator(new LinearInterpolator());
mMoveText1TextOut.setFillAfter(true);
mMoveText1TextOut.setRepeatCount(Animation.INFINITE);
// Animation listeners
mMoveTextOnStart
.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationStart(Animation animation) {
invalidate();
mTextField1.invalidate();
}
public void onAnimationEnd(Animation animation) {
if (mCancelled) {
return;
}
mTextField1.startAnimation(mMoveText1TextOut);
}
public void onAnimationRepeat(Animation animation) {
invalidate();
mTextField1.invalidate();
}
});
mMoveText1TextOut
.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationStart(Animation animation) {
invalidate();
mTextField1.invalidate();
}
public void onAnimationEnd(Animation animation) {
if (mCancelled) {
return;
}
}
public void onAnimationRepeat(Animation animation) {
invalidate();
mTextField1.invalidate();
}
});
}
private void prepare() {
// Measure
mPaint.setTextSize(mTextField1.getTextSize());
mPaint.setTypeface(mTextField1.getTypeface());
mText1TextWidth = mPaint.measureText(mTextField1.getText().toString());
setupText1Marquee();
}
private void initView(Context context) {
setOrientation(LinearLayout.VERTICAL);
setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT, Gravity.LEFT));
setPadding(0, 0, 0, 0);
// Scroll View 1
LayoutParams sv1lp = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
sv1lp.gravity = Gravity.CENTER_HORIZONTAL;
mScrollView1 = new ScrollView(context);
// Scroll View 1 - Text Field
mTextField1 = new TextView(context);
mTextField1.setSingleLine(true);
mTextField1.setEllipsize(TextUtils.TruncateAt.END);
mTextField1.setTypeface(null, Typeface.BOLD);
mScrollView1.addView(mTextField1, new ScrollView.LayoutParams(
mTextField1.getWidth(), LayoutParams.WRAP_CONTENT));
addView(mScrollView1, sv1lp);
}
public void setText1(String text) {
String temp = "";
if (text.length() < 10) {
temp = " " + text + " ";
} else {
temp = text;
}
mTextField1.setText(temp);
}
public void setTextSize1(int textSize) {
mTextField1.setTextSize(textSize);
}
public void setTextColor1(int textColor) {
mTextField1.setTextColor(textColor);
}
private void expandTextView(TextView textView) {
ViewGroup.LayoutParams lp = textView.getLayoutParams();
lp.width = AndroidMediaPlayerActivity.getScreenWidth();
textView.setLayoutParams(lp);
}
}
I came across this problem once and finally fixed the problem by calling .setFocus() on the textView.
Hi You have Tag in the xml file itself. And also use the Scrollview Property of FOCUS_DOWN in the java file ... Hope It helps to u ...
This code is working properly for me.
scrollview=(ScrollView)findViewById(R.id.scrollview1);
tb2.setTextSize(30);
tb2.setMovementMethod(new ScrollingMovementMethod());
scrollview.post(new Runnable() {
public void run() {
scrollview.fullScroll(View.FOCUS_DOWN);
}
});
public class ScrollingTextView extends TextView {
public ScrollingTextView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public ScrollingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollingTextView(Context context) {
super(context);
}
#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;
}
}
<com.test.autoscroll.ScrollingTextView
android:id="#+id/actionbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:textSize="16dip"
android:textStyle="bold"
android:lines="1"
android:scrollHorizontally="true"
android:ellipsize="marquee"
android:text="autoscrollable textview without focus to textview...working...."
android:marqueeRepeatLimit="marquee_forever"
/>
Add this code to your own
findViewById(R.id.yourtextviewid).setSelected(true);
maybe your problem is fixed.

How do I get text to Marquee in the Android-wheel?

I am using the android-wheel http://code.google.com/p/android-wheel/ in an application.
I have three of the wheels side by side on my screen. When the text in a wheel is wider than the wheel I would like it to scroll to the side (As per Marquee)
I have implemented an AbstractWheelTextAdapter and created a custom ScrollingTextView for the items as follows: (ScrollingTextView is to overcome the issue with Marquee only working when an item has focus)
public class ScrollingTextView extends TextView {
public ScrollingTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ScrollingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollingTextView(Context context) {
super(context);
}
#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;
}
}
And the xml:
<com.test.app.ScrollingTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id = "#+id/wheel_text"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:inputType="text"
android:scrollHorizontally="true"
android:textColor="#F000"
android:lines="1"
android:focusable="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:focusableInTouchMode="true"/>
Has anyone been able to get this to work?
(I have also tried setting the Ellipse in the code for the AbstractWheelTextAdapter without success)
Because the WheelView didn't invalidate itself.In Activity,add the code :
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
wheelview.invalidate();
sendEmptyMessageDelayed(0, 0);
}
};
handler.sendEmptyMessage(0);
Then the TextView Marquee effect works.But when you scroll the WheelView,the TextView string reset from start.
I had try the TextView Marquee effect in ListView, the Marquee effect works.I gonna check the ListView source code ,see what differences between ListView and WheelView.

Categories

Resources