2016-06-29 13 views
2

私はチャットルームにメッセージのリストを表示していますが、RecycleViewを表示しています。 ビューは、最初の項目の代わりに最近のメッセージ(最後のメッセージ、リストの最後の項目)に設定します。私はsmoothScrollToPositionを使用しましたが、最近のメッセージを見るために最初から最後までスクロールさせたくありません。 whatsappのようになりたいのですが、チャットをクリックすると最後のメッセージが表示されます。どうすればこれを達成できますか?recyclerviewの最後のアイテムにビューを設定する方法

package com.wipro.chat.activity; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.DefaultItemAnimator; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.Toolbar; 
import android.text.TextUtils; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.Toast; 

import com.android.volley.DefaultRetryPolicy; 
import com.android.volley.NetworkResponse; 
import com.android.volley.Request; 
import com.android.volley.Response; 
import com.android.volley.RetryPolicy; 
import com.android.volley.VolleyError; 
import com.android.volley.toolbox.StringRequest; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.sql.Timestamp; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.HashMap; 
import java.util.Map; 

import com.wipro.chat.R; 
import com.wipro.chat.adapter.ChatRoomThreadAdapter; 
import com.wipro.chat.app.Config; 
import com.wipro.chat.app.EndPoints; 
import com.wipro.chat.app.MyApplication; 
import com.wipro.chat.gcm.NotificationUtils; 
import com.wipro.chat.model.Message; 
import com.wipro.chat.model.User; 

public class ChatRoomActivity extends AppCompatActivity { 

    private String TAG = ChatRoomActivity.class.getSimpleName(); 

    private String userChatRoomId; 
    private RecyclerView recyclerView; 
    private ChatRoomThreadAdapter mAdapter; 
    private ArrayList<Message> messageArrayList; 
    private BroadcastReceiver mRegistrationBroadcastReceiver; 
    private EditText inputMessage; 
    private Button btnSend; 
    private String selfUserId; 
    private String selfUserName; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_chat_room); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     inputMessage = (EditText) findViewById(R.id.message); 
     btnSend = (Button) findViewById(R.id.btn_send); 

     Intent intent = getIntent(); 
     userChatRoomId = intent.getStringExtra("user_id"); 
     String title = intent.getStringExtra("name"); 

     getSupportActionBar().setTitle(title); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

     if (userChatRoomId == null) { 
      Toast.makeText(getApplicationContext(), "User Chat room not found!", Toast.LENGTH_SHORT).show(); 
      finish(); 
     } 

     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 

     messageArrayList = new ArrayList<>(); 

     // self user id is to identify the message owner 
     selfUserId = MyApplication.getInstance().getPrefManager().getUser().getId(); 
     selfUserName = MyApplication.getInstance().getPrefManager().getUser().getName(); 

     mAdapter = new ChatRoomThreadAdapter(this, messageArrayList, selfUserId); 

     LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
     recyclerView.setLayoutManager(layoutManager); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 
     recyclerView.setAdapter(mAdapter); 

     mRegistrationBroadcastReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) { 
        // new push message is received 
        handlePushNotification(intent); 
       } 
      } 
     }; 

     btnSend.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       sendMessage(); 
      } 
     }); 

     fetchChatThread(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     // registering the receiver for new notification 
     LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, 
       new IntentFilter(Config.PUSH_NOTIFICATION)); 

     NotificationUtils.clearNotifications(); 
    } 

    @Override 
    protected void onPause() { 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver); 
     super.onPause(); 
    } 

    /** 
    * Handling new push message, will add the message to 
    * recycler view and scroll it to bottom 
    * */ 
    private void handlePushNotification(Intent intent) { 
     Message message = (Message) intent.getSerializableExtra("message"); 
     String userChatRoomId = intent.getStringExtra("user_id"); 

     if (message != null && userChatRoomId != null) { 
      messageArrayList.add(message); 
      mAdapter.notifyDataSetChanged(); 
      if (mAdapter.getItemCount() > 1) { 
       recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1); 
      } 
     } 
    } 

    /** 
    * Posting a new message in chat room 
    * will make an http call to our server. Our server again sends the message 
    * to all the devices as push notification 
    * */ 
    private void sendMessage() { 
     final String message = this.inputMessage.getText().toString().trim(); 

     if (TextUtils.isEmpty(message)) { 
      Toast.makeText(getApplicationContext(), "Enter a message", Toast.LENGTH_SHORT).show(); 
      return; 
     } 


     /** Create chatroom with the other user after sending the message**/ 
     String endPointInsert = EndPoints.CHAT_ROOM.replace("_ID_", selfUserId) + "/" + userChatRoomId; 
     Log.e(TAG, "endpointInsert: " + endPointInsert); 

     StringRequest strReque = new StringRequest(Request.Method.GET, 
       endPointInsert, new Response.Listener<String>() { 

      @Override 
      public void onResponse(String response) { 
       Log.e(TAG, "response: " + response); 
      } 
      }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       NetworkResponse networkResponse = error.networkResponse; 
       Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse); 
       Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     Date date = new Date(); 
     String createdAt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); 
     Log.e(TAG, "TIMESTAMP:" + createdAt); 

     User user = new User(selfUserId, selfUserName); 

     final Message msg = new Message(); 
     msg.setId(""); 
     msg.setMessage(message); 
     msg.setCreatedAt(createdAt); 
     msg.setUser(user); 

     messageArrayList.add(msg); 

     mAdapter.notifyDataSetChanged(); 
     if (mAdapter.getItemCount() > 1) { 
      // scrolling to bottom of the recycler view 
      recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1); 
     } 

     //Log.e(TAG,msg.getId()); 

     String endPoint = EndPoints.USER_MESSAGE.replace("_ID_", userChatRoomId); 

     Log.e(TAG, "endpoint: " + endPoint); 

     this.inputMessage.setText(""); 

     StringRequest strReq = new StringRequest(Request.Method.POST, 
       endPoint, new Response.Listener<String>() { 

      @Override 
      public void onResponse(String response) { 
       Log.e(TAG, "response: " + response); 

       try { 
        JSONObject obj = new JSONObject(response); 

        // check for error 
        if (obj.getBoolean("error") == false) { 
         JSONObject commentObj = obj.getJSONObject("message"); 

         String commentId = commentObj.getString("message_id"); 
         String commentText = commentObj.getString("message"); 
         String createdAt = commentObj.getString("created_at"); 

         JSONObject userObj = obj.getJSONObject("user"); 
         String userId = commentObj.getString("from_user_id"); 
         String userName = userObj.getString("name"); 
         User user = new User(userId, userName); 

         Log.e(TAG, commentId); 

         msg.setId(commentId); 

         /*Message message = new Message(); 
         message.setId(commentId); 
         message.setMessage(commentText); 
         message.setCreatedAt(createdAt); 
         message.setUser(user);*/ 

         /*messageArrayList.add(msg); 

         mAdapter.notifyDataSetChanged(); 
         if (mAdapter.getItemCount() > 1) { 
          // scrolling to bottom of the recycler view 
          recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1); 
         }*/ 

        } else { 
         Toast.makeText(getApplicationContext(), "" + obj.getString("message"), Toast.LENGTH_LONG).show(); 
        } 

       } catch (JSONException e) { 
        Log.e(TAG, "json parsing error: " + e.getMessage()); 
        Toast.makeText(getApplicationContext(), "json parse error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       NetworkResponse networkResponse = error.networkResponse; 
       Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse); 
       Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show(); 
       inputMessage.setText(message); 
      } 
     }) { 

      @Override 
      protected Map<String, String> getParams() { 
       Map<String, String> params = new HashMap<String, String>(); 
       params.put("user_id", MyApplication.getInstance().getPrefManager().getUser().getId()); 
       params.put("message", message); 

       Log.e(TAG, "Params: " + params.toString()); 

       return params; 
      }; 
     }; 


     // disabling retry policy so that it won't make 
     // multiple http calls 
     int socketTimeout = 0; 
     RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 
       DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
       DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 

     strReq.setRetryPolicy(policy); 

     //Adding request to request queue 
     MyApplication.getInstance().addToRequestQueue(strReque); 
     MyApplication.getInstance().addToRequestQueue(strReq); 
     Log.i(TAG,msg.getId()); 
    } 


    /** 
    * Fetching all the messages of a single chat room 
    * */ 
    private void fetchChatThread() { 

     String endPointi = EndPoints.CHAT_USER_THREAD.replace("_ID_", userChatRoomId); 
     String endPoint = endPointi + "/" + selfUserId; 
     Log.e(TAG, "endPoint: " + endPoint); 

     StringRequest strReq = new StringRequest(Request.Method.GET, 
       endPoint, new Response.Listener<String>() { 

      @Override 
      public void onResponse(String response) { 
       Log.e(TAG, "response: " + response); 

       try { 
        JSONObject obj = new JSONObject(response); 

        // check for error 
        if (obj.getBoolean("error") == false) { 
         JSONArray commentsObj = obj.getJSONArray("messages"); 

         for (int i = 0; i < commentsObj.length(); i++) { 
          JSONObject commentObj = (JSONObject) commentsObj.get(i); 

          String commentId = commentObj.getString("message_id"); 
          String commentText = commentObj.getString("message"); 
          String createdAt = commentObj.getString("created_at"); 

          JSONObject userObj = commentObj.getJSONObject("user"); 
          String userId = userObj.getString("user_id"); 
          String userName = userObj.getString("username"); 
          User user = new User(userId, userName); 

          Message message = new Message(); 
          message.setId(commentId); 
          message.setMessage(commentText); 
          message.setCreatedAt(createdAt); 
          message.setUser(user); 

          messageArrayList.add(message); 
         } 

         mAdapter.notifyDataSetChanged(); 
         if (mAdapter.getItemCount() > 1) { 
          recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, 1); 
         } 




        } else { 
         Toast.makeText(getApplicationContext(), "" + obj.getJSONObject("error").getString("message"), Toast.LENGTH_LONG).show(); 
        } 

       } catch (JSONException e) { 
        Log.e(TAG, "json parsing error: " + e.getMessage()); 
        Toast.makeText(getApplicationContext(), "json parse error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       NetworkResponse networkResponse = error.networkResponse; 
       Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse); 
       Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     //Adding request to request queue 
     MyApplication.getInstance().addToRequestQueue(strReq); 
    } 

} 

package com.wipro.chat.adapter; 

/** 
* Created by COMP on 17-06-2016. 
*/ 
import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
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 com.wipro.chat.R; 
import com.wipro.chat.model.Message; 

public class ChatRoomThreadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    private static String TAG = ChatRoomThreadAdapter.class.getSimpleName(); 

    private String userId; 
    private int SELF = 100; 
    private static String today; 

    private Context mContext; 
    private ArrayList<Message> messageArrayList; 

    public class ViewHolder extends RecyclerView.ViewHolder { 
     TextView message, timestamp; 

     public ViewHolder(View view) { 
      super(view); 
      message = (TextView) itemView.findViewById(R.id.message); 
      timestamp = (TextView) itemView.findViewById(R.id.timestamp); 
     } 
    } 


    public ChatRoomThreadAdapter(Context mContext, ArrayList<Message> messageArrayList, String userId) { 
     this.mContext = mContext; 
     this.messageArrayList = messageArrayList; 
     this.userId = userId; 

     Calendar calendar = Calendar.getInstance(); 
     today = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)); 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View itemView; 

     // view type is to identify where to render the chat message 
     // left or right 
     if (viewType == SELF) { 
      // self message 
      itemView = LayoutInflater.from(parent.getContext()) 
        .inflate(R.layout.chat_item_self, parent, false); 
     } else { 
      // others message 
      itemView = LayoutInflater.from(parent.getContext()) 
        .inflate(R.layout.chat_item_other, parent, false); 
     } 


     return new ViewHolder(itemView); 
    } 


    @Override 
    public int getItemViewType(int position) { 
     Message message = messageArrayList.get(position); 
     if (message.getUser().getId().equals(userId)) { 
      return SELF; 
     } 

     return position; 
    } 

    @Override 
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { 
     Message message = messageArrayList.get(position); 
     ((ViewHolder) holder).message.setText(message.getMessage()); 

     String timestamp = getTimeStamp(message.getCreatedAt()); 

     if (message.getUser().getName() != null) 
      timestamp = message.getUser().getName() + ", " + timestamp; 

     ((ViewHolder) holder).timestamp.setText(timestamp); 
    } 

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

    public static String getTimeStamp(String dateStr) { 
     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     String timestamp = ""; 

     today = today.length() < 2 ? "0" + today : today; 

     try { 
      Date date = format.parse(dateStr); 
      SimpleDateFormat todayFormat = new SimpleDateFormat("dd"); 
      String dateToday = todayFormat.format(date); 
      format = dateToday.equals(today) ? new SimpleDateFormat("hh:mm a") : new SimpleDateFormat("dd LLL, hh:mm a"); 
      String date1 = format.format(date); 
      timestamp = date1.toString(); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 
     return timestamp; 
    } 
} 

答えて

4

setReverseLayout=trueを設定します。これにより、LayoutManagerはアイテムのレイアウトを終了します。

このような何か:

LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
layoutManager.setReverseLayout(true); 
recyclerView.setLayoutManager(linearLayoutManager); 

EDIT:これは、データの順序を逆が、最後の項目にRecyclerViewをスクロールしません。同じデータの順序を維持し、単に最後の項目にRecyclerViewをスクロールするsetStackFromEnd=true

サンプル設定:

LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
layoutManager.setStackFromEnd(true); 
recyclerView.setLayoutManager(linearLayoutManager); 
+0

また、 'setStackFromEnd'を使用することもできます。https://developer.android.com/reference/android/widget/AbsList View.html#setStackFromBottom(boolean) –

+0

はい、メッセージを反転しています。しかし、私はそれを望んでいません。リストに最初から最後までのメッセージを表示するが、チャットを開いたときに最後のメッセージが表示されている必要があります。 –

+1

ありがとう!! "setSatckFromEnd"は働いています。 –

1

使用RecyclerViewのLayoutManager位置

recyclerView.getLayoutManager().scrollToPosition(messageList.size()-1); 

にある項目をスクロールすると、uは良いですgo to

+0

チャットビュー(画面)の適切なソリューションではなく、ページネーションがあります。 – Bawa

関連する問題