2015-08-15 44 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(); 
    } 

}