Создание учебного (тренерского) оверлея. Нужна помощь в перемещении вида на основе позиции другого
Здравствуйте, я пытаюсь сделать отметку тренера над уроком.
Main.java
public class Main extends Activity {
private Button button1;
private int x;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help_overlay);
button1 = (Button)findViewById(R.id.button1);
x = button1.getTop();
showOverLay();
}
private void showOverLay(){
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final Dialog dialog = new Dialog(this, 0);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.overlay_view);
RelativeLayout layout = (RelativeLayout) dialog.findViewById(R.id.overlayLayout);
layout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0)
{
Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
dialog.dismiss();
}
});
dialog.show();
}
}
В общем, метод showOverlay вызывается при первом запуске действия. Это показывает диалог, который занимает весь экран и имеет прозрачный фон без заголовка. overlay.xml, показанный ниже, является макетом этого диалога.
То, что я хочу сделать, это динамически отрегулировать положение текстового представления так, чтобы оно находилось над кнопкой для компенсации различных экранов устройства (в будущем я добавлю виды изображений со стрелками, указывающими на объекты, так что было бы странно, если бы эти стрелки не указывали на вид они ссылаются).
Пожалуйста, обратите внимание. Я не могу использовать showCaseView, потому что я буду ориентироваться на API 8.
На изображении выше показано, что я хочу сделать. Переместите текстовое представление с надписью "HEEEEEELP" немного выше кнопки.
main_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="96dp"
android:onClick="idk"
android:text="This Button" />
</RelativeLayout>
overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:id="@+id/overlayLayout">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="HEEEEEEELP"
android:textColor="#FFFFFF"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Спасибо за чтение.
Обновление 2
Мой метод OnCreate
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help_overlay);
button1 = (Button)findViewById(R.id.button1);
button1.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
public boolean onPreDraw() {
top = button1.getTop();
bottom = button1.getBottom();
left = button1.getLeft();
right = button1.getRight();
showOverLay();
button1.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
}
Теперь у меня есть доступ к координатам button1. Однако я не уверен, как разместить текстовое представление над кнопкой, которая может обслуживать устройства разных размеров. Я пытался поиграться с параметрами метода setMargins, но сложно судить о количестве. Я провел некоторое исследование и обнаружил, что могу использовать относительную компоновку с параметрами компоновки и использовать такие поля, как ABOVE и т. Д., Однако, это не похоже на работу, как предполагалось. Текстовое представление не идет выше кнопки.
Мой код
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)textView.getLayoutParams();
lp.addRule(RelativeLayout.CENTER_HORIZONTAL, R.id.button1);
lp.addRule(RelativeLayout.ABOVE, R.id.button1);
textView.setLayoutParams(lp);
Обратите внимание, что мой overlay_view.xml стал относительным макетом.
4 ответа
Вот что вы должны сделать:
button1.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
public boolean onPreDraw() {
button1.getViewTreeObserver().removeOnPreDrawListener(this);
x = button1.getTop();
showOverLay();
return true;
}
});
На самом деле, когда вы звоните x = button1.getTop();
в onCreate()
вид кнопки еще не прорисован и не измерен, поэтому значение getTop
это 0. Попробуйте это.
Добавьте это в свой метод showOverlay():
TextView textView = (TextView) dialog.findViewById(R.id.textView1);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, 0, x);
textView.setLayoutParams(params);
и удалите это из вашего XML-файла:
android:layout_centerVertical="true"
Вы должны сделать свои рисунки пользовательского интерфейса после того, как макет завершит его рисование. Вы можете сделать это, прикрепив Runnable
Интерфейс на макет рисования потока. Когда вы рассчитываете поля или отступы, вы должны сделать это после создания представления. Пожалуйста, смотрите: onFinishInflate ();
button1.post(new Runnable() {
x = button1.getTop();
showOverLayout();
});
Не используйте Dialog для таких оверлеев, для них может потребоваться отдельное окно. Просто сделайте свою деятельность такой, чтобы она могла отображать представление поверх всего, т.е. FrameLayout
к которому вы можете легко добавлять и удалять любые View
объект.
Затем вы можете найти глобальный прямоугольник любого другого объекта просмотра в окне, используя getGlobalVisibleRect()
, Затем вы выравниваете содержимое справки по любой стороне этого прямоугольника.