Android Textview marquee not working. - android

How come the following code not working. I have something similar at other part of the layout and it works. But this part does not work. Any idea?
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:paddingLeft="50dip"
android:paddingRight="50dip"
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_gravity="center_vertical"
android:id="#+id/statusTvBottom"
android:text="Status: "
android:layout_marginLeft="5dp">
</TextView>
</LinearLayout>

First, the text has to be longer than the "box" in order to marquee, if it fits-no marquee. I use this code:
<TextView
android:id="#+id/availability"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_vertical|center_horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="#343434"
android:textSize="#dimen/text_size_medium"
android:textStyle="bold|italic" />
Setting android:focusable="false" and android:focusableInTouchMode="false" allows it to marquee without focus.

First, you can try this:
textview.setSelected(true);
But it might not work when the text view can't get the focus all the time. So, to ensure TextView Marquee working, I had to use a custom TextView.
public class CustomTextView extends TextView {
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#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 then, you can use the custom TextView as the scrolling text view in your layout .xml file like this:
<com.example.myapplication.CustomTextView
android:id="#+id/tvScrollingMessage"
android:text="#string/scrolling_message_main_wish_list"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#color/black"
android:gravity="center"
android:textColor="#color/white"
android:textSize="15dp"
android:freezesText="true"/>
NOTE: in the above code snippet com.example.myapplication is an example package name and should be replaced by your own package name.
Hope this will help you. Cheers!

Related

Scroll Textview inside RecyclerView

I have a RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/activityRecicler"
android:layout_width="match_parent"
android:scrollbars="vertical"
android:layout_height="wrap_content"
app:stackFromEnd="true"
/>
And I have a row layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/description"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/solutions"/>
</LinearLayout>
And the wrap content work, but my problem is that TextView with id description It could be very long and so, I would have a Scroll for this TextView.
How could I do this?
Change your layout XML to:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ScrollView
android:id="#+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
<TextView
android:id="#+id/solutions"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
And then in your activity:
recyclerView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
findViewById(R.id.scroll_view).getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
});
scrollView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of child view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
I am beginner on Android and so I don't know if my solution it's good.
I have put in Layout Row as suggested by #Payal
<ScrollView
android:id="#+id/childScroll"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/solutions"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="long_text"
android:maxLines="5"
android:scrollbars="vertical"/>
</ScrollView>
And in My ViewHolder
public ViewHolder(View itemView) {
super(itemView);
solutions = (TextView) itemView.findViewById(R.id.solutions);
description = (TextView) itemView.findViewById(R.id.description);
scrollable = (ScrollView) itemView.findViewById(R.id.childScroll);
solutions.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of child view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
//Enabling scrolling on TextView.
solutions.setMovementMethod(new ScrollingMovementMethod());
}
And it's work.
I can scroll the TextView in my RecyclerView
Try below code on your textview id in viewholder.
scrollable = (TextView)findViewById(R.id.textView1);
//Enabling scrolling on TextView.
scrollable.setMovementMethod(new ScrollingMovementMethod());
add in TextViewlayout
android:scrollbars="vertical"
rowlayout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:lines="1"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="#ff4500" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/solutions"/>
</LenearLayout>
and in activity
descrptionTextview.setSelected(true);
either you can wrap it in scrollview like this
<ScrollView
android:layout_height="100px"
android:layout_width="fill_parent">
<TextView
android:id="#+id/text_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="long_text"/>
</ScrollView>
or
add these two attributes to yout textview
android:maxLines="5"
android:scrollbars="vertical"
and add below line in your code
textview.setMovementMethod(new ScrollingMovementMethod());
hope this helps :)
Make a new 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;
}
}
Then in xml
<AutoScrollingTextView
android:scrollHorizontally="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"/>
This works !!!

Custom CheckBoxPreference performance

I'm using this CheckBoxPreference Class to support RTL text direction for pre Android 4.2 versions and to use a custom font style for my preference
public class MyCheckBoxPreference extends CheckBoxPreference {
TextView txtTitle, txtSum;
View Custmv;
public MyCheckBoxPreference(Context context) {
super(context);
}
public MyCheckBoxPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onBindView(#NonNull View view) {
super.onBindView(view);
Context context = getContext();
txtTitle = (TextView) view.findViewById(android.R.id.title);
txtTitle.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf"));
txtSum = (TextView) view.findViewById(android.R.id.summary);
txtSum.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf"));
}
#Override
protected View onCreateView(ViewGroup parent) {
Context ccc = getContext();
LayoutInflater inflater = (LayoutInflater) ccc.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Custmv = inflater.inflate(R.layout.arabic_checkboxpreference_layout, parent, false);
return Custmv;
}
and I'm using it in my prefs.xml like so:
<com.app.myclasses.MyCheckBoxPreference
android:defaultValue="false"
android:key="cb_big"
android:summaryOff="#string/off"
android:summaryOn="#string/on"
android:title="#string/Show_Big_Text" />
And here is the arabic_checkboxpreference_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:id="#+id/sos">
<CheckBox
android:id="#+android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_marginLeft="16dip"
android:minWidth="56dp"
android:gravity="center"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1"
android:gravity="end">
<TextView
android:id="#+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="?android:attr/textColorPrimary"
android:text="Title"
android:layout_alignParentRight="true" />
<TextView
android:id="#android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="3"
android:text="subTitle"
android:layout_alignRight="#android:id/title"
android:textColor="?android:attr/textColorSecondary" />
</RelativeLayout>
Every thing works great, but the problem is when using more than one instance of my custom class, I mean when using multiple CheckBoxPreferences in prefs.xml and when clicking on a CheckBoxPreference it becomes focused for a while (~ 1-2 seconds) before getting checked or unchecked.
Any idea please?
Edit:
According to kha answer I removed the initialization from the onBind method to the constructor and every thing is smooth now:
public MyCheckBoxPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.mTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
this.Custmv = View.inflate(context, R.layout.arabic_checkboxpreference_layout, null);
TextView txtTitle = (TextView) Custmv.findViewById(android.R.id.title);
txtTitle.setTypeface(mTypeface);
TextView txtSum = (TextView) Custmv.findViewById(android.R.id.summary);
txtSum.setTypeface(mTypeface);
}
It may be related to the fact you load the font with Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf")every time you're binding the view.
Try moving it out from your onBindView method and create it once in your view instead and use the reference when you need to set the font and see if that makes any difference

Automatically scrolling TextView inside a ViewPager

I want to create a LinearLayout with two TextViews: a label and a data placeholder. Since the data can be arbitrarily long, I want to restrict the size of the second TextView to a single line, and to automatically scroll horizontally if the data does not fit in the view.
Also, I want the width of the second TextView to be calculated at runtime, so that it can fill 70% of the parent container and be aligned to its right.
So far this is what I've got:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/ll_denunciante" >
<TextView
android:id="#+id/txtv_label_denunciante"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:gravity="left"
android:text="#string/txtv_label_denunciante" />
<TextView
android:id="#+id/txtv_data_denunciante"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="right"
android:maxLines="1"
android:ellipsize="marquee"
android:scrollHorizontally="true"
android:marqueeRepeatLimit="marquee_forever"
android:text="#string/txtv_no_data" />
</LinearLayout>
But the text is simply cut off. It is not ellipsized and automatic scrolling does not work.
Adding
android:focusable="true"
android:focusableInTouchMode="true"
does not fix the problem.
The answer to this question did not help either.
I'll gladly accept an answer using a RelativeLayout if it accomplishes the desired result using less code or if it is not possible using a LinearLayout.
Edit
Changing the second TextView to:
<TextView
android:id="#+id/txtv_data_denunciante"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:ellipsize="marquee"
android:gravity="right"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="#string/txtv_no_data" />
and adding
txtvDataDenunciante.setSelected(true);
fixed it.
I tried this way and it works. Replace your 2nd TextView with the one below. Here is the Result in the attached screenshot.
<TextView
android:id="#+id/txtv_data_denunciante"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:ellipsize="marquee"
android:gravity="right"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:marqueeRepeatLimit="marquee_forever"
android:maxLines="1"
android:singleLine="true"
android:freezesText="true"
android:text="#string/txtv_no_data"
android:selectAllOnFocus="true" />
EDIT : If XML attributes don't work in your case, then the problem is about taking the focus. In some cases, parent Layouts or some others take the focus on theirself. So you need to gain the focus for the particular View element yourself on the RunTime. To do that, you can set your TextView as selected.
yourTextView.setSelected(true);
If it is in a ListView, the problem is that you TextView does not get the focus.
Change your TextView to use this one :
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;
}
}
With these parameters :
android:scrollHorizontally="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
As seen here : https://stackoverflow.com/a/9707140/1318795

ScrollView scrolls when content fits on screen

I'm having an issue where I have a ScrollView content inside of it. In the event that the content doesn't all fit on screen, I want it to scroll. However, if it all fits I don't want it to scroll.
As is, the scrollviewer scrolls quite a bit and all the content can be scrolled way off screen.
How does one get the scrollview to not scroll when all the content fits on the screen?
<ScrollView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_toRightOf="#id/productImageView"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:id="#+id/detailsScrollView"
android:paddingRight="24dp"
android:paddingLeft="24dp"
android:clipChildren="true"
android:fillViewport="true"
android:measureAllChildren="true">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1"
android:paddingTop="24dp"
android:paddingBottom="24dp">
<TextView
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/patternTitleTextView" />
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/designerNameTextView"
android:textColor="#color/default_gray" />
<TextView
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/descriptionTextView"
android:layout_marginTop="12dp"
android:layout_weight="1"
android:minLines="200"
android:scrollbars="none"
android:scrollHorizontally="false"
android:singleLine="false"
android:ellipsize="none" />
</LinearLayout>
</ScrollView>
You probably need to create a custom ScrollView:
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;
public class CustomScrollView extends ScrollView {
private boolean enableScrolling = true;
public boolean isEnableScrolling() {
return enableScrolling;
}
public void setEnableScrolling(boolean enableScrolling) {
this.enableScrolling = enableScrolling;
}
public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomScrollView(Context context) {
super(context);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isEnableScrolling()) {
return super.onInterceptTouchEvent(ev);
} else {
return false;
}
}
}
Then you can do something similar to this in your code:
CustomScrollView myScrollView = (CustomScrollView) findViewById(R.id.myScroll);
myScrollView.setEnableScrolling(false); // disable scrolling
myScrollView.setEnableScrolling(true); // enable scrolling
Of course, it will be up to you to decide when exactly you need to enable/disable scrolling.
The problem in my case was with one of the TextViews.
<TextView
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/descriptionTextView"
android:layout_marginTop="12dp"
android:layout_weight="1"
android:minLines="200"
android:scrollbars="none"
android:scrollHorizontally="false"
android:singleLine="false"
android:ellipsize="none" />
I shouldn't have set minLines or set the layout_weight. After removing those two things the scrollview did exactly what I expected it to.

Android multiple textview marquee

In have the many textview which may have very long text so have done
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
android:singleLine="true"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
For first text view it works fine but for other it is not working, if anyone have done it for other textview in activity then please help me.
Thank you.
It is very easy extend your class with TextView and override following methods
package com.az.app;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.TextView;
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);
}
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#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;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
and in your XML do this
<com.az.app.ScrollingTextView
android:id="#+id/TextView02"
android:layout_width="140dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/ImageView01"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="This is a really very very very very very long text "
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
<com.az.app.ScrollingTextView
android:id="#+id/TextView03"
android:layout_width="140dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/ImageView01"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="This is a really very very very very very long text "
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
Now all the textviews will be scrolling.
Update:
Note that it doesn't work without android:singleLine="true".
Use it with android:maxLines="1", Although we know that it's deprecated.
#Sathish Yes you can, i've done it. Following is my code for two marquee textview in xamarin.android
xml
<TextView
android:text=""
android:singleLine="true"
android:background="#cc2900"
android:ellipsize="marquee"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginLeft="1dp"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:id="#+id/TextView03"
android:padding="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:text=""
android:singleLine="true"
android:background="#cc2900"
android:ellipsize="marquee"
android:textColor="#FFFFFF"
android:textSize="15dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginLeft="1dp"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:id="#+id/txtinternational"
android:padding="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
and in your activity you just have to set focus to your all textviews:
TextView shorts = FindViewById<TextView>(Resource.Id.TextView03);
shorts.Selected = true;
TextView internationalshorts = FindViewById<TextView>(Resource.Id.txtinternational);
internationalshorts.Selected = true;

Categories

Resources