我正在以编程方式设置edittext
的x值。但是,在执行此操作时,调整平移功能不起作用。关于如何实现这一点的任何想法。activity
不处于全屏模式,这种情况仅在APIs > 23
中发生。
Ex。
Edittext editext = findViewById(R.id.edittext);
edittext.setX(200);
//现在点击edittext
,如果它在屏幕上足够低,就会被软键盘覆盖
注意:setY()
也会发生这种情况
以下是重现错误的示例:
@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);
}
布局为:
<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>
和一个清单:
<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>
产生布局:在编程setX和setY 之后编辑文本
点击editext后,我们得到:隐藏的编辑文本
你可以看到它被键盘隐藏了。
更新:我尝试过使用不同的变体来移动EditText,但仍然没有效果。
Ex。
edittext.animate().x(200);
更新2:我还没有解决这个问题。随着我做了一些测试,我越来越接近了,似乎使用布局参数来控制视图的位置在一定程度上是可行的。
Ex。
ConstraintLayout.LayoutParams layoutParams =
(ConstraintLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = 200; //Your X Coordinate
layoutParams.topMargin = 200; //Your Y Coordinate
view.setLayoutParams(layoutParams);
在某种程度上,我的意思是,我在测试库中对这些方法的功能搞砸了,它似乎可以从onCreate((中完成上述操作。然而,在我的应用程序中,我正在回拨中进行呼叫。SetX运行良好,无需在"post"线程或"runOnMainUI"线程中设置它。所以我不知道为什么这不起作用。
好吧,我想好了如何解决这个问题。使用上面"更新2"中的答案,我可以通过一点调整来获得解决方案。
此代码:
ConstraintLayout.LayoutParams layoutParams =
(ConstraintLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = 200; //Your X Coordinate
layoutParams.topMargin = 200; //Your Y Coordinate
view.setLayoutParams(layoutParams);
(你可以使用你正在使用的任何布局,而不是约束(
是setX((和setY((的替代方案,允许adjustPan工作。然而,使用获取视图x或y定位
view.getX();
view.getY();
不会返回视图的视觉定位。您需要通过获取与视图关联的布局参数并获取其边距来获取视图的位置。
现在我意识到,约束布局的关键是必须用xml或通过代码定义约束。
Ex。
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
有了这一点,页边空白就可以参考它是从什么扩展而来的,没有这一点的话,视图的定位就不会移动。
将setX
和setY
替换为leftMargin
和topMargin
进行弹出定位,它将在大于23的API上正常工作。
我无法解释原因,但API 23上不存在问题。
根据建议,这里有一个代码示例,用于通过拖动按钮来移动弹出布局,并保持平移工作。
final View myNote = getActivity().getLayoutInflater().inflate(R.layout.viewer_annotation_layout, null);
final RelativeLayout.LayoutParams noteLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
myNote.setLayoutParams(noteLayoutParams);
mainScreenLayout.addView(myNote, noteLayoutParams);
btnmove.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
//addednotedX = myNote.getX() - event.getRawX();
//addednotedY = myNote.getY() - event.getRawY();
addednotedX = noteLayoutParams.leftMargin - event.getRawX();
addednotedY = noteLayoutParams.topMargin - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int newposx = event.getRawX() + addednotedX;
int newposy = event.getRawY() + addednotedY;
/* this is move the Note layout but prevent adjsutpan working */
//myNote.setX(newposx);
//myNote.setY(newposy);
/* this is move the Note layout and keep adjsutpan working */
noteLayoutParams.leftMargin = newposx;
noteLayoutParams.topMargin = newposy;
myNote.setLayoutParams(noteLayoutParams);
break;
default:
return false;
}
return false;
}
});