I have a ScrollView defined in a layout which contains the ImageSwitcher
now when a user presses next button or previous button i am changing the images inside
ImageSwitcher dynamically.
Now the issues is i have a different size of images one is short in height and another is long in height. so when first short image is displayed and then long and if i go back then scroll view is occupying the height of long image rather then dimension of short image.
here is my layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFFFFF" >
<ScrollView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:layout_below="#+id/headerBar"
android:visibility="gone"
android:id="#+id/helpPanel"
>
<ImageSwitcher android:id="#+id/switcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</ScrollView>
</RelativeLayout>
Related
In a layout file I have a Listview whose size can grow/shrink dynamically. I have a button btn_rec_add and it's click event I add an item in the ListView. I have tried many changes in the Layout file but haven't been able to make the button shift its location based on number of items in the ListView. If I keep the button in the same RelativeLayout which has the ListView, then the button moves dynamically which is exactly how I want but I can't see the button after adding 5 or more elements in 4.3 inch display phones. If I keep the button outside the RelativeLayout of the ListView, then it is fixed on the screen.
Currently, the btn_rec_add is fixed to the bottom of the layout. Can someone please help me solve this problem.
Here is the XML code:
<?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="#drawable/bg" >
<ImageView
android:id="#id/top_bar_view"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/top_bar"
android:contentDescription="#string/content" />
<TextView
android:id="#+id/txt_recipients"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:padding="8dp"
android:text="#string/text_recipients"
android:textColor="#FFFFFF"
android:textSize="16sp" />
<ImageButton
android:id="#id/btn_back"
android:layout_width="80dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="#string/content"
android:paddingTop="6dp"
android:src="#drawable/ic_back" />
<RelativeLayout
android:id="#+id/Rlayout_recipients"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/btn_rec_add"
android:layout_alignParentLeft="true"
android:layout_below="#id/top_bar_view" >
<ListView
android:id="#+id/rec_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#null"
android:dividerHeight="0dp"
android:paddingTop="20dp" />
</RelativeLayout>
<ImageButton
android:id="#+id/btn_rec_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:contentDescription="#string/content"
android:src="#drawable/icon_add" />
</RelativeLayout>
If I understand correctly, you want the behavior of the button to be as follows:
Appear below the last ListView item if the ListView does not extend to fill screen
If the ListView extends the full height of the screen, the button should be at the bottom of the screen, but the list should remain scrollable
If my understanding is correct, you should place your ListView and your button in a LinearLayout as follows:
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:layout_width="match_parent"
android:layout_height="#dimen/button_height"
android:background="#drawable/button_image" />
</LinearLayout>
The effect of the above layout is as follows:
Layout in which items are vertically placed
Layout which will be as wide as parent, but as tall as ListView and Button
ListView will take up all of the space in the layout that the button does not occupy (this is layout_weight="1" whereas Button has no layout weight so it will simply fill as much space as it needs as defined in this case by #dimen/button_height)
Great Android layout question!
Your Problem is related to User Experience.
You have to decide whether user will like to scroll to end of the list to press add button
or user want to add without scrolling to end of list.
Since you only have two options with our scenario,
either keep add button fixed or add it as footer of listview.
As of right now I have a to-do list style app where there is an edittext and button and top and the user would add to the listview by putting input into it. Well if the user puts enough lines into the listview, the listview would be scrollable to see all of the items in it. The only problem is making sure that the button and Ad at the bottom of the screen don't go with it.
Basically, how would one lock some views with a scrollable feature above it?
This is how my xml looks if it helps:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/artport">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_alignParentRight="true"
android:id="#+id/bAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add" />
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/bAdd"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/bAdd"
android:contentDescription="#string/addItemContentDescription"
android:ems="10"
android:hint="#string/addItemHint" />
</RelativeLayout>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="center">
<Button
android:id="#+id/bClearedList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/ad"
android:text="Completed list" />
<com.google.ads.AdView
android:id="#+id/ad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="ca-app-pub-XXXXXXXXXXXXXXXXX/XXXXXXXXXXX"
ads:loadAdOnCreate="true"
android:layout_alignParentBottom="true">
</com.google.ads.AdView>
</RelativeLayout>
Depending upon your need, you could specify the height of the ListView. ListViews are by default scrollable. In your case, when you specify "wrap_content", it expands to occupy as much screen space as possible to display the list and then (since LinearLayout takes an "eldest child wins" approach), the remaining widgets below the ListView get hidden once the list becomes big enough. When you specify the height the ListView would occupy that size even if it's contents are not big enough to fill that size (thereby having some empty space).
Another approach would be to put the ListView within a LinearLayout and then the lower two buttons in another LinearLayout and specify the height of the lower container so that it always occupies that height and the by setting the height of the LinearLayout container that holds the ListView to "match_parent" you could make it occupy the remaining space.
Try to change the parameters of your ListView. Set layout_weight="1" and your ListView will get the remaining space.
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
/>
I'm trying to create a layout which consists of one long image which should be scrolled vertically only.
I.e. - it should stretch to take the whole screen width and stretch for the full height.
My layout does this, but it creates strange gaps before and after the image. Each gap takes about 2/3 of the screen and can be scrolled down.
How can I remove the gaps so that only the ImageView appears on the screen?
My activity XML is like this:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="0dp" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
tools:context=".HelpActivity" >
<ImageView
android:id="#+id/imageHelp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:src="#drawable/tutorial_with_text" />
</LinearLayout>
</ScrollView>
Found the solution: For future reference:
Use android:adjustViewBounds="true" on the ImageView
The usual question regarding ScrollViews seems to be how to use fillViewport to let the ScrollView stretch to the whole screen. My problem is similar, but going the other way :)
I got a LinearLayout that contains multiple elements. All except one element have a fixed height, the special one is an ImageView that should stretch to fill the remaining space. This works fine :)
Now I want to put the LinearLayout into a ScrollView, as some of my elements should expand at runtime (e.g. click on "more"-icon that expands a TextView). In the unexpanded version I would like to have all elements fit on the screen, as if the ScrollView wouldn't exist.
Unfortunately, when wrapping the ScrollView around the LinearLayout, the ImageView is scaled to maxSize und the screen does not fit the screen. Do you have any ideas how to achieve my goal?
I reproduced the problem in an example app to share it with you:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#ffff0000"
android:scaleType="fitCenter"
android:src="#drawable/background" />
<TextView
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#ff00ff00"
android:text="element 2"
tools:context=".MainActivity" />
<TextView
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#ff00ff00"
android:text="element 1"
tools:context=".MainActivity" />
</LinearLayout>
</ScrollView>
Here are the screenshots from the two versions:
The one above is the Layout with ScrollView (notice the scrollbar and cropping on element 1), the one below without.
Update: The original height of the image in the image-view is bigger than the screen. So it should be downscaled (that's why it has weight 1 and scaleType set).
Solution: The following code solved the problem for me (based on Luksprog answer)
Main Activity (excerpt, change of layout is induced by click on ImageView):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = (ScrollView) findViewById(R.id.scroller);
frame = (FrameLayout) findViewById(R.id.frame);
layout = (LinearLayout) findViewById(R.id.layout);
final ImageView image = (ImageView) findViewById(R.id.image);
image.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageView image = (ImageView) findViewById(R.id.image);
frame.removeView(layout);
scrollView.addView(layout);
image.getLayoutParams().height = image.getHeight();
}
});
}
Layout XML file
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ScrollView
android:id="#+id/scroller"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:fillViewport="true"
>
</ScrollView>
<LinearLayout
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#ffff0000"
android:scaleType="fitCenter"
android:src="#drawable/background" />
<TextView
android:id="#+id/text1"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#ff00ff00"
android:text="element 2"
tools:context=".MainActivity" />
<TextView
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#ff00ff00"
android:text="element 1"
tools:context=".MainActivity" />
<TextView
android:layout_width="fill_parent"
android:layout_weight="0.1"
android:layout_height="0px"
android:background="#ff00ff00"
android:text="element 3"
tools:context=".MainActivity" />
</LinearLayout>
</FrameLayout>
As I said in my comments, I don't know if what you're trying to do is possible at the xml level. One option would be to modify your current layout and add a root FrameLayout to which you'll, initially, add the ScrollView and above it, the LinearLayout. In this position the ImageView will behave as you want as the user didn't modify the layout. When you need to show more in your layout you'll detach the LinearLayout from the view hierarchy(with removeView) and attach it to the ScrollView(with addView). You'll reverse this when the user goes back to the initial layout.
This will make the ImageView to have different heights when making the views switch so you'd want to get the height of the ImageView and re set it when doing the switch. To get the height, you could do it in a listener or using the post method in onCreate(as the views haven't been laid out yet at that moment). Also, remember that the user could turn the phone, I don't know if this will affect your layout, but take it consideration.
Firstly i tried running your code and it didn't cause any issue for me. The scrollView did not show up although the image was scaled to a ScreenHeight-160dp height which i expected because you have used weight 1 for this imageview.
I would suggest that you remove the weight and give height as wrapcontent. In that case the Imageview will just enclose the Image. When it becomes bigger in size, automatically scrollview come into use if the total heights of all screen contents is more than the screenheight.
I have the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:isScrollContainer="true"
android:orientation="vertical">
<Gallery
android:id="#+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="bottom" />
<LinearLayout
android:id="#+id/chart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal" />
</LinearLayout>
Gallery is filled at runtime and when the user taps on an item I fill the LinearLayout with a series of images.
I would like to scroll vertically but if I add a ScrollView when the user taps the Gallery the LinearLayout is not filled anymore.
Is it normal? How can I add a vertical scroll?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ScrollView android:id="#+id/ScrlView" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<LinearLayout android:id="#+id/layoutForScroll" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="wrap_content"
>
<Gallery android:id="#+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="bottom"/>
<LinearLayout android:id="#+id/chart" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Your vertical scroll view can only have one child, which means you need to envelop your gallery view and the linear view "chart" with another linerLayout which then should be enveloped with a scrollView.
When you add your new views, you may need to refresh the drawable state of the scroll view or invalidate it, try something like that, so that it expands accordingly.
You have to extend the Gallery class and in the Draw procedure rotate the canvas for 90 degrees. Then just a few adoptions like modifying the onTouch event and a few more is required. After this there will be a few problems with the layout (since it still wants to draw in the layout in its parameters). So I put it inside a LinearLayout and fixed the layout size in that.
So the final vertical gallery is actually a linear layout which has a gallery put inside it. I have implemented it, and it works quite well. You will only need to rotate everything you put in it for 90 degrees to the other direction. The trade off is really a little thus you can extend every view you want to put inside it and just rotate it to the other direction in the draw procedure.