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);
}
4

3 に答える 3

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));
    }
于 2016-06-29T06:01:48.183 に答える