I'm trying to mimic the behaviour of the HTC SMS application (tradional view), where all messages are shown, and an EditTextis shown below. As you can see in the screenshot, when scrolling upwards, the EditText scrolls away at the bottom.
I'm stuck with this, even after reading multiple posts (eg Android Layout with ListView and Buttons and this website: http://www.finalconcept.com.au/article/view/android-keeping-buttons-visible), it's not working as expected.
Thanks to the comments and EditText now showing under ListView, I've managed to have my ListView take all available space and start scrolling once completed. The EditText is showing at the bottom of the screen now - always. I'd like it to disappear at the bottom when I scroll up though - now it remains at the bottom
Current Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/android:list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<TableLayout
android:layout_weight="0"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow>
<EditText android:id="#+id/newmessagecontent"
android:layout_height="150dp"
android:singleLine="false"
android:gravity="top"
android:layout_width="250dp"
android:layout_alignParentTop="true"
/>
<Button android:layout_height="wrap_content"
android:id="#+id/sendmessage"
android:text="Send"
android:layout_width="wrap_content"
/>
</TableRow>
</TableLayout>
</LinearLayout>
i think what you need to implement here is some sort of modification of the SeparatedListAdapter from Jeff Sharkey from this Article. In this article he not only manages to add two Adapters to a ListView but also explains how to have Headers to separate them if you want (you can remove that part of the code).
So what i mean, is your first Adapter will be the data with It's rows, and the second Adapter will be a dummy one with no data that just points to a View with your controls or whatever.
this way the ListView and what you want to add at the bottom are gonna be all scrollable.
Hope this helps.
A ListView automatically scrolls if all the items in it take up more space than the view provides. What happens if you remove the ScrollView?
Related
Is it possible to populate a the same listview with 4 different sources?
at the moment my design is a
textview
listview
textview
listview
what i dont like is the two listview scroll indepently so if the top one is almost empty i have alot of empty space on my screen,
if I dont set the top one to a fixed size and it is very full, the bottom one is not shown.
I would like to have one listview/scrollview so everything is arranged nicely indepent on how many entries are in either of the arrays i use to populate my listviews.
can that be done?
thanks
this is my xml as mention above
<TextView
android:id="#+id/gamesView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/top_btns"
android:gravity="center"
android:text="#string/gamesView"
android:textColor="#FFFFFF"/>
<ListView
android:id="#+id/gameslist"
android:layout_width="match_parent"
android:layout_height="260dip"
android:layout_below="#id/gamesView" />
<TextView
android:id="#+id/finishedGamesView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/gameslist"
android:gravity="center"
android:text="#string/endedGamesView"
android:textColor="#FFFFFF"/>
<ListView
android:id="#+id/finishedgameslist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/finishedGamesView" />
I know that everyone's recommended that we should never use ListView and ScrollView together, and I totally agree. However, I'm currently stuck with a very simple pattern like 8tracks' profile page (as shown in the image below), which include an area for the user profile and a list of mixes they made. So basically, it's desirable that users can just scroll down that page, which means the profile part will get on top of the screen and gradually out of view, and at the same time the below list is scrolled too:
However, at the moment, all I can do is to include a ListView within a LinearLayout, just like my sketch here.
With this design, I can only scroll the list down, while the profile area stays at the same place, which sucks. So I'm looking for any idea to make the whole page scrollable, not just the list. Please help and thanks.
EDITED: I'm sorry for the misleading question. My problem is even more complicated because the content of the tabs are not just ListView - some tab contains LinearLayout or GridView instead. Again, what I want to achieve is to make the whole page scrollable, but ScrollView can't help because if the content of a tab is a ListView or GridView, these views will be collapsed and more importantly - this goes against the design rule.
I know this is late, but I'm the current developer for 8tracks. The (old) 2.x app you have shown above is being rewritten, but I can show you what the old dev did for the profile page.
Before going into that I must say that this is not the best way to do this, but the 8tracks app (2.x) is old.
So back to the code…
The ProfileActivity contains a ProfileFragment.
The main layout you see with the Follow button (and the profile image) is this:
<?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="match_parent"
android:orientation="vertical" >
<!-- Image, name, location -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dip" >
<com.gdub.widget.ImageViewClickable
android:id="#+id/dj_avatar"
android:layout_width="110dip"
android:layout_height="110dip"
android:layout_marginRight="10dip"
android:background="#drawable/default_avatar_max200"
android:scaleType="centerCrop" />
<com.gdub.widget.CollapsingTextView
android:id="#+id/dj_location"
style="#style/mix.counts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:layout_toRightOf="#id/dj_avatar" />
<ViewSwitcher
android:id="#+id/profile_action_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/dj_location"
android:layout_toRightOf="#id/dj_avatar" >
<Button
android:id="#+id/follow_btn"
style="#style/white_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/follow" />
<Button
android:id="#+id/edit_profile_btn"
style="#style/white_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/edit_profile" />
</ViewSwitcher>
</RelativeLayout>
<TextView
android:id="#+id/dj_bio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-25dip"
android:gravity="left|center_vertical"
android:lineSpacingExtra="2dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:textColor="#color/default_text"
android:textSize="15sp" />
<include
android:id="#+id/profile_tabs"
layout="#layout/profile_tabs" />
</LinearLayout>
And profile_tabs…
<?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:visibility="gone"
android:orientation="horizontal">
<include
android:id="#+id/profile_mixes_button"
layout="#layout/profile_tab" />
<include
android:id="#+id/profile_followers_button"
layout="#layout/profile_tab" />
<include
android:id="#+id/profile_following_button"
layout="#layout/profile_tab" />
</LinearLayout>
So as you can see it's a regular layout with three buttons "simulating" tabs.
The contents of the tabs is also dictated by a ViewSwitcher:
<?xml version="1.0" encoding="utf-8"?>
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/profile_view_switcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inAnimation="#anim/fade_in_300"
android:outAnimation="#anim/fade_out_300"
android:background="#color/white">
<include
android:id="#+id/profile_loading"
layout="#layout/loading_view_full" />
<ListView
android:id="#+id/profile_content_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#00000000"
android:divider="#null"
android:dividerHeight="0dip"
android:fadingEdge="none" />
</ViewSwitcher>
That shows a loading wheel and then switches to the listview. There is no other scrollable ViewGroup.
And that's basically it.
Now if you wanted to make the WHOLE thing scroll, then you need to use a custom adapter and set the above layout as the Header (or at least use getItemType in the adapter in a clever way). That way the whole screen is a List (with all the optimizations a list has).
We (ab)use this in the new 8tracks App under dev. ;)
Try to use the following on your listview.
listview.addHeaderView(v);
Also rememeber, you must call this method before calling setAdapter() on your listview.
include your linearlayout where you have the user details and the tabs and add it as a header to the list.
You can try to make the profile and the tabs the header of the listview, then updating the contents of the listview when the tabs are pressed. I don't know if you want the tabs to disappear from view as you scroll, though.
According to the UI guide lines and best practices, it is advisable not to use Scrollable content inside Scrollview and doing that prevents the scrolling of the Scrollable content.
When you put two scrollview android just get confused which scroll view is touched. So sometimes it gets unable to deliver touch event.
But if still you want to achieve the scrolling functionality you can manage it by using the onTouch event of the particular view. And you need to design your layout accordingly.
But even if the requirement forces you to make such layouts. Try this…
Say case is somewhat like this….
<ScrollView android:id=”#+id/parent_scroll”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:layout_weight=”1″
android:background=”#drawable/dotted_bg”
android:focusableInTouchMode=”false”>
<LinearLayout />
<LinearLayout />
<LinearLayout >
<ScrollView android:id=”#+id/child_scroll”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:background=”#drawable/text_box_bg”>
<TextView android:id=”#+id/text_description”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:textColor=”#color/gray”
android:textSize=”12dip”
android:padding=”5dip”
android:scrollbars=”vertical”/>
<!–ScrollView>
</LinearLayout>
Step 1 : Provide unique id to both the scrollview.
Step 2 : get reference of that two scrollview in your activity.
parentScroll=(ScrollView)findViewById(R.id.parent_scroll);
childScroll=(ScrollView)findViewById(R.id.child_scroll);
Step 3: Now set touch listeners for both.
parentScroll.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
Log.v(TAG,”PARENT TOUCH”);
findViewById(R.id.child_scroll).getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
});
childScroll.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event)
{
Log.v(TAG,”CHILD TOUCH”);
// Disallow the touch request for parent scroll on touch of child view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
I hope it will help you.
I'm trying to make a layout similar to the people app, so I have a list with a fixed header at the top. I define the header on top of the listview inside a relative layout but the "glow effect" at the top of the list is only for the listview and not the whole layout.
This is what I have:
and this is what I want:
This is my layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:minHeight="20dp"
android:orientation="vertical" >
<TextView
android:id="#+id/status_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/last_updated"
android:textSize="12sp"
android:textStyle="bold"
android:textAllCaps="true"
android:gravity="center|left"
android:layout_marginLeft="20dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
android:textColor="#color/nice_blue"
/>
<View style="#style/HeaderDivider"/>
</LinearLayout>
<ListView
android:id="#+id/status_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:headerDividersEnabled="false"
android:footerDividersEnabled="false"
android:layout_below="#+id/header_layout" >
</ListView>
The glow effect in both examples are functioning the same.
What is happening within the People application is that it is also a ListView just like yours. The effect happens in the same place. The Me, #, A, etc headers are actually inside the ListView.
Option 1
To do what you are looking to do, put a header in the ListView, you'll also need to create a custom ListView. This means extending ListView.
It sounds more challenging than it is, but you should be able to find a number of examples online. Look for examples that extend a ListView rather than creating a custom ListView.
The general idea is that you'll add in a TextView into the the View of the ListView that will act as your header. This will put the header text Last updated at inside of the ListView view that you've created and since it is inside, it will be included underneath the glow.
Option 2
You may be able to use the addHeaderView(View v, Object data, boolean isSelectable) or addHeaderView(View v) methods on the ListView itself.
I believe this will add a header row inside the ListView, but I've never used this so I can't say for sure how it works. This may be easier, but will be less flexible.
Is it possible to have a custom expandable list view in android with scrollview?
ListView already have scrollView associated with it, you can use MergeAdapter to achieve this
I don't think any of you got his question right! He is asking about the "expandable" list view. Anyways I also seem to be having the same doubt.
I still think the answer is NO.
You may be able to use custom views and them inflate them into an already existent layout element which will give you the same effect. And I think that solution will be better.
ExpandableListView has its own listview. You don't have to integrate another listview on it. Notice that if you have a long list, vertical scroll is associated automatically.
combination of listview withing scrollview is not happening to be good option. if you will place any listview within scroll view the listview will not scroll. Its seeming to be officialy said by google android programmer that this will be a bad user experience.
Of course, combination of expandable listview withing VERTICAL scrollview is not happening to be good option, but using it within HorizontalScrollView works impressive. I use this method in my program. User can horizontally scroll long strings.
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
android:id="#+id/RelativeView01"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<Button
android:id="#+id/btnSaveSelection"
android:layout_alignParentLeft="true"
android:layout_width="100dip"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:text="#string/SaveSelection"
android:focusable="true"
android:background="#drawable/android_button"
android:onClick="myClickHandler14" />
.........
<HorizontalScrollView
android:id="#+id/HorizontalScrollView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:scrollbars="horizontal|vertical"
android:layout_above="#id/button_add_group"
android:layout_alignParentTop="true">
<LinearLayout android:id="#+id/LinearLayout02"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<ExpandableListView android:id="#+id/android:list"
android:layout_width="750px"
android:layout_height="wrap_content"
android:groupIndicator="#android:color/transparent" />
<TextView android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000000"
android:text="#string/no_data"/>
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
I am trying to port an existing iPhone application to android. I wish to have a button scroll into view at the bottom of a GridView to enable the user to load more data from the server. Presently, my solution simply fixes a button at the bottom of the screen instead of having it scroll into view.
Here is my layout code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:columnWidth="70dp"
android:numColumns="auto_fit"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="#000000"
/>
<Button
android:id="#+id/load_more"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Load More"
/>
</LinearLayout>
Fixing the button at the bottom of the screen won't work because I plan on placing an ad at the bottom.
Can anyone either explain conceptually how to get a load more button to scroll into view, or point me to some sample code, OR tell me why this is not idiomatic to Android and what other UI convention it uses to load more data in a GridView?
Thanks!
You can place a ScrollView inside your main LinearLayout. A ScrollView can only have one direct child, though, so you'll need to put another LinearLayout inside of it which would then contain your GridView and Button.
I had a similar problem with scrolling a GridView and after refreshing the underlying data, noticing that the scoll was not reset to the beginning. I solved it with the following code fragment
gvKeys.setSelection(0);
I'm guessing that if you know the number of items in your grid, N, that the following will work:
gvKeys.setSelection(N);