0

此问题已被第二次编辑:要查看原始问题,请向下滚动到显示“原始问题”的位置 - 对于之后的任何编辑 - 请向下滚动到“编辑 #”部分。

编辑二:

此编辑是为了响应 Luksprog 的请求,以查看我在 getView() 中设置所需元素的位置 - 在检查 convertView 是否为空之后。

注意:请理解此代码是半模块化的。

代码:

使用的持有人模式:

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 并查看屏幕截图。

如果有人有任何问题或需要澄清,请发表评论,我会尽快回复您。

编辑一: Made Changes ,但仍然是相同的行为

下面是使用 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 在 canam 应该位于的顶部的位置?

在此处输入图像描述

应该有的清单:

  1. 地址头
  2. 卡南
  3. 员工页眉
  4. 戴夫
  5. 布伦特
  6. 斯蒂芬
  7. 莫阿希尔
  8. 彼得
  9. 琳达

即使视图搞砸了——单击视图会弹出正确的对话框——如上所示。

这是没有发生的事情:

  1. 无重复视图
  2. 没有在错误的地方绘制节标题
  3. 没有部分标题被绘制为命令(可以是地址或联系人)。

我觉得我就在那里,伙计们.. 我会错过什么?


原始问题:

这就是我目前正在做的事情:我已经简化了情况,实际上只是用 convertView 提出我的问题,而不会将人们与我的其他 ViewCreators 混淆。

我的 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;
}

感谢您提前提供的所有帮助!我会回答你可能有的任何问题。

4

2 回答 2

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;
于 2012-11-11T18:46:41.617 回答
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;

是我编写的示例代码,其中包含实现多种ViewHolders不同行布局类型的示例(如果您在适配器的这方面有问题)。

于 2012-11-11T18:38:03.813 回答