【问题标题】:How to update an item on a recyclerview after excuting AsyncTask doInBackground?执行 AsyncTask doInBackground 后如何更新回收站视图上的项目?
【发布时间】:2017-12-08 14:50:38
【问题描述】:

我正在为一个应用程序创建一个聊天功能,它工作得非常好。但我想向用户显示消息已发送或仍在等待服务器的响应。

字段:

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

这是我在 ChatActivity 类上发送消息的方式:

    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: 我的 ChatAdapter 类是这样设置的:

          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 有人告诉我获取视图的引用并在 Activity 的 asynctask 上更改它或为我的适配器创建回调侦听器。

但我不知道如何做任何一个,任何帮助表示赞赏。

【问题讨论】:

  • 你会想要实现 onPostExecute() 以便在 doInBackground() 完成后更改 UI 线程。
  • @Carnal 没有多大帮助。我已经有 runOnUiThread()
  • runOnUiThread 一旦调用了 AsyncTask 就没有任何意义,doInBackground 就像它所说的那样:在后台运行。添加 onPostExecute 实现应该可以解决它

标签: android android-asynctask client-server android-recyclerview android-viewholder


【解决方案1】:

您熟悉“回调”或“接口”的使用吗?您可以创建一个接口并在您的活动中实现它。通过“AsyncTask”中的参数传递回调并在那里使用它。

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

    void updateAdapter(String result);
}

在活动中:

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

终于在 AsyncTask 上...请从 AsyncTask 创建一个外部类!

/**
 * 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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    相关资源
    最近更新 更多