I am programmatically setting the x value of an edittext
. However, in doing so the adjust pan function does not work. Any ideas on how to make this work. The activity
is not in full-screen mode and this only happens in APIs > 23
.
Ex.
Edittext editext = findViewById(R.id.edittext);
edittext.setX(200);
//Clicking on edittext
now, gets covered by the soft keyboard if it low enough on screen
Note: this also happens with setY()
Here is an example to reproduce the error:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = this;
setContentView(R.layout.activity_main);
//Get edittext from layout file and set X and Y to the bottom
//left of screen
EditText edittext = findViewById(R.id.editText);
edittext.setX(0);
//Getting device frame to make sure its below keyboard, Not
//necessary can just guess any value
edittext.setY(getDeviceFrame(context).getHeight() / 1.2f);
}
With a layout of :
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
And a manifest of :
<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Resulting in a layout : Edittext after programmatic setX and setY
And after clicking on editext we get : Hidden editext
Which you can see is hidden by the keyboard.
UPDATE : I have tried to use the different variations to moving the EditText with still no avail.
Ex.
edittext.animate().x(200);
UPDATE 2: I have yet to solve this issue. I have been getting closer as I have done some test and it appears that using layout params to control the positioning of the view works to an extent.
Ex.
ConstraintLayout.LayoutParams layoutParams =
(ConstraintLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = 200; //Your X Coordinate
layoutParams.topMargin = 200; //Your Y Coordinate
view.setLayoutParams(layoutParams);
By some extent, I mean I have messed around with the functionality of these methods in a test library and it seems to work doing the above from onCreate(). However, in my app, I am doing the call in a callback. SetX works fine without me having to set it in a 'post' thread or 'runOnMainUI' thread. So I am not sure why this is not working.
Okay, so I figured out how to solve the issue. Using the answer from my "Update 2" above I was able to get the solution with a little tweaking.
This code:
ConstraintLayout.LayoutParams layoutParams =
(ConstraintLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = 200; //Your X Coordinate
layoutParams.topMargin = 200; //Your Y Coordinate
view.setLayoutParams(layoutParams);
(You can use whatever Layout you are using instead of Constraint)
Is an alternative to setX() and setY() and allows adjustPan to work. However, getting the views x or y positioning with :
view.getX();
view.getY();
Will not return the visual positioning of the view. You need to get the view's position by getting the layout params associated with the view and getting its margins.
Now what I came to realize and is key for the Constraint Layout is that you MUST have the constraint defined in xml or via code.
Ex.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
Having this allows the margins to have a reference to what it was extended from, without this, the positioning of the view with not move.