-1

I'm creating a chat feature for an application and it works super fine. But I would like to show the user that message has been sent or it still wating for the server's response.

Fields:

List<ChatMessage> chatMessages;
ChatAdapter chatAdapter;
RecyclerView chatRecyclerView;
ImageButton submitMessageBtn;

this how I send a message on my ChatActivity class:

    public void submitMessage(final String messageType, final byte[] message){
    final ChatMessageResponse messageObject = new ChatMessageResponse();
    new AsyncTask<Void, Void, Void>() {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            messageObject.setMessage( message);
            messageObject.setYours(true);
            messageObject.setUserNickname(getNickname());
            messageObject.setCreationDate(DateTime.now().withZone(DateTimeZone.UTC));
            messageObject.setType(messageType);

            AddMessage(messageObject);
        } 


        @Override
        protected Void doInBackground(Void... voids) {
            try {

                chatClient.chat().sendMessage(eventId,  messageType, message);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // Update message on the list after has been sent to server 
                    }
                });

            } catch (IOException e) {
                e.printStackTrace();
            }
         return null;
        }
    }.execute();

}

  public void AddMessage(ChatMessage message)
    {
        chatMessages.add(message);
        chatAdapter.notifyDataSetChanged();
        chatRecyclerView.scrollToPosition(chatMessages.size() -1);
    }

When message is immediatly added to the adapter it should look like this: my ChatAdapter class is setup like this:

          public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {

            private static final int VIEW_TYPE_MESSAGE_THIS_USER = 0;
            private static final int VIEW_TYPE_MESSAGE_OTHER_USER = 1;
            private final Activity activity;
            public List<ChatMessage> chats=new ArrayList<>();
            ArrayList<String> usercolor=new ArrayList<>();
            Context mContext;
            View view;

    public ChatAdapter(List<ChatMessage> chats, Context mContext, Activity activity) {
                this.chats = chats;
                this.mContext = mContext;
                this.activity = activity;
            }

            @Override
            public ChatViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
                mContext = parent.getContext();

                if (viewType == VIEW_TYPE_MESSAGE_OTHER_USER) {
                    view = View.inflate(mContext, R.layout.message_item_left, null);
                } else if (viewType == VIEW_TYPE_MESSAGE_THIS_USER){
                    view = View.inflate(mContext, R.layout.message_item, null);
                }

                return new ChatViewHolder(view,(View.OnLongClickListener)activity);
            }

        @Override
        public void onBindViewHolder(final ChatViewHolder holder, int position){
            final ChatMessageResponse m = (ChatMessageResponse) chats.get(position);
            if (getItemViewType(position) == VIEW_TYPE_MESSAGE_OTHER_USER){
                holder.bindToView1(m);
            } else if (getItemViewType(position) == VIEW_TYPE_MESSAGE_THIS_USER)
            {
                holder.bindToView(m);
            }
        }

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

        @Override
        public int getItemViewType(int position) {
            return chats.get(position).isYours() ? VIEW_TYPE_MESSAGE_THIS_USER : VIEW_TYPE_MESSAGE_OTHER_USER;
            }

  }

When the server's response is positive the views in the ChatViewHolder (that I don't show the code because is too long) should change visibility state Someone told me to get a referece for the view and change it on the activity's asynctask or create a Callback listener for my adapter.

But I have no Idea how to do either one of then any help is appreciated.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
braulio.cassule
  • 1,322
  • 4
  • 14
  • 23
  • You're gonna want to implement onPostExecute() in order to the changes in UI thread after doInBackground() is done. – Carnal Dec 08 '17 at 14:53
  • @Carnal that doesn't help much. I already have runOnUiThread() – braulio.cassule Dec 08 '17 at 14:57
  • runOnUiThread doesn't mean anything once the AsyncTask is called, doInBackground does just what it says: runs in the background. Adding onPostExecute implementation should fix it – Nick Mowen Dec 08 '17 at 15:23
  • See https://stackoverflow.com/questions/33784369/recyclerview-get-view-at-particular-position – Venator85 Dec 08 '17 at 15:37

1 Answers1

1

Are you familiar with the use of "Callbacks" or "Interfaces"? You can create an interface and implement it in your activity. Pass the callback by parameters in the "AsyncTask" and use it there.

//Interface class
/**
 * Created by gmora
 */
public interface IProcess {

    void updateAdapter(String result);
}

On Activity:

public class YourActivity extends AppCompatActivity {

    private IProcess mProcess;
    private Adapter mRecyclerAdapter;
    private RecyclerView mRecyclerView;
    private List<ChatMessage> chats; //update chats on activity and refresh your adapter

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_layout);
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);

         mProcess = new IProceso() {
                @Override
                public void updateAdapter(String pException) {
                  //update chats ... and update mAdater.notifyDataChange()...
                  // or mRecyclerView.setAdapter(new Adpater.... with new list chats)..
                }
            };

        mRecyclerView = find....
        // etc.... 
        mRecyclerAdapter = new RecyclerAdapter( chats, ...);
        mRecyclerView.setAdapter(mRecyclerAdapter);   
    }
}

Finally on AsyncTask... create a external class from AsyncTask please!

/**
 * Created by gmora.
 */

public class YourAsyncTaskClass extends AsyncTask<String, Void, String > {

    private IProcess iProcess;

    public StarSearchPrinterTask(IProcess pIProcess) {
        this.iProcess= pIProcess;
    }

    @Override
    protected void onPreExecute() {
        //loading... its optional
    }

    @Override
    protected String doInBackground(String... interfaceType) {
        // execute webservice or api and get results..

        return results;
    }

    @Override
    protected void onPostExecute(String results) {
        mIProceso.updateAdapter(results);
    }
}
Nikki Borrelli
  • 899
  • 9
  • 21
Gustavo Mora
  • 843
  • 1
  • 7
  • 18