可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to show a button under a ListView
. Problem is, if the ListView
gets extended (items added...), the button is pushed out of the screen.
I tried a LinearLayout
with weights (as suggested in Android: why is there no maxHeight for a View?), but either I got the weights wrong or it simply didn't work.
Also, I found somewhere the hint to use a RelativeLayout
. The ListView
would then be set above the button with the android:layout_above
param.
Problem with this is that I don't know how to position the button afterwards. In the example I found, the View below the ListView
was adjusted using android:layout_alignParentBottom
, but I don't want my button to cling to the bottom of the screen.
Any ideas apart from using setHeight-method and some calculating of the required space?
Edit:
I got a lot of useful answers.
bigstone's & user639183's solution almost worked perfectly. However, I had to add an extra padding/margin to the bottom of the button, as it still would be pushed half way out of the screen (but then stopped)
Adinia's answer with the relative layout only is fine if you want the button fixed to the bottom of the screen. It's not what I intended but still might be useful for others.
AngeloS's solution was the one I chose at the end as it just created the effects I wanted. However, I made two minor changes to the LinearLayout
around the button:
First, as I didn't want to have any absolute values in my layout, I changed android:layout_height="45px"
to wrap_content
, which works just fine as well.
Second, as I wanted the button to be centered horizontally, which is only supported by vertical LinearLayout
, I changed android:orientation="horizontal" to "vertical".
AngeloS also stated in his initial post that he was not sure if the android:layout_weight="0.1"
param in the LinearLayout
around the ListView
had any effect; I just tried and it actually does! Without, the button gets pushed out of the screen again.
回答1:
I had this exact issue and to solve it I created two seperate LinearLayouts
to house the ListView
and Button
respectively. From there I put both in another Linear Layout
and set that container's android:orientation
to vertical
. I also set the weight of the the LinearLayout
that housed the ListView
to 0.1
but I dont know if that has any effect. From there, you can set the height of the bottom container (that has your button) to whatever height you would like.
EDIT this is what i mean:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
>
<ListView android:id="@+id/ListView01"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:dividerHeight="2px">
</ListView>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="45px"
android:background="@drawable/drawable"
>
<Button android:background="@drawable/btn_more2"
android:id="@+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:paddingRight="20px"
/>
</LinearLayout>
</LinearLayout>
The above solution will fix the button the the bottom of the screen.
To have the button float at the bottom of the list, change the height of ListView01
to wrap_content
:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
>
<ListView android:id="@+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:dividerHeight="2px">
</ListView>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="45px"
android:background="@drawable/drawable"
>
<Button android:background="@drawable/btn_more2"
android:id="@+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:paddingRight="20px"
/>
</LinearLayout>
</LinearLayout>
回答2:
I solved this problem in code, setting height of listview only if it has more than 5 items in it:
if(adapter.getCount() > 5){
View item = adapter.getView(0, null, listView);
item.measure(0, 0);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, (int) (5.5 * item.getMeasuredHeight()));
listView.setLayoutParams(params);
}
Notice that I set the max height to 5.5 times the height of a single item, so the user will know for sure there is some scrolling to do! :)
回答3:
On your last edit, you just have to also add android:layout_above="@+id/butt1"
in your ListView code.
And to show you(and everybody here who tried an answer earlier) that you really don't need to use more than one RelativeLayout
, here is your corrected code:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bkg">
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TextView1"
android:layout_alignParentTop="true">
</TextView>
<TextView
android:id="@+id/textView2"
android:layout_below="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TextView2"
android:layout_centerHorizontal="true">
</TextView>
<Button
android:id="@+id/butt1"
android:text="string/string3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true">
</Button>
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dip"
android:layout_marginBottom="2dip"
android:drawSelectorOnTop="false"
android:visibility="visible"
android:layout_below="@+id/textView2"
android:layout_above="@+id/butt1" />
</RelativeLayout>
and the result, using some random list:
回答4:
Using LinearLayout
, set the height of your ListView
and Button
to wrap_content
and add a weight=1 to ListView
. This should work as you want.
And yes, set the layout_gravity
of the Button
to bottom
回答5:
RelativeLayout
is a solution, if you don't want the button to stay too close to the bottom you can add margins (padding a button would break it because it uses a 9-patch background, and it sets its own padding).
It would be the same if you used a LinearLayout
: the way to achieve what you want is to set the ListView
to a height=0 and weight=1, and for the button height=wrap_content and weight=0. (setting both to wrap_content, as user639183 said, would not limit ListView
's height).
回答6:
Found a way to do this without using nested containers, inspired from AngeloS's solution.
I used a LinearLayout
with a vertical orientation, that has a ListView
and a button. I set the android:layout_weight="0.1"
for the ListView
.
It manages to get the button stick to the bottom of the list always. And the button does not get pushed off the screen when the list grows.
<ListView
android:id="@+id/notes_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
/>
<Button
android:id="@+id/create_note_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onCreateButtonClicked"
android:text="@string/create_notes"
/>
回答7:
You can probably make this work using nested containers. It's possible that you might need to wrap the Button in a second (inner) container so that it takes up more space, and just align the Button to the top of the inner container.
Possible something like this:
RelativeLayout
-- ListView
-- RelativeLayout
---- Button
Using the different alignment options on the two containers, you should be able to get this to work.
回答8:
This is the cleanest way to do it:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/ListView01"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:dividerHeight="2px">
</ListView>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/drawable"
>
<Button android:background="@drawable/btn_more2"
android:id="@+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="20px"
/>
</LinearLayout>
</LinearLayout>
It is similar to Angelos's solution but you don't need the linearlayout that wraps up the ListView. Also you can use a FrameLayout which is lighter compare to a LinearLayout to wrap up the Button.
回答9:
The idea is outlined in the very good solutions by:
They both seem to work perfectly at least on v4.4.3.
I still had to spend some time writing test code to check it out and confirm each method. Below is the self contained, minimal test code required.
Layout is based on Sparkle's solution, as it contains fewer nested layout. Also has been updated to reflect the current LINT checks.
<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:orientation="vertical"
tools:context="MainActivity" >
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Grow List"
tools:ignore="HardcodedText" />
</LinearLayout>
Activity provides the boilerplate code to test the solution for yourself.
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listview = (ListView)findViewById(R.id.listview);
final ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
new ArrayList<String>());
adapter.setNotifyOnChange(true);
listview.setAdapter(adapter);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int count = adapter.getCount();
adapter.add(String.valueOf(count));
listview.setSelection(count);
}
});
}
}
Feel free to add or improve as this is "community wiki".
回答10:
Try to use RelativeLayout with button in the bottom. Set the height of the layout as "wrap_content".
I haven't tried it. Just idea
回答11:
in LinearLayout, just add android:layout_weight="1"
to you ListView
回答12:
Following is what worked for me...
if(adapter.getCount() > 3){
View item = adapter.getView(0, null, impDateListView);
item.measure(0, 0);
LayoutParams params = impDateListView.getLayoutParams();
params.width = LayoutParams.MATCH_PARENT;
params.height = 3 * item.getMeasuredHeight();
impDateListView.setLayoutParams(params);
}
Note : The params.width =... Needs to be set also...
The above example is when you use TableRow and ListView inside TableRow...
回答13:
wrap content in linear layout
in List View add:
android:layout_weight="1"
in your Button set fixed height
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/my_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="50dp"/>
</LinearLayout>
回答14:
If you want the content below the list view to move down as elements are added to the list, try this solution:
Add positive padding to the bottom of the list view and negative padding to the top of the "footer". This will work in a linear layout or a relative layout.
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="50dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-50dp"/>
回答15:
Since there's no MaxHeight attribute, your best bet is either to set the height of the ListView to a set value, or to use wrap_content
.
回答16:
I solved this by putting the ListView inside a ScrollView. Lint didn't like it, but by adding a minHeight and setting the fillViewport to true, I have a nice result.
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:minHeight="100dp"
android:fillViewport="true"
android:fadeScrollbars="false"
android:paddingTop="2dp"
android:orientation="vertical"
android:scrollbarAlwaysDrawVerticalTrack="true" >
<ListView
android:id="@+id/workoutAElistRoutines"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
android:background="@drawable/dialog_inner_border_tan"
android:choiceMode="singleChoice"
android:orientation="vertical"
android:paddingLeft="3dp"
android:paddingRight="3dp" >
</ListView>
</ScrollView>