how do I get a TextView into the visible area of a screen by scrolling a ScrollView, if the TextView is not a direct child of the ScrollView?
I've got a LinearLayout view that has a TextView at the top, then a ScrollView and below a Button:
<LinearLayout
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_height="wrap_content"/>
<ScrollView
android:id="#+id/s"
android:layout_height="0dip"
android:layout_weight="1" >
<TableLayout
android:id="#+id/t"
android:layout_height="wrap_content" >
<TableRow
android:id="#+id/r" >
<TextView
android:id="#+id/a"/>
<TextView
android:id="#+id/b"/>
<TextView
android:id="#+id/c"/>
</TableRow>
</TableLayout>
</ScrollView>
<Button
android:layout_height="wrap_content"/>
</LinearLayout>
That generated a wholly filled screen with the label at the top border, the button at the bottom border, and a table between it; depending on how many rows this table has, you can scroll it or not.
The contents of the table are generated by Java code, I just added one row as example of what is inserted there.
I now need to make sure a certain row (not necessarily the last one) is visible by scrolling vertically. I can access every element from s to c, but I can't figure out the code to make the ScrollView s scroll at all.
I tried requestChildRectangleOnScreen, scrollBy and, scrollTo, but possibly always with the wrong arguments.
For now I don't care whether TextView a is vertically centered or at the bottom or top border, it would indeed be great if it was visible at all. X-scroll should stay 0, ideally (i. e. leftmost position).
In case this is important: this function is only called when the user enters the screen with a special Intent that's telling the screen to scroll to TableRow x (it's just to show the latest change).
If you need even more information, please ask.
Thank you!
The problem was indeed that I called the function directly from a sub call of onCreate. This meant the layout wasn't done yet, thus all scrolling was done before the elements had a height and so it scrolled by 0 pixels.
The solution is to use View.post(Runnable r):
ScrollView s = (ScrollView) findViewById(R.id.s);
TextView a = (TextView) findViewById(R.id.a);
s.post(new Runnable() {
public void run() {
int[] location = new int[2];
a.getLocationInWindow(location);
int y = location[1];
s.getLocationInWindow(location);
s.scrollTo(0, y-location[1]); // or some other calculation
}
});
Related
I have a TextView and a Button in an android XML layout(TextView is at left most side and Button is at right most side in the same line), as the text in TextView is dynamic so it should take a minimum width for some initial text to be visible. As width of devices changes the minimum width of TextView does not look good all the time.
For example if width of device becomes greater, then the minimum width alloted to the TextView would look so bad because it would not use more space available on the screen.
So what I want to do is to set the minimum width of TextView according to the position of Button present at the Right most side of the screen
Like minWidth = "leave this dp" form Button.
I hope you have understood it well if not then ask me more about it.
Seeking for attributes to use.
Use a LinearLayout with horizontal orientation put that TextView and Button inside that LinearLayout. Give weight of that TextView to 1 and set width to 0dp and use wrap_content for Buttn's width
Code snippet
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
</LinearLayout>
Put button and textview inside linearlayout and set weight for textview and button according your requirement. it will set layout view according device screen size.
I have been working on an app that shows statuses about a server. I have a CardView for each server, with a RelativeView inside. On the left is an image, aligned to the cards left. In the middle, I have a TextView, aligned to the image right. On the right, I have a TextView, aligned to the right of the card.
Basically, my issue is, without using a LinearLayout, how can I make it so the middle TextView does not overlap the right TextView, preferably in the layout's XML? The text in both views is dynamically long, making a LinearLayout not very preferable.
Here is a diagram of the Layout to help you picture what I'm talking about. Sorry for the external link, it was getting reformatted in the post.
1.Aline middle TextView to centerHorizontal of parent, give fixed width , margin left and right to it. Mention that it is right of another TextView by using layout_toLeftOf.
2.Also aligh right hand side TextView to right by using alignRightToParent = true. Then give left margin to it.
I tried by using below xml code:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="#+id/sun"
android:background="#004700" >
<TextView
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="#+id/sun12"
android:singleLine="false"
android:text="abcdgsss ssssssssssssssss ssssssss sssssssssssssssssssssss"
android:textColor="#fff"
android:textSize="16sp" />
<TextView
android :id="#+id/sun12"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dp"
android:text="abcdgsss ssssssssssssssss ssssssss sssssssssssssssssssssss"
android:textColor="#fff"
android:textSize="16sp" >
</TextView>
</RelativeLayout>
I figured out how to do it programatically. Simply, you want to subtract the widths and padding of the surrounding views from the size of the container view, and set the leftover value to the text view's width. Here is an example:
int view_length = personViewHolder.container.getWidth() - personViewHolder.container.getPaddingStart() - personViewHolder.container.getPaddingEnd();
view_length = view_length - personViewHolder.object_to_left.getWidth() - personViewHolder.object_to_left.getPaddingStart() -personViewHolder.object_to_left.getPaddingEnd();
view_length = view_length - personViewHolder.object_to_right.getWidth() - personViewHolder.object_to_right.getPaddingStart() - personViewHolder.object_to_right.getPaddingEnd();
personViewHolder.view_to_set_width.getLayoutParams().width = view_length;
personViewHolder.view_to_set_width.invalidate();
You can place the views in a RelativeLayout (if they are not already in one), then and use the ToStartOf or ToEndOf attributes to align one of them to the start or end of the other. You could also use ToLeftOf or ToRightOf, but this is not recommended because in some locales you want the user to read from right to left instead of left to right. This will ensure that the two views never overlap (assuming you haven't placed negative margins on either of the views). This can be extended to as many views as you want, as long as you correctly configure their alignment attributes.
I have 4 Relative layouts : ( as you can see in the animation)
The green RelativeView
The "type something & icons" RelativeView
The gray speperator RelativeView
The bottom Textview
Each RelativeView is "below" it's previous relative view.
By design , when the 2 inner views are closed , the button should be half top above the green , and half bottom above the text ( just like the animation shows)
Ok , So I added a button which is found inside the "bottom textview"
But in order for the bottom to be only half bottom above the view , I added it a negative Margin :
So here it is without the negative margin :
And here it is with the negative margin ( the desired result)
So when I clicked the button I simply hide/show ( + animation with android:animateLayoutChanges="true") the inner 2 middle views
So where is the problem ?
Question
I don't know why but only the bottom half of the button is clickable ! I guess it is because that half is inside its container view while the top half is not in its view...( maybe i'm wrong)
But if I remove the negative margin and the button is fully in its container - then the button is 100% fully clickeable ( both top half and bottom half)
As you can see in the animation (last frames) - when i click the top half - nothing happens....
How can I fix that ?
Maybe i've taken a wrong initial approach ?
nb : some more visualization of structure :
Have your button as a sibling to the RelativeLayouts rather than as a child. This works as you want it to.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">![enter image description here][1]
<RelativeLayout
android:id="#+id/red"
android:background="#android:color/holo_red_dark"
android:layout_width="match_parent"
android:layout_height="100dp">
</RelativeLayout>
<RelativeLayout
android:id="#+id/green"
android:layout_below="#id/red"
android:background="#android:color/holo_green_dark"
android:layout_width="match_parent"
android:layout_height="100dp">
</RelativeLayout>
<RelativeLayout
android:id="#+id/blue"
android:background="#android:color/holo_blue_dark"
android:layout_below="#id/green"
android:layout_width="match_parent"
android:layout_height="100dp">
</RelativeLayout>
<Button
android:id="#+id/button"
android:layout_centerHorizontal="true"
android:layout_below="#id/green"
android:layout_width="wrap_content"
android:text="Hide Green"
android:layout_marginTop="-24dp"
android:layout_height="wrap_content"/>
</RelativeLayout>
Looks like this and the button moves up/down as setVisibility is toggled between GONE/VISIBLE for green RelativeLayout
Your button belongs to bottom RL. When android routes ACTION_DOWN it checks layout's borders and gives events to viewgrops (VG) which have event coordinates inside. Then VG proporate event to it's children based on it's coordinates.
So when you click on upper part of your button touch event given to grey RL and button which belonges to blue RL doesn't get it. Actually event given to Window -> Root ViewGroup -> Some Other ViewGroup -> View. And routing happens base on coordinates. It is true for ACTION_DOWN which starts touch, but not all MotionEvent processed this way.
As a solution, you can move button to another groupview which can route touch event properly. Or maybe try to use touch delegates.
I need to align button,and textview in on same line,button aligned right side and textview also aligned right side,
I tried lot of methods but aligned first textview then aligned button,
how to solve this problem please any one help and solve my problem in programatically,
aligned success in layout xml design but I need it programatically.
place both views inside your layout and set orientation to "horizontal".
<LinearLayout>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
linear layout can also be nested into one another!
if you want to implement more lines of views then you could just define a vertical layout (the main.xml will by default define one for you when first created) and inside that vertical linear layout just insert how many horizontal linear layouts (like the one I written above) as you wish.
Something like this should work. You should modify this to fit your needs (i.e. set the proper text size, width, height, etc).
TextView tv = new TextView(this);
tv.setText("Text");
Button bt = new Button(this);
bt.setText("Button");
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
ll.addView(tv);
ll.addView(bt);
setContentView(ll);
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical">
<ScrollView android:id="#+id/scroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:fillViewport="true">
<adam.music.testfont.NwcDrawingArea android:id="#+id/NwcDrawingArea"
android:layout_height="2000dp"
android:layout_width="2000dp"
/>
</ScrollView>
</LinearLayout>
I created Android Project and edited main.xml as above.
And then I customized view to draw image.
To see the effect of scrolling customized view I set width and height as above.
Now I can see the image in a customized view but it doesn't scroll.
Could you help me what the problem is?
Should I add something more?
There's an interplay between ScrollView and its contents. For example, if, instead of your NwcDrawingArea widget, you inserted this TextView into your ScrollView:
<TextView android:text="8This is a lot of text 7This is a lot of text 6This is a lot of text 5This is a lot of text 4This is a lot of text 3This is a lot of text 2This is a lot of text 1This is a lot of text"
android:layout_width="10dp"
android:layout_height="2000dp"
android:background="#FF00FF00"
/>
You'll see a skinny green vertical TextView whose text is longer than the screen, and the ScrollView shows scrollbars that let you see the hidden part of the TextView to the extent of the text. Now, change the TextView layout_width="2000dp". The TextView becomes a full-screen green area that has a single line of text that runs off the right side of the screen. ScrollView, of course, shows no horizontal scroll bars. However, ScrollView shows no vertical scroll bars either, even though we sized the TextView to be much longer than the screen. ScrollView is attempting to determine the visually interesting portion of its contents, so you need to understand the behavior for whatever widget you are subclassing.
For example, ScrollView respects the layout sizes of LinearLayout and RelativeLayout in the way that you expected it to behave with TextView. In fact, it is common to make a LinearLayout or RelativeLayout -- rather than a view such as TextView -- the child of a ScrollView. Drop your TextView in a fixed-height LinearLayout and you should get the behavior that you expected.