2016-06-26 66 views
1

以下是我完整的sendbird聊天適配器類。每個消息都顯示帶時間的日期。 viewHolder.getView("left_time")viewHolder.getView("right_time")是用於顯示日期和時間的視圖,並且它是在方法getDisplayDateTime中計算的。我希望只有當日期有變化時才顯示帶有時間的日期。例如,如果有一組日期爲6月23日的消息,則日期隨時間應僅在第6日23日發佈的第一封郵件中顯示。適配器 - 僅在值發生更改時才顯示視圖

我試着這樣做,通過檢測日期的變化,將日期存儲在xyz變量中,並將其與每個消息的日期進行比較,並且每當它們不相等時,就可以使該消息的日期視圖可見並將新日期分配給xyz變量與未來消息進行比較。但是,當我向下滾動並向上滾動列表時,此方法失敗。 實現此目標的理想方法是什麼?

public class SendBirdMessagingAdapter extends BaseAdapter { 
    private static final int TYPE_UNSUPPORTED = 0; 
    private static final int TYPE_MESSAGE = 1; 
    private static final int TYPE_SYSTEM_MESSAGE = 2; 
    private static final int TYPE_FILELINK = 3; 
    private static final int TYPE_BROADCAST_MESSAGE = 4; 
    private static final int TYPE_TYPING_INDICATOR = 5; 
    private final Context mContext; 
    private final LayoutInflater mInflater; 
    private final ArrayList<Object> mItemList; 
    private Hashtable<String, Long> mReadStatus; 
    private Hashtable<String, Long> mTypeStatus; 
    private List<MessagingChannel.Member> mMembers; 
    private long mMaxMessageTimestamp = Long.MIN_VALUE; 
    private long mMinMessageTimestamp = Long.MAX_VALUE; 
    public SendBirdMessagingAdapter(Context context) { 
     mContext = context; 
     mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     mItemList = new ArrayList<Object>(); 
     mReadStatus = new Hashtable<String, Long>(); 
     mTypeStatus = new Hashtable<String, Long>(); 
    } 
    @Override 
    public int getCount() { 
     return mItemList.size() + ((mTypeStatus.size() <= 0) ? 0 : 1); 
    } 
    @Override 
    public Object getItem(int position) { 
     if (position >= mItemList.size()) { 
      ArrayList<String> names = new ArrayList<String>(); 
      for (MessagingChannel.Member member : mMembers) { 
       if (mTypeStatus.containsKey(member.getId())) { 
        names.add(member.getName()); 
       } 
      } 
      return names; 
     } 
     return mItemList.get(position); 
    } 
    public void delete(Object object) { 
     mItemList.remove(object); 
    } 
    public void clear() { 
     mMaxMessageTimestamp = Long.MIN_VALUE; 
     mMinMessageTimestamp = Long.MAX_VALUE; 
     mReadStatus.clear(); 
     mTypeStatus.clear(); 
     mItemList.clear(); 
    } 
    public void resetReadStatus(Hashtable<String, Long> readStatus) { 
     mReadStatus = readStatus; 
    } 
    public void setReadStatus(String userId, long timestamp) { 
     if (mReadStatus.get(userId) == null || mReadStatus.get(userId) < timestamp) { 
      mReadStatus.put(userId, timestamp); 
     } 
    } 
    public void setTypeStatus(String userId, long timestamp) { 
     if (userId.equals(SendBird.getUserId())) { 
      return; 
     } 
     if (timestamp <= 0) { 
      mTypeStatus.remove(userId); 
     } else { 
      mTypeStatus.put(userId, timestamp); 
     } 
    } 
    @Override 
    public long getItemId(int position) { 
     return position; 
    } 
    public void addMessageModel(MessageModel messageModel) { 
     if (messageModel.isPast()) { 
      mItemList.add(0, messageModel); 
     } else { 
      mItemList.add(messageModel); 
     } 
     updateMessageTimestamp(messageModel); 
    } 
    private void updateMessageTimestamp(MessageModel model) { 
     mMaxMessageTimestamp = mMaxMessageTimestamp < model.getTimestamp() ? model.getTimestamp() : mMaxMessageTimestamp; 
     mMinMessageTimestamp = mMinMessageTimestamp > model.getTimestamp() ? model.getTimestamp() : mMinMessageTimestamp; 
    } 
    public long getMaxMessageTimestamp() { 
     return mMaxMessageTimestamp == Long.MIN_VALUE ? Long.MAX_VALUE : mMaxMessageTimestamp; 
    } 
    public long getMinMessageTimestamp() { 
     return mMinMessageTimestamp == Long.MAX_VALUE ? Long.MIN_VALUE : mMinMessageTimestamp; 
    } 
    public void setMembers(List<MessagingChannel.Member> members) { 
     mMembers = members; 
    } 
    @Override 
    public int getItemViewType(int position) { 
     if (position >= mItemList.size()) { 
      return TYPE_TYPING_INDICATOR; 
     } 
     Object item = mItemList.get(position); 
     if (item instanceof Message) { 
      return TYPE_MESSAGE; 
     } else if (item instanceof FileLink) { 
      return TYPE_FILELINK; 
     } else if (item instanceof SystemMessage) { 
      return TYPE_SYSTEM_MESSAGE; 
     } else if (item instanceof BroadcastMessage) { 
      return TYPE_BROADCAST_MESSAGE; 
     } 
     return TYPE_UNSUPPORTED; 
    } 
    @Override 
    public int getViewTypeCount() { 
     return 6; 
    } 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder viewHolder; 
     final Object item = getItem(position); 
     if (convertView == null || ((ViewHolder) convertView.getTag()).getViewType() != getItemViewType(position)) { 
      viewHolder = new ViewHolder(); 
      viewHolder.setViewType(getItemViewType(position)); 
      switch (getItemViewType(position)) { 
       case TYPE_UNSUPPORTED: 
        convertView = new View(mInflater.getContext()); 
        convertView.setTag(viewHolder); 
        break; 
       case TYPE_MESSAGE: { 
        TextView tv; 
        CircularImageView iv; 
        View v; 
        convertView = mInflater.inflate(R.layout.sendbird_view_messaging_message, parent, false); 
        v = convertView.findViewById(R.id.left_container); 
        viewHolder.setView("left_container", v); 
        iv = (CircularImageView) convertView.findViewById(R.id.img_left_thumbnail); 
        viewHolder.setView("left_thumbnail", iv); 
        tv = (TextView) convertView.findViewById(R.id.txt_left); 
        viewHolder.setView("left_message", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_left_name); 
        viewHolder.setView("left_name", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_left_time); 
        viewHolder.setView("left_time", tv); 
        v = convertView.findViewById(R.id.right_container); 
        viewHolder.setView("right_container", v); 
        iv = (CircularImageView) convertView.findViewById(R.id.img_right_thumbnail); 
        viewHolder.setView("right_thumbnail", iv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right); 
        viewHolder.setView("right_message", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right_name); 
        viewHolder.setView("right_name", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right_time); 
        viewHolder.setView("right_time", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right_status); 
        viewHolder.setView("right_status", tv); 
        convertView.setTag(viewHolder); 
        break; 
       } 
       case TYPE_SYSTEM_MESSAGE: { 
        convertView = mInflater.inflate(R.layout.sendbird_view_system_message, parent, false); 
        viewHolder.setView("message", convertView.findViewById(R.id.txt_message)); 
        convertView.setTag(viewHolder); 
        break; 
       } 
       case TYPE_BROADCAST_MESSAGE: { 
        convertView = mInflater.inflate(R.layout.sendbird_view_system_message, parent, false); 
        viewHolder.setView("message", convertView.findViewById(R.id.txt_message)); 
        convertView.setTag(viewHolder); 
        break; 
       } 
       case TYPE_FILELINK: { 
        TextView tv; 
        CircularImageView civ; 
        ImageView iv; 
        View v; 
        convertView = mInflater.inflate(R.layout.sendbird_view_messaging_filelink, parent, false); 
        v = convertView.findViewById(R.id.left_container); 
        viewHolder.setView("left_container", v); 
        civ = (CircularImageView) convertView.findViewById(R.id.img_left_thumbnail); 
        viewHolder.setView("left_thumbnail", civ); 
        iv = (ImageView) convertView.findViewById(R.id.img_left); 
        viewHolder.setView("left_image", iv); 
        tv = (TextView) convertView.findViewById(R.id.txt_left_name); 
        viewHolder.setView("left_name", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_left_time); 
        viewHolder.setView("left_time", tv); 
        v = convertView.findViewById(R.id.right_container); 
        viewHolder.setView("right_container", v); 
        civ = (CircularImageView) convertView.findViewById(R.id.img_right_thumbnail); 
        viewHolder.setView("right_thumbnail", civ); 
        iv = (ImageView) convertView.findViewById(R.id.img_right); 
        viewHolder.setView("right_image", iv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right_name); 
        viewHolder.setView("right_name", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right_time); 
        viewHolder.setView("right_time", tv); 
        tv = (TextView) convertView.findViewById(R.id.txt_right_status); 
        viewHolder.setView("right_status", tv); 
        convertView.setTag(viewHolder); 
        convertView.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View v) { 
          new AlertDialog.Builder(mContext) 
            .setTitle("Foodvite") 
            .setMessage("Do you want to download this file?") 
            .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
             @Override 
             public void onClick(DialogInterface dialog, int which) { 
              try { 
               downloadUrl((FileLink) item, mContext); 
              } catch (IOException e) { 
               e.printStackTrace(); 
              } 
             } 
            }) 
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
             @Override 
             public void onClick(DialogInterface dialog, int which) { 
             } 
            }) 
            .create() 
            .show(); 
         } 
        }); 
        break; 
       } 
       case TYPE_TYPING_INDICATOR: { 
        convertView = mInflater.inflate(R.layout.sendbird_view_typing_indicator, parent, false); 
        viewHolder.setView("message", convertView.findViewById(R.id.txt_message)); 
        convertView.setTag(viewHolder); 
        break; 
       } 
      } 
     } 
     viewHolder = (ViewHolder) convertView.getTag(); 
     switch (getItemViewType(position)) { 
      case TYPE_UNSUPPORTED: 
       break; 
      case TYPE_MESSAGE: 
       Message message = (Message) item; 
       if (message.getSenderId().equals(SendBird.getUserId())) { 
        viewHolder.getView("left_container", View.class).setVisibility(View.GONE); 
        viewHolder.getView("right_container", View.class).setVisibility(View.VISIBLE); 
        displayUrlImage(viewHolder.getView("right_thumbnail", CircularImageView.class), message.getSenderImageUrl(), true); 
        viewHolder.getView("right_name", TextView.class).setText(message.getSenderName()); 
        viewHolder.getView("right_message", TextView.class).setText(message.getMessage()); 
        viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp())); 
        int readCount = 0; 
        for (String key : mReadStatus.keySet()) { 
         if (key.equals(message.getSenderId())) { 
          readCount += 1; 
          continue; 
         } 
         if (mReadStatus.get(key) >= message.getTimestamp()) { 
          readCount += 1; 
         } 
        } 
        if (readCount < mReadStatus.size()) { 
         if (mReadStatus.size() - readCount > 1) { 
          viewHolder.getView("right_status", TextView.class).setText("Unread " + (mReadStatus.size() - readCount)); 
         } else { 
          viewHolder.getView("right_status", TextView.class).setText("Unread"); 
         } 
        } else { 
         viewHolder.getView("right_status", TextView.class).setText(""); 
        } 
        viewHolder.getView("right_container").setOnLongClickListener(new View.OnLongClickListener() { 
         @Override 
         public boolean onLongClick(View v) { 
          new AlertDialog.Builder(mContext) 
            .setTitle("Foodvite") 
            .setMessage("Do you want to delete a message?") 
            .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
             @Override 
             public void onClick(DialogInterface dialog, int which) { 
              SendBird.deleteMessage(((Message) item).getMessageId(), new DeleteMessageHandler() { 
               @Override 
               public void onError(SendBirdException e) { 
                e.printStackTrace(); 
               } 
               @Override 
               public void onSuccess(long messageId) { 
                mSendBirdMessagingAdapter.delete(item); 
                mSendBirdMessagingAdapter.notifyDataSetChanged(); 
                Toast.makeText(mContext, "Message has been deleted.", Toast.LENGTH_SHORT).show(); 
               } 
              }); 
             } 
            }) 
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
             @Override 
             public void onClick(DialogInterface dialog, int which) { 
             } 
            }) 
            .create() 
            .show(); 
          return true; 
         } 
        }); 
       } else { 
        viewHolder.getView("left_container", View.class).setVisibility(View.VISIBLE); 
        viewHolder.getView("right_container", View.class).setVisibility(View.GONE); 
        displayUrlImage(viewHolder.getView("left_thumbnail", CircularImageView.class), message.getSenderImageUrl(), true); 
        viewHolder.getView("left_name", TextView.class).setText(message.getSenderName()); 
        viewHolder.getView("left_message", TextView.class).setText(message.getMessage()); 
        viewHolder.getView("left_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp())); 
        if(isGroupChat) 
         viewHolder.getView("left_name", TextView.class).setVisibility(View.VISIBLE); 
        else 
         viewHolder.getView("left_name", TextView.class).setVisibility(View.GONE); 
       } 
       break; 
      case TYPE_SYSTEM_MESSAGE: 
       SystemMessage systemMessage = (SystemMessage) item; 
       viewHolder.getView("message", TextView.class).setText(Html.fromHtml(systemMessage.getMessage())); 
       break; 
      case TYPE_BROADCAST_MESSAGE: 
       BroadcastMessage broadcastMessage = (BroadcastMessage) item; 
       viewHolder.getView("message", TextView.class).setText(Html.fromHtml(broadcastMessage.getMessage())); 
       break; 
      case TYPE_FILELINK: 
       FileLink fileLink = (FileLink) item; 
       if (fileLink.getSenderId().equals(SendBird.getUserId())) { 
        viewHolder.getView("left_container", View.class).setVisibility(View.GONE); 
        viewHolder.getView("right_container", View.class).setVisibility(View.VISIBLE); 
        displayUrlImage(viewHolder.getView("right_thumbnail", ImageView.class), fileLink.getSenderImageUrl(), true); 
        viewHolder.getView("right_name", TextView.class).setText(fileLink.getSenderName()); 
        if (fileLink.getFileInfo().getType().toLowerCase().startsWith("image")) { 
         displayUrlImage(viewHolder.getView("right_image", ImageView.class), fileLink.getFileInfo().getUrl()); 
        } else { 
         viewHolder.getView("right_image", CircularImageView.class).setImageResource(R.drawable.sendbird_icon_file); 
        } 
        viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, fileLink.getTimestamp())); 
        int readCount = 0; 
        for (String key : mReadStatus.keySet()) { 
         if (key.equals(fileLink.getSenderId())) { 
          continue; 
         } 
         if (mReadStatus.get(key) < fileLink.getTimestamp()) { 
          readCount += 1; 
         } 
        } 
        if (readCount < mReadStatus.size() - 1) { 
         viewHolder.getView("right_status", TextView.class).setText("Unread"); 
        } else { 
         viewHolder.getView("right_status", TextView.class).setText(""); 
        } 
       } else { 
        viewHolder.getView("left_container", View.class).setVisibility(View.VISIBLE); 
        viewHolder.getView("right_container", View.class).setVisibility(View.GONE); 
        displayUrlImage(viewHolder.getView("left_thumbnail", ImageView.class), fileLink.getSenderImageUrl(), true); 
        viewHolder.getView("left_name", TextView.class).setText(fileLink.getSenderName()); 
        if (fileLink.getFileInfo().getType().toLowerCase().startsWith("image")) { 
         displayUrlImage(viewHolder.getView("left_image", ImageView.class), fileLink.getFileInfo().getUrl()); 
        } else { 
         viewHolder.getView("left_image", CircularImageView.class).setImageResource(R.drawable.sendbird_icon_file); 
        } 
        if(isGroupChat) 
         viewHolder.getView("left_name", TextView.class).setVisibility(View.VISIBLE); 
        else 
         viewHolder.getView("left_name", TextView.class).setVisibility(View.GONE); 
        viewHolder.getView("left_time", TextView.class).setText(getDisplayDateTime(mContext, fileLink.getTimestamp())); 
       } 
       break; 
      case TYPE_TYPING_INDICATOR: { 
       int itemCount = ((List) item).size(); 
       String typeMsg = ((List) item).get(0) 
         + ((itemCount > 1) ? " +" + (itemCount - 1) : "") 
         + ((itemCount > 1) ? " are " : " is ") 
         + "typing..."; 
       viewHolder.getView("message", TextView.class).setText(typeMsg); 
       break; 
      } 
     } 
     return convertView; 
    } 
    public boolean checkTypeStatus() { 
     /** 
     * Clear an old type status. 
     */ 
     for (String key : mTypeStatus.keySet()) { 
      Long ts = mTypeStatus.get(key); 
      if (System.currentTimeMillis() - ts > 10 * 1000L) { 
       mTypeStatus.remove(key); 
       return true; 
      } 
     } 
     return false; 
    } 
    private class ViewHolder { 
     private Hashtable<String, View> holder = new Hashtable<String, View>(); 
     private int type; 
     public int getViewType() { 
      return this.type; 
     } 
     public void setViewType(int type) { 
      this.type = type; 
     } 
     public void setView(String k, View v) { 
      holder.put(k, v); 
     } 
     public View getView(String k) { 
      return holder.get(k); 
     } 
     public <T> T getView(String k, Class<T> type) { 
      return type.cast(getView(k)); 
     } 
    } 
} 
private static String getDisplayDateTime(Context context, long milli) { 
    Date date = new Date(milli); 
    if (System.currentTimeMillis() - milli < 60 * 60 * 24 * 1000l) { 
     return DateFormat.getTimeFormat(context).format(date); 
    } 
    return DateFormat.getDateFormat(context).format(date) + " " + DateFormat.getTimeFormat(context).format(date); 
} 
+0

Areyou能夠manageresult不滾動,則接着是正常顯示,因爲根據你的getDisplayDateTime函數,它只會在我假設的情況下適用於當前日期。 – Vickyexpert

+0

@Vickyexpert在getDisplayDateTime方法中,我們用毫秒錶示來自服務器的時間。對於從服務器獲取的每條消息(這是發送該消息的時間)。上面的代碼能夠正確顯示日期和時間每個消息的時間有或沒有滾動..但我希望只有在日期有變化時才顯示日期和時間。例如,如果有一組日期爲6月23日的消息,則應該只顯示第一個日期和時間消息與日期6月23日。 –

+0

@Andrid學習者,請檢查我的答案是否對你有幫助。 – Vickyexpert

回答

1

試試下面爲你的方法的代碼,

private static String getDisplayDateTime(Context context, long milli, long milli2) 
    { 
     Date date = new Date(milli); 
     Date previousDate = new Date(milli2); 
     String strCurrentDate = "", strPreviousDate = ""; 

    if (System.currentTimeMillis() - milli < 60 * 60 * 24 * 1000l) 
    { 
     strCurrentDate = DateFormat.getTimeFormat(context).format(date); 

     if(milli2 != -1) 
      strPreviousDate = DateFormat.getTimeFormat(context).format(previousDate); 
     //return strCurrentDate.equals(strPreviousDate) ? "" : strCurrentDate; 
    } 
    else 
    { 
     strCurrentDate = DateFormat.getDateFormat(context).format(date) + " " + DateFormat.getTimeFormat(context).format(date); 

     if(milli2 != -1) 
      strPreviousDate = DateFormat.getDateFormat(context).format(strPreviousDate) + " " + DateFormat.getTimeFormat(context).format(strPreviousDate); 
    } 
    return strCurrentDate.equals(strPreviousDate) ? "" : strCurrentDate; 
} 

現在打電話給你的方法,如下面

if(position > 0) 
    { 
     final Object previousItem = getItem(position - 1); 
     Message previousMessage = (Message) previousItem; 

     viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp(), previousMessage.getTimestamp())); 
    } 
    else 
    { 
     viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp(), -1)); 
    } 
0

您可以強制系統通過調用BaseAdapter.notifyDataSetChanged()

+0

我已經嘗試notifyDataSetChanged()與我所述的方法,但該方法失敗時,我上下滾動..請用代碼回答我應該做什麼樣的改變以及應該採用什麼方法.. –

1

重繪所有的項目我有一個similar problem (ref this SO Question)幾個月前從除外代替ArrayAdapter<MyObject>BaseAdapter延伸毫無效果。

因此,將您的適配器的基類更改爲ArrayAdapter<MyObject>並實現抽象類的提示方法。您可能需要將您的現有代碼移到這些重寫的方法以獲得更好的性能。如果你沒有滾動列表

相關問題