问题
I want create the custom list to inflate the different data for each row by grouping the data I managed to get each section headers by the type of Data but I want to add the footer for each section as well. I don't know how to execute it
I tried to return the section footer by getitemviewtype() but it has to be return in everyitem type so don't know how to execute it
public override View GetView(int position, View convertView, ViewGroup parent)
{
programTabAllItemHolder programTabAllItemHolder;
View view = convertView;
if (view == null)
{
programTabAllItemHolder = new programTabAllItemHolder();
if (GetItemViewType(position) == 0)
{
view = LayoutInflater.From(context).Inflate(Resource.Layout.FTSProgramItemLayout, parent, false);
programTabAllItemHolder.searchprogramdate = view.FindViewById<TextView>(Resource.Id.searchdate);
programTabAllItemHolder.searchprogramtime = view.FindViewById<TextView>(Resource.Id.searchtime);
programTabAllItemHolder.searchProgramTitle = view.FindViewById<TextView>(Resource.Id.searchprogramtitle);
programTabAllItemHolder.linearsearchdatetime = view.FindViewById<RelativeLayout>(Resource.Id.linearsearchdatetime);
programTabAllItemHolder.programseparator = view.FindViewById<View>(Resource.Id.programline);
programTabAllItemHolder.searchprogramresults = view.FindViewById<TextView>(Resource.Id.searchprogramresults);
}
else if (GetItemViewType(position) == 1)
{
view = LayoutInflater.From(context).Inflate(Resource.Layout.FTSParticipantItemLayout, parent, false);
programTabAllItemHolder.initialsView = view.FindViewById<TextView>(Resource.Id.searchparticipantinitialsView);
programTabAllItemHolder.Listimageview = view.FindViewById<ImageView>(Resource.Id.searchparticipantlistimageView);
programTabAllItemHolder.searchParticipantTitle = view.FindViewById<TextView>(Resource.Id.searchparticipanttitle);
programTabAllItemHolder.searchparticipantresults = view.FindViewById<TextView>(Resource.Id.searchparticipantresults);
}
else if (GetItemViewType(position) == 2)
{
view = LayoutInflater.From(context).Inflate(Resource.Layout.FTSInformationItemLayout, parent, false);
programTabAllItemHolder.searchinformationlistimageView = view.FindViewById<ImageView>(Resource.Id.searchinformationlistimageView);
programTabAllItemHolder.searchinformationtitle = view.FindViewById<TextView>(Resource.Id.searchinformationtitle);
programTabAllItemHolder.searchinformationresults = view.FindViewById<TextView>(Resource.Id.searchinformationresults);
}
view = LayoutInflater.From(context).Inflate(Resource.Layout.SearchFooterView, parent, false);
programTabAllItemHolder.searchfooterview = view.FindViewById<LinearLayout>(Resource.Id.ftsfooterview);
view.Tag = programTabAllItemHolder;
}
else
{
programTabAllItemHolder = view.Tag as programTabAllItemHolder;
}
if (GetItemViewType(position) == 0)
{
// setColorsforprogram
SetViewStyleforProgram(programTabAllItemHolder);
programTabAllItemHolder.searchProgramTitle.Text = programVTs[position].Title;
programTabAllItemHolder.searchprogramdate.Text = programVTs[position].StartDate.ToString("dd MMM");
programTabAllItemHolder.searchprogramtime.Text = programVTs[position].StartDate.ToString("hh:mm tt");
}
// participant view
else if (GetItemViewType(position) == 1)
{
programTabAllItemHolder.searchParticipantTitle.Text = programVTs[position].FirstName + programVTs[position].LastName;
//If profile icon is missing then show initials of First Name and Last Name ahead
if (string.IsNullOrEmpty(programVTs[position].IconUrl))
{
programTabAllItemHolder.Listimageview.Visibility = ViewStates.Gone;
programTabAllItemHolder.initialsView.Visibility = ViewStates.Visible;
programTabAllItemHolder.initialsView.Text = Utils.getUserFirstandLastChar(programVTs[position].FirstName, programVTs[position].LastName);
programTabAllItemHolder.initialsView.SetTextColor(Color.ParseColor(Utils.topNavForegroundColor));
//Round background image of initials
GradientDrawable initialsShape = new GradientDrawable();
initialsShape.SetShape(ShapeType.Oval);
initialsShape.SetCornerRadius(100f);
initialsShape.SetColor(Color.ParseColor(Utils.topNavBackgroundColor));
initialsShape.SetStroke(1, Color.ParseColor(Utils.topNavBackgroundColor));
//Invert the colors if theme is light
if (!Util.IsColorDark(Color.ParseColor(Utils.topNavBackgroundColor)))
{
initialsShape.SetColor(Color.ParseColor(Utils.topNavForegroundColor));
initialsShape.SetStroke(1, Color.ParseColor(Utils.topNavForegroundColor));
programTabAllItemHolder.initialsView.SetTextColor(Color.ParseColor(Utils.topNavBackgroundColor));
}
programTabAllItemHolder.initialsView.SetBackgroundDrawable(initialsShape);
}
else
{
programTabAllItemHolder.initialsView.Visibility = ViewStates.Gone;
MyApp.picassoWithCache.Load(programVTs[position].IconUrl).Into(programTabAllItemHolder.Listimageview);
}
//int check = position + 1;
//if ( check%3 == 0)
//{
// programTabAllItemHolder.seachparticipantsshowmore.Visibility = ViewStates.Visible;
//}
}
else if (GetItemViewType(position) == 2)
{
programTabAllItemHolder.searchinformationtitle.Text = programVTs[position].Title;
if (string.IsNullOrEmpty(programVTs[position].IconUrl))
{
programTabAllItemHolder.searchinformationlistimageView.SetImageResource(Resource.Drawable.linked_info_default_icon);
}
else
{
MyApp.picassoWithCache.Load(programVTs[position].IconUrl).Into(programTabAllItemHolder.searchinformationlistimageView);
}
}
return view;
}
回答1:
You can create a custom view, inflate it then can use like this:
View headerView = getLayoutInflater().inflate(R.layout.listview_header, null);
listView.addHeaderView(headerView);
For more information, you can check this link
回答2:
There are a number of ways to achieve this but because you don't give any code examples for your Adapter and data structure so it is difficult to give an exact answer.
Edit Update After getView
was added:
It looks like your Data Structure is an Array of Objects
You just need to Override the getItemViewType
method as I did below to return the right type for the contents of the Current Object.
This could be done by adding a new member variable to you Object to indicate the row type.
e.g. programVTs[position].rowType
with values of 0 or 1 or 2 depending on row type
Then your getItemViewType
could look something like:-
@Override
public int getItemViewType(int position) {
return programVTs[position].rowType;
}
OR
I think you could deduce the row type from the content
pseudocode below for getItemViewType
if (programVTs[position].Title and programVTs[position].StartDate are not null or empty)
return 0;
else if (programVTs[position].FirstName and programVTs[position].LastName are not null or empty)
return 1;
else return 2;
End Update
BUT there is a common theme on how section headers are usually added.
Section headers are usually inserted as normal listview rows in the dataset but are a different Object type or has addition member variable to denote they are a header.
When the getView
method of the Adapter processes the item it checks the Object type or member variable to format that row as a normal item or section header row.
This method can easily be expanded to add footers as well, you need to insert an extra data item that has the properties that cause getView
to treat it like a footer.
One way of doing it:- Create some Java objects for Header and Footers Rows (Normal rows just use a String Object) Create a list of generic Objects for your Adapter to process Then the Adapter checks the type of Object is in the list and processes accordingly
public class Footer {
public String itemText;
public Footer(String text){
itemText = text;
}
}
public class Header {
public String itemText;
public Header(String text){
itemText = text;
}
}
public class ItemAdapter extends BaseAdapter {
private ArrayList<Object> mData;
private LayoutInflater mInflater;
private static final int NORMAL_ITEM = 0;
private static final int HEADER_ITEM = 1;
private static final int FOOTER_ITEM = 2;
public ItemAdapter(Context context, ArrayList<Object> data){
mData = data;
mInflater = (LayoutInflater.from(context));
}
@Override
public int getCount(){
return mData.size();
}
@Override
public Object getItem(int position){
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public int getItemViewType(int position) {
Object mObject = getItem(position);
if (mObject instanceof String){
return NORMAL_ITEM;
} else if (mObject instanceof Header) {
return HEADER_ITEM;
} else if (mObject instanceof Footer) {
return FOOTER_ITEM;
} else {
return IGNORE_ITEM_VIEW_TYPE;
}
}
public View getView(int position, View convertView, ViewGroup parent) {
int rowType = getItemViewType(position);
Object object = getItem(position);
View view;
TextView textView;
// In this simple case all row items are inflated as Textview's to contain the string
// With the background color changed after inflation
// But each object could use a different layout for each object type
// e.g An ImageView, etc
switch (rowType) {
case NORMAL_ITEM:
view = mInflater.inflate(R.layout.list_item, parent, false);
textView = (TextView) view.findViewById(R.id.list_item);
textView.setText((String) object);
break;
case HEADER_ITEM:
view = mInflater.inflate(R.layout.list_item, parent, false);
textView = (TextView) view.findViewById(R.id.list_item);
// Set the background to red because it is a Header row
textView.setBackgroundColor(Color.RED);
// Cast the object from generic list to Header type
Header header = (Header) object;
textView.setText(header.itemText);
break;
case FOOTER_ITEM:
view = mInflater.inflate(R.layout.list_item, parent, false);
textView = (TextView) view.findViewById(R.id.list_item);
// Set the background to green because it is a Header row
textView.setBackgroundColor(Color.GREEN);
Footer footer = (Footer) object;
textView.setText(footer.itemText);
break;
default:
return convertView;
}
return view;
}
}
public class MainActivity extends AppCompatActivity {
private ItemAdapter mAdapter;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the dataset for the Adapter
ArrayList<Object> mList = new ArrayList<Object>();
mList.add(new Header("Header 1"));
mList.add("Item 1");
mList.add("Item 2");
mList.add(new Footer("Footer 1"));
mList.add(new Header("Header 2"));
mList.add("Item 3");
mList.add(new Footer("Footer 2"));
// Create Adapter
mAdapter = new ItemAdapter(this, mList);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(mAdapter);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/list_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
This will produce a view like
来源:https://stackoverflow.com/questions/57873565/android-listview-with-section-headers-and-footers