8

I am having trouble pushing up the entire recycler view when the keyboard is diplayed, it cuts off the message that is previous. I am create a chat view that looks like this xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/commentsParentLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/noCommentsResults"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/lineSep"
        android:layout_alignParentTop="true"
        android:layout_marginTop="20dp"
        android:gravity="center"
        android:text="@string/noCommentsFound"
        android:textSize="20sp"
        android:visibility="gone" />

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/pullToLoadMore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/lineSep"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="50dp"
        android:paddingBottom="10dp">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/comments_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none"
            />
    </android.support.v4.widget.SwipeRefreshLayout>

    <View
        android:id="@+id/lineSep"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_above="@+id/commentsAddLayout"
        android:background="@color/horizontalLine" />

    <LinearLayout
        android:id="@+id/commentsAddLayout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:gravity="center"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/emojiSelector"
            android:layout_width="0dp"
            android:layout_height="36dp"
            android:layout_weight="1"
            android:src="@drawable/emoji" />

        <EditText
            android:id="@+id/commentText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_weight="4"
            android:background="@android:color/transparent"
            android:hint="@string/add_comment"
            android:maxLength="150" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1">

            <View
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:background="@color/horizontalLine" />

            <TextView
                android:id="@+id/sendComment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="@string/send"
                android:textSize="18sp" />
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

And this is my recycler view code:

 private void setupAdapter() {

        //stops lag for recycler view for load
        commentsRecyclerView.setHasFixedSize(true);
        commentsAdapter = new CommentsAdapter(this, dbCommentsList, TypeFaceProvider.getTypeFace(this, 0),
                TypeFaceProvider.getTypeFace(this, 1), TypeFaceProvider.getTypeFace(this, 2));
        LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
        mLayoutManager.setReverseLayout(true);
        mLayoutManager.setStackFromEnd(true);

        commentsRecyclerView.setLayoutManager(mLayoutManager);

        commentsRecyclerView.setItemAnimator(new DefaultItemAnimator());

        commentsAdapter.setOnEntryClickListener(new CommentsAdapter.OnEntryClickListener() {
            @Override
            public void onEntryClick(View view, int position) {
                DatabaseComment comment = dbCommentsList.get(position);
                TextView deleteBtn = (TextView) view.findViewById(R.id.commentUserRemove);
                if (view == deleteBtn) {

                    //used to remove the comment from db and the list
                    db.removeSingleComment(comment);
                    dbCommentsList.remove(position);
                    commentsAdapter.notifyDataSetChanged();

                } else {
                    takeToUserProfile(dbCommentsList.get(position));
                }
            }
        });

        commentsRecyclerView.setAdapter(commentsAdapter);
        commentsRecyclerView.scrollToPosition(0);

        hideProgressDialog();
    }

This is my comments adapter:

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

    private static OnEntryClickListener mOnEntryClickListener;
    private List<DatabaseComment> dbCommentsList;
    private Typeface typeFace, italicTypeface, boldTypeface;

    public CommentsAdapter(Context mContext, List<DatabaseComment> comments, Typeface myTypeface, Typeface myTypefaceItalic, Typeface myTypefaceBold) {
        Context context = mContext;
        dbCommentsList = comments;
        typeFace = myTypeface;
        italicTypeface = myTypefaceItalic;
        boldTypeface = myTypefaceBold;
    }

    public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
        mOnEntryClickListener = onEntryClickListener;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case 0:
                return new MyFeatureViewHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.comment_business_item, parent, false));
            case 1:
                return new MyViewHolder(LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.comment_user_item, parent, false));
        }

        return new MyViewHolder(LayoutInflater.from(parent.getContext())
                .inflate(R.layout.comment_user_item, parent, false));


    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        int pos = getItemViewType(position);

        //is a business comment
        if (pos == 0) {
            MyFeatureViewHolder featureViewHolder = (MyFeatureViewHolder) holder;

            DatabaseComment dbComment = dbCommentsList.get(position);

            featureViewHolder.commentCompany.setTypeface(boldTypeface);
            featureViewHolder.commentCompanyMsg.setTypeface(typeFace);
            featureViewHolder.commentCompanyDate.setTypeface(italicTypeface);

            featureViewHolder.commentCompany.setText(dbComment.getUsername());
            featureViewHolder.commentCompanyMsg.setText(dbComment.getCommentText());

            Calendar date = Calendar.getInstance();
            date.setTimeInMillis(dbComment.getCommentDate());
            int newMonth = date.get(Calendar.MONTH) + 1;
            String commentDateTxt = (newMonth + "." + date.get(Calendar.DAY_OF_MONTH) + "." + date.get(Calendar.YEAR));

            featureViewHolder.commentCompanyDate.setText(commentDateTxt);


        }



        //anything greater than 0 is a user comment - with emoji
        if (pos == 1) {
            MyViewHolder myViewHolder = (MyViewHolder) holder;

            if (dbCommentsList.get(position).getIsChanged() == 1) {
                myViewHolder.commentUserRemove.setVisibility(View.VISIBLE);
            } else {
                myViewHolder.commentUserRemove.setVisibility(View.GONE);
            }

            DatabaseComment dbComment = dbCommentsList.get(position);

            myViewHolder.commentUsername.setTypeface(boldTypeface);
            myViewHolder.commentUserMsg.setTypeface(typeFace);
            myViewHolder.commentUserDate.setTypeface(italicTypeface);

            myViewHolder.commentUsername.setText(dbComment.getUsername());
            myViewHolder.commentUserMsg.setText(dbComment.getCommentText());

            Calendar date = Calendar.getInstance();
            date.setTimeInMillis(dbComment.getCommentDate());

            //Note only one plus one because of new comments added will
            int newMonth = date.get(Calendar.MONTH) + 1;
            String commentDateTxt = (newMonth + "." + date.get(Calendar.DAY_OF_MONTH) + "." + date.get(Calendar.YEAR));

            myViewHolder.commentUserDate.setText(commentDateTxt);

            int[] commentsImageList = new int[]{R.drawable.e1, R.drawable.e1, R.drawable.e2, R.drawable.e3, R.drawable.e4,
                    R.drawable.e5, R.drawable.e6, R.drawable.e7, R.drawable.e8, R.drawable.e9, R.drawable.e10,
                    R.drawable.e11, R.drawable.e12, R.drawable.e13, R.drawable.e14,
                    R.drawable.e15, R.drawable.e16, R.drawable.e17, R.drawable.e18, R.drawable.e19};
            myViewHolder.emojiIcon.setImageResource(commentsImageList[dbComment.getIsType()]);


        }


    }

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

    @Override
    public int getItemViewType(int position) {
        if (dbCommentsList.get(position).getIsType() == 0) {
            return 0;
        } else {
            return 1;
        }
    }


    public interface OnEntryClickListener {
        void onEntryClick(View view, int position);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView commentUsername, commentUserMsg, commentUserDate, commentUserRemove;
        public ImageView emojiIcon;


        public MyViewHolder(View view) {
            super(view);
            commentUsername = (TextView) view.findViewById(R.id.commentUsername);
            commentUserMsg = (TextView) view.findViewById(R.id.commentUserMsg);
            commentUserDate = (TextView) view.findViewById(R.id.commentUserDate);
            commentUserRemove = (TextView) view.findViewById(R.id.commentUserRemove);
            emojiIcon = (ImageView) view.findViewById(R.id.emojiIcon);

            view.setOnClickListener(this);
            commentUserRemove.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {
            if (mOnEntryClickListener != null) {
                mOnEntryClickListener.onEntryClick(v, getAdapterPosition());

            }
        }
    }

    public class MyFeatureViewHolder extends RecyclerView.ViewHolder {
        public TextView commentCompany, commentCompanyMsg, commentCompanyDate;
        public ImageView emojiIcon;


        public MyFeatureViewHolder(View view) {
            super(view);
            commentCompany = (TextView) view.findViewById(R.id.commentCompany);
            commentCompanyMsg = (TextView) view.findViewById(R.id.commentCompanyMsg);
            commentCompanyDate = (TextView) view.findViewById(R.id.commentCompanyDate);
            emojiIcon = (ImageView) view.findViewById(R.id.emojiIcon);


        }


    }
}

So when the edit text box is selected the messages in the list view do not move up, but the SEND button and the rest do - so not sure what I need to do to push up the comments view? It looks like I might have a layout issue - but trying the answers in the other questions have not solved it for me:

Solution 1: The adjustpan pushes the view up too high going over the battery and time in the status bar and slightly cutting off the bottom of the view when the keyboard pops up.

Solution 2: The adjustresize does nothing the view still stays the same.

Lion789
  • 4,402
  • 12
  • 58
  • 96
  • last layout must be align to bottom properly. In order to achieve this. – Zar E Ahmer Oct 07 '16 at 05:32
  • Can you elaborate on that, what do I need to add, thanks! – Lion789 Oct 07 '16 at 06:10
  • The part you want to push up from bottom must be align to bottom properly otherwise half of it's view cuts or it doesn't push up – Zar E Ahmer Oct 07 '16 at 06:48
  • So it is aligned to the bottom and looks correct. I have align to parent bottom in the relative layout... is there something I am missing? Also, do you know why adjust pan cuts it off - and how to avoid adjust pan from overlaying the menu bar on top – Lion789 Oct 07 '16 at 06:52
  • Once I face the cuts off issue . It is due to not aligning the last layout to parent bottom. Let me check you layout once. and I will upadate – Zar E Ahmer Oct 07 '16 at 07:03
  • make your parent LinearLayout and add give height =0 and weight=1 to your SwipeRefresh. then set your last layout automatically attached to bottom. May be it helps – Zar E Ahmer Oct 07 '16 at 07:13
  • Well it is not changing anything, with those changes the layout looks the same but it still cuts off part of the bottom view and the comments overlay the status bar – Lion789 Oct 07 '16 at 07:18

1 Answers1

6

If you want to resize your content when the softkeyboard opened, use adjust resize

<application ... >
    <activity
        android:windowSoftInputMode="adjustResize" ... >
        ...
    </activity>
    ...
</application>

or if you want your screen pushed to top, use adjustPan in your manifest

<application ... >
    <activity
        android:windowSoftInputMode="adjustPan" ... >
        ...
    </activity>
    ...
</application>
Oğuzhan Döngül
  • 7,856
  • 4
  • 38
  • 52
  • 2
    The first one does not affect it at all, same situation, and doing the second one works somewhat but cuts off part of the bottom of the chat, and also, the stats bar of the battery and time overlays the top comments ? – Lion789 Oct 07 '16 at 06:12
  • @Lion789 you need to wrap your whole content with a scrollable like NestedScrollView. Otherwise adjustResize won't work. And yes, AdjustPan only works like that. – Oğuzhan Döngül Oct 07 '16 at 07:11
  • does the scroll view have to be the parent or wrap all the content within my linear layout? I wrapped everything with a scroll view - and now my SEND and bottom bar moved to the very top on start and the keyboard is out right away... – Lion789 Oct 07 '16 at 16:22
  • 1
    @Lion789 I don't know what exactly your problem was but for me, adding `android:fitsSystemWindows="true"` to my `ScrollView` solved the problem for me. It now works like I expected it to. – Sufian Nov 10 '16 at 07:58
  • @oguzhand this solution works great but I needed to add `android:fitsSystemWindows="true"` as suggestion [here](http://stackoverflow.com/a/21860837/1276636). It needs to be added to the view which is scrollable. – Sufian Nov 10 '16 at 08:00