sagar suri
sagar suri

Reputation: 4731

Keep the last item of a recyclerview visible when soft keyboard is visible in chat application

I created one simple chat application in android studio. Initially when I send text the last item of the recyclerview is always in focus but when I hide the soft keyboard and then again click on the editext to send message the last item in the recyclerview is not in focus. I need to scroll down to see the last message when the soft keyboard is in focus. Below is layout and the MainActivity code:

EditText messageEdt;
ImageView sendBtn;
RecyclerView recyclerView;
CustomAdapter adapter;
List<Model> chatList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    messageEdt = (EditText) findViewById(R.id.messageText);
    sendBtn = (ImageView) findViewById(R.id.sendBtn);
    recyclerView = (RecyclerView) findViewById(R.id.recyclerChatList);
    chatList = new ArrayList<>();
    adapter = new CustomAdapter(this);
    recyclerView.setAdapter(adapter);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    messageEdt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean b) {
            if(b && adapter.getItemCount()>1){
                recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,null,adapter.getItemCount()-1);
            }
        }
    });
    getSupportActionBar().hide();

}

private void getData() {
    String messageStr = messageEdt.getText().toString().replaceAll("[ ]","%20");
    Log.e("messageStr",messageStr);
    Model model = new Model();
    model.setMessage(messageEdt.getText().toString());
    model.setUser("User");
    chatList.add(model);

    messageEdt.setText("");

    adapter.getChatList(chatList);
    adapter.notifyDataSetChanged();
    if(adapter.getItemCount()>1){
        recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,null,adapter.getItemCount()-1);
    }
    url = "http://chat.vicz.in/get/";
    url = url.concat(messageStr);
    Log.e("Url", url);
    StringRequest getData = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                url = "http://chat.vicz.in/get/";
                Log.e("Response", response);
                JSONObject responseObj = new JSONObject(response);
                String stringResponse = responseObj.getString("response");
                Model data = new Model();
                data.setMessage(stringResponse);
                data.setUser("Bot");
                chatList.add(data);
                recyclerView.smoothScrollToPosition(chatList.size()-1);
                adapter.getChatList(chatList);
                adapter.notifyDataSetChanged();
                if(adapter.getItemCount()>1){
                    recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,null,adapter.getItemCount()-1);
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            url = "http://chat.vicz.in/get/";
        }
    });
    getData.setRetryPolicy(new DefaultRetryPolicy(30000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    Volley.newRequestQueue(this).add(getData);


}

public void sendMessage(View view) {
    getData();
}

Here is the layout of my chat application:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"

tools:context="com.example.admin.chatbot.MainActivity">



    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerChatList"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@null"
        android:divider="@null"
        android:transcriptMode="alwaysScroll"
        android:stackFromBottom="true">

    </android.support.v7.widget.RecyclerView>



        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <EditText
                android:id="@+id/messageText"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="80"
                android:hint="Enter Message" />

            <ImageView
                android:id="@+id/sendBtn"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="20"
                android:onClick="sendMessage"
                android:src="@android:drawable/ic_menu_send" />
        </LinearLayout>

I have already used smoothScrollToPosition() but it only works initially when the soft keyboard is visible from the beginning. But if I hide and then focus the soft keyboard the last item in the list is not in focus.

Upvotes: 4

Views: 3711

Answers (3)

sarika
sarika

Reputation: 47

You can possibly try this:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

Upvotes: -1

SK16
SK16

Reputation: 642

You can try following options:

  1. Use AdjustResize at required activity in androidManifest.xml (Adjust Resize) Or You can use AdjustPan (It'll hide toolbar at the top though)
  2. if Adjust resize not worked, then if You are

LinearLayoutManager layoutManager = new LinearLayoutManager(mActivity); layoutManager.setStackFromEnd(true); (worked for me)

(if setReverseLayout(true) is used then List will be displayed in reversed order)

Another answer had suggested using onClickListener and

mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount() - 1);

Upvotes: 2

Much Overflow
Much Overflow

Reputation: 3140

You should do this on your RecyclerView's layout manager. The below code will stack each item from bottom of the RecyclerView and keeps the focus at bottom.

LinearLayoutManager llm = new LinearLayoutManager(getContext());
llm.setReverseLayout(true);
llm.setStackFromEnd(true);
myRecyclerView.setLayoutManager(llm);

Upvotes: 0

Related Questions