2016-06-26 5 views
1

다음은 내 새 어댑터 클래스 인 sendbird 채팅입니다. 현재 모든 메시지에 날짜가 표시됩니다. viewHolder.getView("left_time")viewHolder.getView("right_time")은 날짜가 표시되는 시간을 표시하는 데 사용되며 getDisplayDateTime 메서드에서 계산됩니다. 날짜가 변경 될 때만 표시되는 날짜가 필요합니다. 예를 들어 23 번째 다음 날짜와 6 월 12 일자 날짜의 메시지가있는 경우 날짜 23rd june의 첫 번째 메시지에 대해서만 표시되어야합니다.값이 변경된 경우에만 어댑터 표시보기

날짜를 변경하고 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

하는 말이야 할 수는 manageresult 아래처럼 메소드를 호출은 의미가 제대로 표시됩니다 , 귀하의 getDisplayDateTime 함수에 따르면, 그것은 내가 생각하는대로 현재 날짜에만 작동합니다. – Vickyexpert

+0

@Vickyexpert getDisplayDateTime 메서드에서 우리는 서버로부터 오는 밀리 초 단위의 시간을 pssing하고 있습니다. 모든 메시지에 대해 우리는 서버로부터 그 시간을 얻고 있습니다 (메시지를 보낼 시간입니다). 위의 코드는 올바르게 날짜와 시간을 표시 할 수 있습니다. 모든 메시지에 대해 스크롤이 있거나없는 시간을 지정합니다. 그러나 날짜가 변경된 경우에만 날짜와 시간을 표시하고 싶습니다. 예를 들어 23 일 오후 6시에 날짜가 설정된 메시지가있는 경우 첫 번째 메시지 만 표시해야합니다 날짜가 23nd june 인 메시지. –

+0

@Andrid Learner, 내 대답이 도움이되는지 확인하십시오. – 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

당신은

+0

나는 question.DataSetChanged()를 시도했다. 질문에 언급 된 접근 방식으로 시도했지만, 위아래로 스크롤 할 때 그 접근법은 실패한다. 코드로 대답해라. 내가해야하는 모든 변화와 내가 사용해야하는 접근 방식 .. –

1

BaseAdapter.notifyDataSetChanged()를 호출하여 모든 항목을 다시 그리도록 시스템을 강제 할 수 나는 similar problem (ref this SO Question) 몇 달 전에 있었다 아무것도 ArrayAdapter<MyObject> 대신 BaseAdapter에서 연장을 제외하고 일했다.

따라서 어댑터의 기본 클래스를 ArrayAdapter<MyObject>으로 변경하고 추상 클래스의 프롬프트 메서드를 구현하십시오. 더 나은 성능을 위해 기존 코드를 이러한 재정의 된 메소드로 이동해야 할 수도 있습니다. 당신이 목록을 스크롤 할 경우 방법에 대한 코드 아래

관련 문제