Android: How to create a Dialog with a Scrolling title? - android

Ok so I've read the Custom Dialog explanation on the And Dev website
http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog
It show's you how to make a custom dialog, but not how to customise the title!
Basically my title is too long and I want it to scroll (like textview) or better still have a 'marquee' effect i think it's called.
Or if I can't make it scroll, give it more space to wrap onto more lines!
Any ideas, I don't hold out much hope as it's not on android.dev :-(

You can make dialog title multiline:
TextView title = (TextView) dialog.findViewById(android.R.id.title);
title.setSingleLine(false);

Customizig window (and thus also dialog) titles can be done by requesting the window feature CUSTOM_TITLE, which must be done before setContentView.
So in your Dialog / Activity subclasses onCreate(), call the following:
super.onCreate(savedInstance);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // <- insert this
Then, after your setContentView, do this:
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title); // <- insert this
The layout can generally contain anything you want.
For a marquee text control. e.g. do this:
layout/custom_title.xml:
<FrameLayout android:id="#+id/FrameLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TextView android:id="#+id/caption_text"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="This is a very very long text that will not fit into a caption regularly, so it will be displayed using marquee..."
android:lines="1"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
></TextView>
</FrameLayout>
Due to some constraints with the marquee feature, the text view has to be made focusable and it will only be scrolling when focused (which it initially should be).

I consider a combination of RuslanK's (for getting the TextView) Thorstenvv's (for making TextView scrollable) answer to be best practice.

Related

Android how to create textview one over another

I am developing an Android application with a textview updated by one event and at the same place where the textview is present, I want 1 more textview so that other event can update this new textview. How do i achieve in having 1 textview on other
I'm assuming that you're asking how you could have two TextView components overlaying each other. There are a few way you could do this.
Frame Layout
Use a Frame Layout to determine the area in which the TextViews will occupy. Like this...
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/tv1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/tv2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</FrameLayout>
Credit goes to https://stackoverflow.com/a/2634059/3769032
Create a Compound View
This is fairly in-depth for the type of question you are asking. CompoundViews are a collection of typical views, such as a TextView, that you can create if you plan on re-using the view frequently.
If you plan on overlaying the TextViews often, I recommend this. So check out this tutorial.
Use only one TextView
Having two overlayed textviews can become messy really quickly. If you have two pieces of text overlayed is becomes impossible to read. So since the content of your textview is based on an event. Use the same event listener in your java code to determine the content of your TextViews.
For example, in your on click listener you might have...
TextView tv1 = (TextView) findViewByID(R.id.tv1);
public void onClick(View view){
if (first_event_happened){
tv1.setText("One event happened");
} else if(second_event_happened){
tv1.setText("A different event happened");
}
}
These conditions might mean checking the type of view that was clicked, or checking its id (what I usually do). Please comment if things aren't clear. Some clarification on your question would be helpful too.
use relative layout and also you can set text on exiting textView like when event one triggered textView.setText(your text) and same when event two triggered textView.setText(your text)
There is no trick to this. Just put two TextViews in a RelativeLayout at the same position and they will draw overtop of one another. Like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first textview"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="second textview"/>
</RelativeLayout>
You can make each one visible or invisible by using TextView.setVisibility(...) or you can set their text with TextView.setText(...).

a textview in a listview' s row cannot click after setting descendantFocusability="blocksDescendants"

I write a customized item layout for a listview. The layout has many widgets and some will have its own clicklistener.
When I click the row, sometimes the listview' s onListItemClick work, but sometimes not.
After I spent some time searching, I find a way, setting android:descendantFocusability="blocksDescendants" in the layout' s root. It works, but only one textview cannot work,(the clickable, fucusable attr have been tried). In the list' s adapter, I set the textview' s onClickListener, it works. But that' s not nature, does anyone know how to solve it?
btw, is there a way to distinguish diffderent widget' click? Now, no matter what I click(except that textview), the whole row' s background selector got changed.
many thanks!
// my list row layout root
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:descendantFocusability="blocksDescendants"
android:padding="#dimen/medium"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
// the awful textview
<TextView
android:id="#+id/text"
android:textColor="#android:color/secondary_text_light"
android:textColorLink="#android:color/holo_blue_dark"
android:layout_marginTop="#dimen/small"
android:textAppearance="#android:style/TextAppearance.DeviceDefault"
android:layout_below="#id/nick"
android:layout_alignLeft="#id/nick"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
update
the textview uses Linkify to provide some links functionalities.
After spenting some time trying, I solved both.
the first. if your customized listview' s layout has a textview which has been set autolink or Linkify in the code, the click event in the textview won' t affect the list' s row. You have to extends your own TextView and override onTouchEvent method. please see it here
the second. just set in the customized listview' s root node: android:descendantFocusability="blocksDescendants", and then, in your widget which will have its own onClickListener, set android:clickable="true", it works for me.
hope it useful for those you encounter the same:-)

How to use layout weight when you want to toggle one of 2 visible views

I have a LinearLayout that will have a cancel button and a progress bar, where the progress bar is 70% and the cancel button is 30%, like so:
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ProgressBar
android:id="#+id/uploadProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_weight=".7"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
/>
<Button
android:id="#+id/uploadCancelButton"
style="#style/TitleBarButton"
android:layout_width="0dp"
android:layout_weight=".3"
android:layout_height="wrap_content"
android:text="#string/cancel_btn"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
This works fine, however I realized that actually I either want to show the progress bar or a text view, where the text view could be a small status message (if say the upload failed).
I tried putting a TextView in the the above LinearLayout and having its visibility set to "gone" by default and with the weight set the same as the progress bar. In the code I would only set either the progress bar to visible or the text view, and the other I would set to gone. However the android system appeared to contribute the invisible items weight to the total. I even tried using android:weightSum="1.0" in the LinearLayout xml attributes but that then my button was no longer visible as even though the text was gone, it took space.
ViewFlipper is what you are looking for.
It is very simple to use. You put the views you want to toggle inside the ViewFlipper exactly the same way like you would place them within a Layout inside XML. Then from code you call setDisplayedChild() on the ViewFlipper object containing your views. The parameter of this method is the index of the view that you want to be shown.

Extend UI of an View

I would like to extend the UI of AutoCompleteTextView. The Functionality is fine, all I need is to add an button to the right that looks like a drop-down button. Sadly AutoCompleteTextView has a 'natural' margin that I can't reduce to 0.
What can I do now?
Dose I have to overwrite onDraw() & onMeasure() to archive my goal (is there an easier way)?
You could put both AutoCompleteTextView and button onto FrameLayout, add some extra margin right to AutoCompleteTextView to make FrameLayout slightly bigger, and align button to parent right. In fact, these 2 views will interfere, but for user they will appear one next to the other w/o any margin.
Another option could be to set custom background to AutoCompleteTextView (probably modified original one taken from Android source with removed margin).
Just remembered that you can supply negative margin. You can put both views onto LinearLayout and set left margin of button to -5dp for example. However, you will still have to supply custom marginless background for button.
you can use RelativeLayout to put Button to the right of AutoCompleteTextView
Sample
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btn_close_pressed"
android:layout_alignParentRight="true"
android:id="#+id/myBtn"
></Button>
<AutoCompleteTextView android:id="#+id/myautocomplete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:layout_toLeftOf="#+id/myBtn"
/>
</RelativeLayout>

Scrollbars in TextView

I just didn't want to use ScrollView. So I have a textview with enabled vertical scrollbars.
<TextView
android:id="#+id/tv_service_ticketinfo_details"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:textColor="#color/black"
android:autoLink="web"
android:scrollbars="vertical"
android:text="empty"
android:background="#drawable/custom_shape_grey">
</TextView>
The problem is, that scrollbars are scrollable only for texts, which contain a web-links. For other texts I see a scrollbar, but can't scroll.
I can't explain it. And you?
UPD:
Another strange thing:
once I set the text with links, then I can replace it by another one without links and the textView stays scrollable
So I think the problem is that TextViews don't automatically scroll, just because you set android:scrollbars. You have to set the ScrollingMovementMethod.
However, when you use autoLink and links are found, the android framework will set the MovementMethod for you. That's why the behaviour's different.
There are two solutions that work for me.
After we set our text, force the movement method to one that supports links and scrolling.
final TextView output = (TextView) findViewById(R.id.output);
output.setText(content);
// ensure that text will scroll with or without linked text
output.setMovementMethod(LinkMovementMethod.getInstance());
Or set the movement method, assuming plaintext, before adding text to the TextView. If autoLink detects links, it will change the movement method itself.
final TextView output = (TextView) findViewById(R.id.t_output);
// ensure that text defaults to scrollable
output.setMovementMethod(ScrollingMovementMethod.getInstance());
output.setText(content);
(FYI: I'm using android:autoLink="all")
add this in your code(may be in onCreate)
//textView.setMovementMethod(ScrollingMovementMethod.getInstance());
tv_service_ticketinfo_details.setMovementMethod(ScrollingMovementMethod.getInstance());
and test.
To get a scroll bar at run time or from code, you may try with following solution:
xml:
<LinearLayout
android:id="#+id/view1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="#+id/tv_service_ticketinfo_details"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:textColor="#color/black"
android:autoLink="web"
android:scrollbars="vertical"
android:text="empty"
android:background="#drawable/custom_shape_grey">
</TextView>
</LinearLayout>
java:
mTextViewPort = (LinearLayout) findViewById(R.id.view1);
// Create a ScrollView instance
ScrollView mScrollView = new Scrollview(mContext);
// here mContext would be Activity's context. You may also choose
// mScrollView as a global variable.
mScrollView.setScrollBarStyle(SCROLLBARS_OUTSIDE_INSET);
mTextViewPort.addView(mScrollView,
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
TextView mTextView = (TextView) findViewById(R.id.tv_service_ticketinfo_details);
mScrollView.addView(mTextView );
This may help to resolve this problem.

Categories

Resources