Reputation: 14591
I have a layout inflater and a custom arrayAdapter which create a scrolling listview. I want to keep the scrolling listview, but add a navigation bar (tablerow with image buttons or something) to the top and bottom which are independent of the scrolled list. How could I do that?
This is what I want to do:
+--------------------------------------+
| fixed nav bar |
+--------------------------------------+
| scroll listview item |
|--------------------------------------|
| scroll listview item |
|--------------------------------------|
| scroll listview item |
|--------------------------------------|
| scroll listview item |
+--------------------------------------+
| fixed nav bar |
+--------------------------------------+
This is how I'm instantiating the listAdapter, But I want the addHeaderView() to stay fixed when the the list scrolls:
String [] list_array = new String [mCursor.getCount ()];
View vh = getLayoutInflater ().inflate (R.layout.tabtwo_header, null);
ListView lv = getListView ();
lv.addHeaderView (vh);
setListAdapter (new dynAdap (this, android.R.layout.simple_list_item_1, list_array));
My xml layout for the listview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical">
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:padding="10dip"
android:layout_width="fill_parent"
android:gravity="left|center"
android:textSize="22sp"
android:textStyle="bold"
android:drawableRight="@drawable/next_icon"
android:text="Name Name"
android:id="@+id/tv_ListItem"
android:background="@drawable/xml_tabtwo">
</TextView>
</LinearLayout>
The ArrayAdapter:
public class dynAdap extends ArrayAdapter<String>
{
String [] list;
public dynAdap (Context context, int textViewResourceId, String [] objects)
{
super (context, textViewResourceId, objects);
list = objects;
}
@Override
public View getView (int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = getLayoutInflater ();
View row = inflater.inflate (LAYOUT_TABTWO, parent, false);
TextView tv1 = (TextView) row.findViewById (R.id.tv_ListItem);
tv1.setText (list[position]);
return row;
}
}
Upvotes: 0
Views: 3049
Reputation: 14591
Ok finally got this working. Maximus and OcuS, thanks for all your help. I was a big help. Also got lots of info and examples from these two websites:
Here is a working example. Hope it helps out anyone else who is trying to do the same thing.
The files to do it:
myList.java
The main activity. Extends ListActivity and includes a custom adapter which is used to populate the list.
drawable/xml_listitem_shape.xml
This controls the Pressed, Selected and Normal states of the list items using gradient 'shapes' instead of images. The gradients allow for faster rendering, and are not specific to the device, so it gets you away from the multiple-image mess (hdpi, mdp, ldpi...)
layout/main.xml
Contains the layout for the Header, Footer and Listview objects. Does not use any selector files, but declares android:id/list as an ID for the listview object, which is required. Android will complain about not finding this ID if you do not do it.
layout/menu_item.xml
Contains only a TextView object for use by the dynAdap class (no layout needed). This file declares the xml_listitem_shape selector file as it's background, which defines how the listitem will appear in it's various states.
values/colors.xml
Color definitions used throughout the application. You can hard code your colors, but this file keeps things much cleaner.
myList.java
package com.test.listview;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class myList extends ListActivity
{
public final String TAG = "** myList **";
String[] mNames = new String[] {
"Linux", "Plan9", "Eclipse", "Java","Ubuntu", "Next", "Android", "Xoom", "Pascal", "Assembly",
"C++", "Perl", "Bash", "Korn", "Int3", "CS:IP" };
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView (R.layout.main);
Button b1 = (Button) findViewById (R.id.button1);
Button b2 = (Button) findViewById (R.id.button2);
Button b3 = (Button) findViewById (R.id.button3);
Button b4 = (Button) findViewById (R.id.button4);
ListView listView = getListView();
setListAdapter (new dynAdap (this, android.R.layout.simple_list_item_1, mNames));
listView.setOnItemClickListener (oicl);
b1.setOnClickListener (ocl);
b2.setOnClickListener (ocl);
b3.setOnClickListener (ocl);
b4.setOnClickListener (ocl);
}
/*
* listener for buttons
*/
OnClickListener ocl = new OnClickListener()
{
@Override
public void onClick (View v)
{
String b = new String ("");
switch (v.getId ())
{
case R.id.button1:
b = "button1";
break;
case R.id.button2:
b = "button2";
break;
case R.id.button3:
b = "button3";
break;
case R.id.button4:
b = "button4";
break;
}
Toast.makeText (myList.this, b, Toast.LENGTH_SHORT).show();
}
};
/*
* listener for listview clicks - pop up toast to show what was selected
*/
OnItemClickListener oicl = new OnItemClickListener()
{
@Override
public void onItemClick (AdapterView<?> parent, View view, int index, long id)
{
Toast.makeText (myList.this, mNames[index], Toast.LENGTH_SHORT).show();
}
};
/*
* This is a custom list adapter to set the color and text content of each list item
*/
public class dynAdap extends ArrayAdapter<String>
{
String [] list;
public dynAdap (Context context, int textViewResourceId, String [] objects)
{
super (context, textViewResourceId, objects);
list = objects;
}
@Override
public View getView (int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = getLayoutInflater ();
// return the view associated with the TextView in the menu_item.xml file
View row = inflater.inflate (R.layout.menu_item, parent, false);
TextView tv1 = (TextView) row.findViewById (R.id.tv_item);
tv1.setText (list[position]);
return row;
}
}
}
xml_listitem_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed state of item -->
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="@color/DkRed"
android:endColor="@color/Red"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/LightGreen" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<!-- focused state of item -->
<item android:state_selected="true" >
<shape>
<gradient
android:endColor="@color/Silver"
android:startColor="@color/Gray"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/Red" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<!-- normal state of item -->
<item>
<shape>
<gradient
android:endColor="@color/White"
android:startColor="@color/Silver"
android:angle="270" />
<stroke
android:width="3dp"
android:color="@color/LightBlue" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/top_control_bar">
<TableRow
android:id="@+id/tableRow1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="@color/LightBlue"
android:gravity="center"
android:padding="5dip">
<Button
android:text="Button"
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
<Button
android:text="Button"
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
<Button
android:text="Button"
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
</TableRow>
</RelativeLayout>
<LinearLayout
android:id="@+id/bottom_control_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/LightBlue"
android:padding="10dip">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Add Item"
android:id="@+id/button4" />
</LinearLayout>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:choiceMode="multipleChoice"
android:layout_below="@id/top_control_bar"
android:layout_above="@id/bottom_control_bar"
android:background="@color/Silver">
</ListView>
</RelativeLayout>
menu_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:paddingTop="20dip"
android:paddingBottom="20dip"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#000000"
android:background="@drawable/xml_listitem_shape"
android:text="Fooooooo"
android:textSize="22dip"
android:id="@+id/tv_item" />
colors.xml
<resources>
<color
name="transparent">#00000000</color>
<!-- colors used in application -->
<color
name="Black">#000000</color>
<color
name="DkRed">#660000</color>
<color
name="Red">#b70101</color>
<color
name="White">#f7f5e8</color>
<color
name="Silver">#c8c5bb</color>
<color
name="Gray">#6e6a5b</color>
<color
name="Yellow">#f6f900</color>
<color
name="Orange">#ff9000</color>
<color
name="LightGreen">#00ff00</color>
<color
name="Green">#085c00</color>
<color
name="Gold">#ccaf00</color>
<color
name="LightBlue">#0077ff</color>
<color
name="Blue">#000077</color>
<color
name="LightCyan">#00ffff</color>
<color
name="Cyan">#007777</color>
</resources>
Upvotes: 2
Reputation: 8431
If you use a LinearLayout with the top View having weight of 0, the ListView having a weight of 1 and the bottom View having a weight of 0, it would work just fine.
I always forget the Header and Footer views of a ListView, so OcuS's post is definitely a way to go, especially if you're extending ListActivitiy.
In any event, here's a VERY simple layout example. The TextViews could be replaced with lot's of other things... an additional horizontal LinearLayout for example.
Remember, this is the layout you'd set as your content view in your main activity. If your main activity is extending ListActivity you would not use this.
<?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" >
<TextView android:id="@+id/toplabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:text="Test"/>
<ListView android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView android:id="@+id/bottomtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
</LinearLayout>
Upvotes: 1