2016-05-05 8 views
1

Hauptziel: Android App-Messenger für chating mit Firmenunterstützung.Adapter, Timer und Nebenläufigkeit in Android

Aufgabe: Um Timer von Warte Antwort von Operator oder Client in Listview zu untermauern.

Problem: In allen Listview-Elemente Rendering eines der Timer, und dann Anwendung listet einige Timer für einen Moment Rendering für korrekt Ergebnis, aber wenn sie sich überlappen.

Visuell können Sie hier sehen: https://drive.google.com/file/d/0B_SjoeZavdZwdXlUQlU3QTVKeG8/view?usp=sharing]1

-Code:

public class SessionAdapter extends BaseAdapter { 

    private static final String TAG = SessionAdapter.class.toString(); 
    List<SessionInterface> sessions = new ArrayList<>(); 
    Context context; 
    private Message mLastMessage; 
    private List<ViewHolder> lstHolders; 
    private Handler mHandler = new Handler(); 
    private Runnable updateRemainingTimeRunnable = new Runnable() { 
     @Override 
     public void run() { 
      synchronized (lstHolders) { 
       long currentTime = System.currentTimeMillis(); 
       for (ViewHolder holder : lstHolders) { 
        holder.updateTimeRemaining(currentTime, 0); 
       } 
      } 
     } 
    }; 

    public SessionAdapter(List<SessionInterface> sessions, Context context) { 
     this.sessions = sessions; 
     this.context = context; 
     lstHolders = new ArrayList<>(); 
     startUpdateTimer(); 
    } 

    public void updateSessions(List<SessionInterface> sessionInterface) { 
     this.sessions = sessionInterface; 
    } 

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

    @Override 
    public SessionInterface getItem(int position) { 
     return sessions.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     SessionInterface session = sessions.get(position); 
     return session.getId(); 
    } 

    public long getPositionById(long id) { 
     for (int i = 1; i < sessions.size(); i++) { 
      long sessionId = getItemId(i); 
      Log.d(TAG, "getPositionById-i: " + i); 
      Log.d(TAG, "getPositionById-id: " + id); 
      Log.d(TAG, "getPositionById-sessionId: " + sessionId); 
      boolean eq = id == sessionId; 
      Log.d(TAG, "getPositionById-sessionId==id: " + eq); 
      if(eq) { 
       return i; 
      } 
     } 
     return 0; 
    } 

    private void startUpdateTimer() { 
     Timer tmr = new Timer(); 
     tmr.schedule(new TimerTask() { 
      @Override 
      public void run() { 
       mHandler.post(updateRemainingTimeRunnable); 
      } 
     }, 1000, 1000); 
    } 

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

     final SessionInterface session = sessions.get(position); 
     ViewHolder holder; 
     mLastMessage = session.getMessages().get(session.getMessages().size() - 1); 


     if(convertView == null) { 
      holder = new ViewHolder(); 
      convertView = LayoutInflater.from(context).inflate(R.layout.adapter_sessions, null); 
      holder.label = (TextView) convertView.findViewById(R.id.label); 
      holder.sessionTitle = (TextView) convertView.findViewById(R.id.ticket_title); 
      holder.date = (TextView) convertView.findViewById(R.id.date); 
      holder.message = (TextView) convertView.findViewById(R.id.comment); 
      holder.status = (TextView) convertView.findViewById(R.id.status); 
      holder.chatStatusImage = (ImageView) convertView.findViewById(R.id.ticket_status); 
      holder.timeRemaining = (TextView) convertView.findViewById(R.id.time_remaining); 
      convertView.setTag(holder); 
      synchronized (lstHolders) { 
       lstHolders.add(holder); 
      } 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.label.setText("Чат #" + session.getId()); 
     holder.sessionTitle.setText(Helpers.stringLimit(session.getQueue().getName(), 30)); 

     try { 
      Date jud = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", new Locale("ru")).parse(mLastMessage.getDate()); 
      String targetFormat = new SimpleDateFormat("d MMMM, HH:mm", new Locale("ru")).format(jud); 
      long milliseconds = jud.getTime(); 
      holder.date.setText(targetFormat); 
      if(session.getClosedTimeAgo() == null) { 
       holder.updateTimeRemaining(System.currentTimeMillis(), milliseconds); 
       holder.timeRemaining.setVisibility(View.VISIBLE); 
      } else { 
       holder.timeRemaining.setVisibility(View.GONE); 
      } 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 

     holder.message.setText(Helpers.stringLimit(Helpers.stripLineBreaks(mLastMessage.getText(), " "), 50)); 

     if(session.getIs_closed() == 1) { 
      holder.setClosed(convertView); 
     } else { 
      if(mLastMessage.getSender_type().equals(Constants.CLIENT_TYPE)) { 
       holder.setClientWaiting(convertView); 
      } else { 
       holder.setOperatorWaiting(convertView); 
      } 
     } 

     return convertView; 

    } 

    private class ViewHolder { 
     TextView label; 
     TextView sessionTitle; 
     TextView date; 
     TextView message; 
     TextView status; 
     ImageView chatStatusImage; 
     TextView timeRemaining; 

     public void updateTimeRemaining(long currentTime, long timeAgo) { 
      Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(currentTime - timeAgo) = " + (currentTime - timeAgo)); 
      Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(timeAgo - currentTime) = " + (timeAgo - currentTime)); 
      long timeDiff = currentTime - timeAgo; 
      if (timeDiff > 0) { 
       int seconds = (int) (timeDiff/1000) % 60; 
       int minutes = (int) ((timeDiff/(1000 * 60)) % 60); 
       int hours = (int) ((timeDiff/(1000 * 60 * 60)) % 24); 
       int hourMinutes = hours*60 + minutes; 
       timeRemaining.setText(hourMinutes + ":" + (seconds < 10 ? "0" + seconds : seconds)); 
      } else { 
       timeRemaining.setText("Expired!!"); 
      } 
     } 

     public void setClosed(View convertView) { 
      this.status.setText("Закрыто"); 
      this.status.setTextColor(convertView.getResources().getColor(R.color.closedText)); 
      this.chatStatusImage.setImageDrawable(convertView.getResources().getDrawable(R.drawable.chat_status_closed)); 
     } 

     public void setOperatorWaiting(View convertView) { 
      this.status.setText("Оператор ожидает ваш ответ"); 
      this.status.setTextColor(convertView.getResources().getColor(R.color.clientColor)); 
      this.timeRemaining.setTextColor(convertView.getResources().getColor(R.color.clientColor)); 
      this.chatStatusImage.setImageDrawable(convertView.getResources().getDrawable(R.drawable.chat_status_client)); 
     } 

     public void setClientWaiting(View convertView) { 
      this.status.setText("Ожидается ответ оператора"); 
      this.status.setTextColor(convertView.getResources().getColor(R.color.operatorColor)); 
      this.timeRemaining.setTextColor(convertView.getResources().getColor(R.color.operatorColor)); 
      this.chatStatusImage.setImageDrawable(convertView.getResources().getDrawable(R.drawable.chat_status_operator)); 
     } 
    } 

} 
+0

Sie besser rec verwenden Ycle View .. Ich denke .. Und für diese .. Sie können eine Liste, die die neueste Zeit enthalten und NotifyDatasetChanged() ... anstelle von ** Text in ViewHolder ** einrichten pflegen. Das ist dein Hauptproblem. –

Antwort

0

Fooh .. Jahr .. Es war wirklich nicht leicht .. Hier ist meine Lösung ist .. vielleicht es wird helfen, anobody in der Zukunft ..

import android.content.Context; 
import android.os.Handler; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.TextView; 

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.List; 
import java.util.Locale; 
import java.util.TimeZone; 
import java.util.Timer; 
import java.util.TimerTask; 
import java.util.concurrent.TimeUnit; 

import ru.pinspb.pinsupport.R; 
import ru.pinspb.pinsupport.common.Constants; 
import ru.pinspb.pinsupport.pojo.Message; 
import ru.pinspb.pinsupport.pojo.SessionInterface; 
import ru.pinspb.pinsupport.utils.Helpers; 

public class SessionAdapter extends RecyclerView.Adapter<SessionAdapter.Holder> { 

    public interface OnItemClickListener { 
     void onItemClick(SessionInterface item); 
    } 

    private static final String TAG = SessionAdapter.class.toString(); 
    private final OnItemClickListener listener; 
    List<SessionInterface> sessions = new ArrayList<>(); 
    Context context; 
    private Message mLastMessage; 
    private Handler mHandler = new Handler(); 

    public SessionAdapter(List<SessionInterface> sessions, Context context, OnItemClickListener listener) { 
     this.sessions = sessions; 
     this.context = context; 
     this.listener = listener; 
    } 

    public void updateSessions(List<SessionInterface> sessionInterface) { 
     this.sessions = sessionInterface; 
    } 

    public int getCount() { 
     return sessions.size(); 
    } 

    public SessionInterface getItem(int position) { 
     return sessions.get(position); 
    } 

    @Override 
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_sessions, null); 
     return new Holder(v); 
    } 

    @Override 
    public void onBindViewHolder(final Holder holder, int position) { 

     final SessionInterface session = sessions.get(position); 
     mLastMessage = session.getMessages().get(session.getMessages().size() - 1); 

     holder.bind(session, listener); 

     holder.label.setText("Чат #" + session.getId()); 
     holder.sessionTitle.setText(Helpers.stringLimit(session.getQueue().getName(), 30)); 


     try { 
      SimpleDateFormat ru = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", new Locale("ru")); 
      ru.setTimeZone(TimeZone.getTimeZone("GMT+03:00")); 
      Date jud = ru.parse(mLastMessage.getDate()); 
      String targetFormat = new SimpleDateFormat("d MMMM, HH:mm", new Locale("ru")).format(jud); 
      final long milliseconds = jud.getTime(); 
      holder.date.setText(targetFormat); 

      if(session.getClosedTimeAgo() == null) { 
       startUpdateTimer(new Runnable() { 
        @Override 
        public void run() { 
         Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Moscow")); 
         Date currentDate = calendar.getTime(); 
         holder.updateTimeRemaining(currentDate.getTime(), milliseconds); 
        } 
       }); 
//    Log.d(TAG, "Sid: " + session.getId() + " ;\nnow: " + System.currentTimeMillis() + ";\n last date: " + mLastMessage.getDate() + "; \nmill: " + milliseconds); 
       holder.timeRemaining.setVisibility(View.VISIBLE); 
      } else { 
       holder.timeRemaining.setVisibility(View.GONE); 
      } 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 

     holder.message.setText(Helpers.stringLimit(Helpers.stripLineBreaks(mLastMessage.getText(), " "), 50)); 

     if(session.getIs_closed() == 1) { 
      holder.setClosed(); 
     } else { 
      if(mLastMessage.getSender_type().equals(Constants.CLIENT_TYPE)) { 
       holder.setClientWaiting(); 
      } else { 
       holder.setOperatorWaiting(); 
      } 
     } 
    } 

    @Override 
    public long getItemId(int position) { 
     SessionInterface session = sessions.get(position); 
     return session.getId(); 
    } 

    @Override 
    public int getItemCount() { 
     return sessions.size(); 
    } 

    public long getPositionById(long id) { 
     for (int i = 1; i < sessions.size(); i++) { 
      long sessionId = getItemId(i); 
      boolean eq = id == sessionId; 
      if(eq) { 
       return i; 
      } 
     } 
     return 0; 
    } 

    private void startUpdateTimer(final Runnable runnable) { 
     Timer tmr = new Timer(); 
     tmr.schedule(new TimerTask() { 
      @Override 
      public void run() { 
       mHandler.post(runnable); 
      } 
     }, 1000, 1000); 
    } 

    public static class Holder extends RecyclerView.ViewHolder { 
     TextView label; 
     TextView sessionTitle; 
     TextView date; 
     TextView message; 
     TextView status; 
     ImageView chatStatusImage; 
     TextView timeRemaining; 

     public Holder(View itemView) { 
      super(itemView); 
      this.label = (TextView) itemView.findViewById(R.id.label); 
      this.sessionTitle = (TextView) itemView.findViewById(R.id.ticket_title); 
      this.date = (TextView) itemView.findViewById(R.id.date); 
      this.message = (TextView) itemView.findViewById(R.id.comment); 
      this.status = (TextView) itemView.findViewById(R.id.status); 
      this.chatStatusImage = (ImageView) itemView.findViewById(R.id.ticket_status); 
      this.timeRemaining = (TextView) itemView.findViewById(R.id.time_remaining); 
     } 

     public void updateTimeRemaining(long currentTime, long timeAgo) { 
//   Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(currentTime - timeAgo) = " + (currentTime - timeAgo)); 
//   Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(timeAgo - currentTime) = " + (timeAgo - currentTime)); 
      long timeDiff = currentTime - timeAgo; 
      long seconds = TimeUnit.MILLISECONDS.toSeconds(timeDiff) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeDiff)); 
      String time = String.format("%d:%s", 
        TimeUnit.MILLISECONDS.toMinutes(timeDiff), 
        seconds < 10 ? seconds + "0" : String.valueOf(seconds) 
      ); 
      timeRemaining.setText(time); 
     } 

     public void setClosed() { 
      this.status.setText("closed"); 
      this.status.setTextColor(itemView.getResources().getColor(R.color.closedText)); 
      this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_closed)); 
     } 

     public void setOperatorWaiting() { 
      this.status.setText("some text"); 
      this.status.setTextColor(itemView.getResources().getColor(R.color.clientColor)); 
      this.timeRemaining.setTextColor(itemView.getResources().getColor(R.color.clientColor)); 
      this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_client)); 
     } 

     public void setClientWaiting() { 
      this.status.setText("some text"); 
      this.status.setTextColor(itemView.getResources().getColor(R.color.operatorColor)); 
      this.timeRemaining.setTextColor(itemView.getResources().getColor(R.color.operatorColor)); 
      this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_operator)); 
     } 

     public void bind(final SessionInterface item, final OnItemClickListener listener) { 
      itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        listener.onItemClick(item); 
       } 
      }); 
     } 
    } 

}