2015-08-15 42 views
2

我有一个列表视图,它从一个arrayList中加载项目,问题出现在使用onLongClickItemListener时 每当一个项目被长时间点击时,我会在该项目本身中显示一个隐藏的布局。因此,无论何时列表正在回收物品,隐藏的布局对于被回收的物品(应该不显示布局)都是可见的。onLongItemClick影响回收的视图

任何想法?我试图给列表中每个项目的对象本身添加一个标志,但没有运气,我能得到的最多的是让滚动时显示的每个项目的布局消失,但我想保留已打开的项目由用户保持可见。

这里是我当前的代码:

messageListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 
      @Override 
      public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 

       LinearLayout ll = (LinearLayout) view.findViewById(R.id.hiddenLayout); 
       if (ll.getVisibility() == View.VISIBLE) { 
        ll.setVisibility(View.GONE); 
        msgs.get(position).setViewFlag(false); 
        msgAdapter.setMessages(msgs); 
       } else { 
        ll.setVisibility(View.VISIBLE); 
        msgs.get(position).setViewFlag(true); 
        msgAdapter.setMessages(msgs); 
       } 
       return true; 
      } 
     }); 

而这里的适配器的代码:

public class MessagesAdapter extends BaseAdapter { 

     private static int lastPos = -1; 
     private ArrayList<Message> messages; 
     private Context context; 



    public MessagesAdapter(ArrayList<Message> messages, Context context) { 
     this.messages = messages; 
     this.context = context; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     if (convertView == null) { 
      LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
      convertView = inflater.inflate(R.layout.message_list_row, null); 

      ViewHolder viewHolder = new ViewHolder(); 

      viewHolder.title = (TextView) convertView.findViewById(R.id.msgTitle); 
      viewHolder.body = (TextView) convertView.findViewById(R.id.msgBody); 
      viewHolder.monthDate = (TextView) convertView.findViewById(R.id.monthDate); 
      viewHolder.dayDate = (TextView) convertView.findViewById(R.id.dayDate); 
      viewHolder.status = (ImageView) convertView.findViewById(R.id.statusIcon); 
      viewHolder.linearLayout = (LinearLayout) convertView.findViewById(R.id.hiddenLayout); 
      viewHolder.linearLayout.setVisibility(View.GONE); 

      convertView.setTag(viewHolder); 
     } 

     ViewHolder holder = (ViewHolder) convertView.getTag(); 

     if (!(messages.get(position).isViewFlag())) 
      holder.linearLayout.setVisibility(View.GONE); 

     holder.title.setText(messages.get(position).getTitle()); 
     holder.body.setText(messages.get(position).getBody()); 
     switch (messages.get(position).getMessageType()) { 
      case READ: 
       holder.status.setBackgroundResource(R.drawable.yellowcircle); 
       break; 
      case UNREAD: 
       holder.status.setBackgroundResource(R.drawable.redcircle); 
       break; 
     } 
     lastPos = position; 
     return convertView; 
    } 

    @Override 
    public int getCount() { 
     return messages.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return messages.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 

    static class ViewHolder { 
     public TextView title; 
     public TextView body; 
     public TextView dayDate; 
     public TextView monthDate; 
     public ImageView status; 
     public TextView read; 
     public TextView unread; 
     public TextView remove; 
     public TextView reply; 
     public LinearLayout linearLayout; 

    } 

    public void setMessages(ArrayList<Message> msgs) { 
     this.messages = msgs; 
    } 

} 
+1

你必须在'Message'类中添加一个布尔标志 – pskink

回答

1

这不是一个好主意,修改的ListView直接内部意见的知名度。作为一般模式,您需要更新备份ListView的数据 - 您的案例中的消息数组。您需要在Message中设置isViewFlag属性,而不是尝试更改视图上的可见性,而您无法控制哪个项目正在使用。

你的点击处理程序将只是做(并按照适配器的变化以及):

@Override 
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 
    msgAdapter.setExpandedPosition(msgAdapter.getExpandedPosition() == position ? -1 : position); 
    return true; 
} 

然而,因为这是不确实取决于你的项目的属性的UI状态,而是基于用户与UI的交互,有人可能会争辩(包括我在内),这些信息不属于此处。我将在适配器中设置属性(如果只有一个项目可以在特定时间处于扩展状态)或属性列表(如稀疏数组)(如果多个项目可以在相同时间处于扩展状态) 。

适配器会是这样的(也请不改变原来的getItemId()setMessages()不具有任何与在手的问题,但都只是很好的做法):

public class MessagesAdapter extends BaseAdapter { 
    // for Option1 - only one item expanded at a time 
    int expandedPos = -1; 
    .... 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     .... 
     //Option 1 - only one item expanded at a time 
     holder.linearLayout.setVisibility(position == expandedPos ? View.GONE : View.VISIBLE); 
     //Option 2 - multiple items can be expanded at the same time, following your current implementation 
     holder.linearLayout.setVisibility(messages.get(position).isViewFlag() ? View.VISIBLE : View.GONE); 
     .... 
    } 

    public void setExpandedPosition(int position) { 
     //Option 1 - only one item expanded at a time 
     expandedPos = position; 

     //Option 2 - multiple items can be expanded at the same time, following your current implementation 
     messages.get(position).setIsViewFlag(position != -1); 

     // In both cases: 
     notifyDataSetChanged(); 
    } 


    // only for Option 1 - only one item expanded at a time 
    public int getExpandedPosition() { 
     return expandedPos; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    public void setMessages(ArrayList<Message> msgs) { 
     this.messages = msgs; 
     notifyDataSetChanged(); 
    } 

}