此问题已经第二次编辑:要查看原始问题,请向下滚动到“原始问题”的位置 - 对于之后的任何修改 - 请向下滚动到“编辑#”部分
编辑二:
此编辑响应Luksprog的请求,以查看我在getView()中设置所需元素的位置 - 检查convertView是否为null。
注意:请理解此代码是半模块化的。
CODE:
使用的持有人模式:
public static class HeaderHolder
{
public TextView textView;
}
public static class CommandHolder
{
public TextView textView;
public Button[] buttonHolder;
public OnClickListener[] clickHolder;
}
getView()方法 - 设置的位置:
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;
问题:看到问题在视觉上发生。请向下滚动到EDIT ONE并查看屏幕截图。
如果有任何问题或需要澄清,请发表评论,我会尽快回复。
编辑一个: 做出改变,但仍然是相同的行为
这是使用getItemViewType()的getView()方法的新实现: 我做了以下检查:
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;
发生了什么:
我是一个视觉人,所以我认为这会有所帮助: 这是一些屏幕截图: 没有滚动 - 一切看起来都很棒
使用鼠标滚动滚动,一切看起来都很棒
通过单击列表并向下拖动来滚动 - 注意canam现在位于底部,Linda应该在哪里?
通过单击列表并向上拖动来滚动 - 请注意peter应该位于哪个顶部?
应该在哪里列出:
即使视图搞砸了 - 单击视图会弹出正确的对话框 - 如上所示。
以下是没有发生的事情:
我觉得我就在那里.. 我可以错过什么?
原始问题:
这正是我正在做的事情:我已经简化了这种情况,只是用convertView问我的问题,而不是把人与其余的ViewCreator混淆。
我的ListViewAdapter具有的方法:
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;
}
}
问题: 我应该如何使用getItemViewType和getViewTypeCount?以及如何使用Viewgroups和我目前的持有者?以下是否有效?
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?
}
以下是我的处理程序:
public static class HeaderHolder
{
public TextView textView;
}
public static class CommandHolder
{
public TextView textView;
public Button[] buttonHolder;
public OnClickListener[] clickHolder;
}
提前感谢您的帮助!我会回答你的任何问题。
答案 0 :(得分:1)
关于这两种方法:
getViewTypeCount()返回布局类型的数量,在您的情况下为2
getItemViewType()根据您提供的int
参数返回0
(例如标题布局)或1
(对于正常的行布局)。这实际上取决于您的数据以及如何在列表中设置标题和正常行。
关于上次编辑,您可能不会像应该那样在行布局上设置数据,尤其是当您引用这些OnClickListeners
时。您应该发布此块中的完整代码:
// set the actual elements
switch(type)
case:header
//set all elements in header
break;
case: command
//set all elements in command
break;
Here是我编写的示例代码,其中包含一个实现多个ViewHolders
和不同行布局类型的示例(如果您在适配器的这方面遇到问题)。
答案 1 :(得分:1)
尝试此代码可能会对您有所帮助......
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 : {
if(convertView.getTag() instanceOf HeaderHolder){
headerHolder = convertView.getTag();
} else {
headerHolder = inflate a header
convertView.setTag(headerHolder);
}
}
break;
case command : {
commandHolder = convertView.getTag();
if(convertView.getTag() instanceOf CommandHolder){
commandHolder = convertView.getTag();
} else {
commandHolder = inflate a command
convertView.setTag(commandHolder );
}
}
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;