This question has been edited for the second time: To view the original question, please Scroll down to where it says “ORIGINAL QUESTION” – for any edits after that – Please scroll down to an “EDIT #” section.
EDIT TWO:
This edit is in reponse to Luksprog’s request to see where I set elements required in getView() – After checks for convertView being null or not.
Note : Please understand that this code is semi-modular.
CODE:
Holder Patterns Used:
public static class HeaderHolder
{
public TextView textView;
}
public static class CommandHolder
{
public TextView textView;
public Button[] buttonHolder;
public OnClickListener[] clickHolder;
}
getView() Method – Where the setting takes place:
switch(type)
{
case 0: // Is a header
String temp = commandLabel.replace("Section:", "");
headerHolder.textView.setText(temp);
break;
case 1:// Is a command
commandHolder.textView.setText(commandLabel);
ArrayList<String[]> commands = commandCreator.getCommands();
// Initially set the visibility of buttons to GONE
for (int i = 0; i <commandHolder.buttonHolder.length; i++)
{
commandHolder.buttonHolder[i].setVisibility(View.GONE);
}
// Only show buttons based on how many commands there are
for (int i = 0; i < commands.size(); i++)
{
pos = i;
commandHolder.buttonHolder[i].setVisibility(View.VISIBLE);
drawable_normal = commands.get(i)[1];
drawable_pressed = commands.get(i)[1] + "_pressed";
buttonStates = new StateListDrawable();
buttonStates.addState(new int[]{statePressed}, ApplicationConstants.moduleImageLoader.findImageByName(drawable_pressed));
buttonStates.addState(new int[]{-statePressed}, ApplicationConstants.moduleImageLoader.findImageByName(drawable_normal));
buttonStates.addState(new int[]{}, ApplicationConstants.moduleImageLoader.findImageByName(drawable_normal));
commandHolder.buttonHolder[i].setBackgroundDrawable(buttonStates);
// Retrieve the intent and parameter from the current command
String parameter = commands.get(i)[2];
String intentName = commands.get(i)[0];
if(intentName.contains("Call Phone"))
{
commandHolder.clickHolder[i] = new OnClickListener()
{
public void onClick(View arg0)
{
//con.startActivity(call_phone);
}
};
}
else if(intentName.contains("Cell"))
{
commandHolder.clickHolder[i] = new OnClickListener()
{
public void onClick(View arg0)
{
//con.startActivity(call_cell);
}
};
}
else if(intentName.contains("Map"))
{
commandHolder.clickHolder[i] = new OnClickListener()
{
public void onClick(View arg0)
{
//con.startActivity(load_map);
}
};
}
else if(intentName.contains("Email"))
{
commandHolder.clickHolder[i] = new OnClickListener()
{
public void onClick(View arg0)
{
//con.startActivity(send_email);
}};
}
commandHolder.buttonHolder[i].setOnClickListener(commandHolder.clickHolder[i]);
}
convertView.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
Dialog dialog = new Dialog(ApplicationConstants.ref_currentActivity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
LinearLayout listDialogBoxlayout = new ListDialogBox(con, commandType, commandLabel, commandInfo);
dialog.setContentView(listDialogBoxlayout);
dialog.setCancelable(true);
dialog.show();
}
});
break;
}
return convertView;
Question : To see the problem occurring visually. Please scroll down to EDIT ONE and look at the screen shots.
If anyone has any questions, or needs clarification, please leave a comment and I will get back to you.
EDIT ONE:
Made Changes , but still the same behaviour
Here’s the new implementation of the getView() method using getItemViewType():
I do the following checks:
if(convertView == null)
{
switch type
case header:
convertView = inflate a header
headerHolder.textView = convertView.findViewById(headerTextId);
convertView.setTag(headerHolder);
break;
case command:
convertView = inflate a command
// Use CommandHolder to initialize all the necessary elements
commandHolder.textView = convertView.findViewById(commandLabel);
.
.
convertView.setTag(commandHolder);
break;
}
else
{
switch(type)
case header :
headerHolder = convertView.getTag();
break;
case command :
commandHolder = convertView.getTag();
break;
}
// set the actual elements
switch(type)
case:header
//set all elements in header
break;
case: command
//set all elements in command
break;
return convertView;
What’s happening:
I’m a visual person, so I thought this would help:
Here’s some screen shots:
No scrolling – Everything looks great

Scrolling with mouse scroll, everything still looks great

Scrolling by clicking on the list and dragging it down – Notice how canam is now at the bottom, where Linda should be?

Scrolling by clicking on the list and dragging it up – Notice how peter is at the top where canam should be?

List of what should be there:
- Address Header
- Canam
- Employees Header
- Dave
- Brent
- Stephen
- Moacir
- Peter
- Linda
Even though the views get messed up – clicking the views shows the correct dialog box pop up- As you can see above.
Here’s whats not happening:
- No repeating views
- No section headers being drawn in the wrong places
- No section headers being drawn as commands(which can be addresses or contacts).
I feel like I’m right there guys..
What could I have missed?
Original Question:
This is currently what I am doing: I’ve simplified the situation to really just ask my question with convertView and not possibly confuse people with the rest of my ViewCreators.
Methods that my ListViewAdapter has:
getItemViewType(...)
getViewTypeCount(...)
getView(int position, View convertView, ViewGroup parent)
{
int type = getItemViewType(position);
if(listItem is section)
{
if(convertView == null)
{
ViewGroup viewGroup = inflate a view
Holder.textView = textview;
viewgroup.setTag(holder);
view = viewGroup;
}
else
{
holder = (HeaderHolder) convertView.getTag();
view = convertView;
}
}
else
// different layout. Complicated list item in the form:
//|TextView Button1 Button2 Button3| , where buttons only appear based on
//a CommandCreator. If john(TextView) has a phone and email - it displays:
// |John PhoneButton EmailButton|
{
if(convertView == null)
{
// inflate view
// make buttons
// make onclicks null
// set different holder
viewgroup.setTag(holder)
view = viewgroup;
}
else
{
view = convertView;
holder = (CommandHolder) convertView.getTag();
}
// set the buttons to show based on commands
// set the onclick listeners to the buttons to call certain intents based on the command
}
return view;
}
}
Question:
How should I use getItemViewType and getViewTypeCount? and How do I use Viewgroups, and my current holders? Would the following work?
getView
{
type = getItemViewType;
if(convertView == null)
{
switch(type)
case: header
convertView = inflate header view
intialize HeaderHolder
break;
case: command
convertView = inflate command view
initialize CommandHolder
break;
}
else
{
switch(type)
case: header
//Actually set all the HeaderHolder Stuff
String temp = commandLabel.replace("Section:", "");
holder.textView.setText(temp);
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
holder.textView.setLayoutParams(textViewParams);
return view;
QUESTION : But how do I use Viewgroups, and my holder. and what am I returning?
break;
case: command
Actually set all the commandHolder stuff
QUESTION : Same as above.
break;
}
return convertView?
}
Here are my Handlers now:
public static class HeaderHolder
{
public TextView textView;
}
public static class CommandHolder
{
public TextView textView;
public Button[] buttonHolder;
public OnClickListener[] clickHolder;
}
Thank you for all your help in advance! and I will answer any questions you may have.
About those two methods:
getViewTypeCount() return the number of types of layouts, 2 in your case
getItemViewType() based on the
intparameter supplied you either return0(for the header layout for example) or1(for the normal row layout). This really depends on your data and how you setup the headers and normal rows in the list.Regarding your last edit, you probably don’t set the data on the row layout like you should, especially as you have references to those
OnClickListeners. You should post the full code from this block:Here is a sample code I wrote with an example implementing multiple
ViewHoldersand different row layouts types(if you have problems regarding this aspect of the adapters).