GetLocationOnScreen возвращает старую позицию после вращения
Что у меня:
- Активность с
android:configChanges="orientation|screenSize|keyboardHidden"
- Диалоговый фрагмент на нем
- ViewA на DialogFragment
В чем проблема:
Я использую ViewA.getLocationOnScreen
, чтобы получить местоположение на экране представления. при первом открытии диалога позиция правильная. После поворота экрана из-за android:configChanges
вид каким-то образом не обновляет его позицию, и даже если диалог правильно центрирован в действии, getLocationOnScreen ViewA указывает на более раннее местоположение перед вращением.
Что я пробовал.
Я перепробовал onConfigurationChanged
диалогового окна и пробовал это:
-
ViewA.requestLayout
(ничего не делает)
-
ViewA.getViewTreeObserver().addOnGlobalLayoutListener
и в onGlobalLayout установите topMargin в 1 и снова вызовите requestLayout. (это сработало, но я не хочу устанавливать маржу при каждом повороте экрана)
Что я хочу знать, так это то, как я могу принудительно изменить положение диалогового окна, чтобы getLocationOnScreen возвращал правильные значения после поворота
Обратите внимание, что я не хочу изменять android:configChanges
Ответы
Ответ 1
Чтобы попытаться объяснить, если у вас есть этот android:configChanges="orientation
, не произойдет отдыха Activity
, что означает, что View
не будет измеряться, поэтому сообщается о старых позициях, а также запрашивать полную наберите View
, вам нужно o вызвать его в DialogFrament
View parent, поэтому для общей игры ваш DecorView
- вызов invalidate()
и requestLayout()
Ответ 2
Отображение местоположения на экране еще не обновлено при вызове onConfigurationChanged
. Вам нужно добавить OnLayoutChangeListener
в представление, чтобы поймать нужные вам обновления. См. Пример ниже.
TestDialogFragment.java
public class TestDialogFragment extends DialogFragment {
private static final String TAG = "TestDialogFragment";
View testView;
int[] testViewLocation = {0, 0};
public TestDialogFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test_fragment, container);
testView = view.findViewById(R.id.test_view);
testView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Log.d(TAG, "onLayoutChange");
testView.getLocationOnScreen(testViewLocation);
Log.d(TAG, String.format("%s %s", testViewLocation[0], testViewLocation[1]));
}
});
return view;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged");
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.d(TAG, "landscape");
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Log.d(TAG, "portrait");
}
testView.getLocationOnScreen(testViewLocation);
Log.d(TAG, String.format("%s %s", testViewLocation[0], testViewLocation[1]));
}
}
test_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/test_view"
android:layout_height="50dp"
android:layout_width="match_parent"
android:layout_gravity="center"/>
</FrameLayout>
Выход журнала
06-24 16:20:05.682 D/TestDialogFragment﹕ onConfigurationChanged
06-24 16:20:05.682 D/TestDialogFragment﹕ portrait
06-24 16:20:05.682 D/TestDialogFragment﹕ 504 601
06-24 16:20:05.852 D/TestDialogFragment﹕ onLayoutChange
06-24 16:20:05.852 D/TestDialogFragment﹕ 84 1021
06-24 16:20:08.695 D/TestDialogFragment﹕ onConfigurationChanged
06-24 16:20:08.695 D/TestDialogFragment﹕ landscape
06-24 16:20:08.695 D/TestDialogFragment﹕ 84 1021
06-24 16:20:08.865 D/TestDialogFragment﹕ onLayoutChange
06-24 16:20:08.865 D/TestDialogFragment﹕ 504 601
06-24 16:20:13.550 D/TestDialogFragment﹕ onConfigurationChanged
06-24 16:20:13.550 D/TestDialogFragment﹕ portrait
06-24 16:20:13.550 D/TestDialogFragment﹕ 504 601