'Show RecyclerView/PopupWIndow by anchoring below or above edittext depending on where the cursor is and depending on screen available height
I am trying to display @ user mentions like facebook or twitter. I am able to implement this functionality. But i have a ui problem.
If edittext is at the bottom of the screen i need to show suggestion in recyclerview at the top.(above edittext cursor)
If edittext is at the top of the screen i need to show suggestion in recycelrview at the bottom (below edittext cursor)
What have i tried?
I have used recyclerview that is constrained below edittext
Problem
When soft keyboard opens it covers the recyclerview. This happens when edittext cursor is at the bottom.
How can i fix this using existing recyclerview itself?.
When edittext cursor is at the top see suggestions are shown below properly.
Code
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textStyle="bold"
android:textSize="16sp"
android:textColor="@color/black"
android:fontFamily="@font/source_sans_pro"
android:id="@+id/titleHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/create_feed_post"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="#c8c8c8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleHeader" />
<com.linkedin.android.spyglass.ui.MentionsEditText
android:padding="8dp"
android:id="@+id/mentionsEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="300dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@null"
android:gravity="start|top"
android:hint="Share team wins or recognize colleague for a job well done"
android:inputType="textMultiLine"
android:minHeight="50dp"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/line">
</com.linkedin.android.spyglass.ui.MentionsEditText>
<ImageView
android:id="@+id/preview"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/mentionsEditText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="0dp"
android:layout_height="250dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:elevation="5dp"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/mentionsEditText" />
<View
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
android:background="#c8c8c8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/preview" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/optionsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/line2">
<ImageView
android:id="@+id/visibility"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:src="@drawable/toggle_comment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/attach"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/attach"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_upload_image" />
<Button
android:id="@+id/done"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginStart="32dp"
android:text="@string/post"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/visibility"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="@+id/titleHeader"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/titleHeader"
app:srcCompat="@drawable/ic_close"
app:tint="@color/black" />
<FrameLayout
android:visibility="gone"
android:elevation="5dp"
android:id="@+id/container"
app:layout_constraintBottom_toTopOf="@+id/preview"
app:layout_constraintEnd_toEndOf="@+id/preview"
app:layout_constraintTop_toTopOf="@+id/preview"
android:layout_width="20dp"
android:layout_height="20dp">
<com.mikhaellopez.circleview.CircleView
app:cv_border_width="1dp"
app:cv_border_color="#EAEAEA"
app:cv_border="true"
app:cv_color="@color/white"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_gravity="center"
android:id="@+id/removePreview"
android:layout_width="15dp"
android:layout_height="15dp"
app:srcCompat="@drawable/ic_close"
app:tint="#999999" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>
Update: i tried using a pop up window. I am able to show above or below a view depending on where the view is located. But there is still one problem with keyboard opening. The pop up comes over the keyboard when the edittext is at the bottom. The edittext moves up but popup window stays in same place
Update 2:
if(anchor instanceof EditText) {
EditText editText = (EditText) anchor;
int pos = editText.getSelectionStart();
Layout layout = editText.getLayout();
int line = layout.getLineForOffset(pos);
int baseline = layout.getLineBaseline(line);
int ascent = layout.getLineAscent(line);
float cursorx = layout.getPrimaryHorizontal(pos);
cursory = baseline + ascent- editText.getScrollY();
}
final View contentView = view;
final Rect windowRect = new Rect();
contentView.getWindowVisibleDisplayFrame(windowRect);
final int windowW = windowRect.width();
final int windowH = windowRect.height();
contentView.measure(
makeDropDownMeasureSpec(getWidth(), windowW),
makeDropDownMeasureSpec(getHeight(), windowH)
);
final int measuredW = contentView.getMeasuredWidth();
final int measuredH = contentView.getMeasuredHeight();
final int[] anchorLocation = new int[2];
anchor.getLocationInWindow(anchorLocation);
final int anchorBottom = anchorLocation[1] + anchor.getHeight();
if (y + anchorBottom < 0) {
y = -anchorBottom;
} else {
y = (int) (y + cursory );
}
And then
popupWindow.showAsDropDown(anchor, 0, y);
and the flag in manifest is
android:windowSoftInputMode="adjustResize"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|