Определить, если вид на экране-Android

я немного застрял с этим - в первую очередь, следующая ссылка была полезна, однако я придумал немного проблемы с видимостью:

ссылки: проверяем видимость

у меня есть вид прокрутки (Родительский) и ряд подвидов (LinearLayout ->TableLayout) etc. Есть ряд элементов, которые я установил в View.GONE в XML (android:visibility="gone").

у меня есть простой код, чтобы определить, является ли он видимым или нет используя getVisibility() однако, когда я установил элемент в View.VISIBLE и постарайтесь сразу getDrawingRect() Я получаю прямую кишку с нулями по всей доске. Любой дальнейший щелчок получает правильные координаты.

теперь это может быть потому, что представление никогда не рисовалось (как определено в XML), заставляя его возвращать координаты, однако я устанавливаю View.VISIBLE перед попыткой определить видимость экрана. Может быть, мне нужно получить какой-то обратный вызов от say the onDraw()? или, возможно, установите видимость представления скрытые элементы в коде. Немного раздражает ;(

код:

Rect scrollBounds = new Rect();
scroll.getHitRect(scrollBounds);

Rect viewBounds = new Rect();

if (view.getVisibility() == View.GONE) {
    view.setVisibility(View.VISBLE)


    viewBounds.getDrawingRect(viewBounds);
    if (!Rect.intersects(scrollBounds, viewBounds) {
        // do somthing
    } 
}

область макетов следующим образом:

  • ScrollView
    • LinearLayout
      • TableLayout
        • Button
        • HiddenView

конечно, весьма вероятно, что я иду об этом неправильным путем - в основном я просто хочу убедиться, что scrollview позиционирует себя так, что вид, который стал видимым, можно увидеть во всей его полноте.

если требуется какая-либо другая информация, дайте мне знать!

2 ответов


Хорошо, спасибо OceanLife за то, что указал мне в правильном направлении! Был действительно обратный вызов требуется и ViewTreeObserver.OnGlobalLayoutListener() сделал свое дело. Я закончил реализацию прослушивателя против моего класса фрагментов и взял его там, где мне это было нужно. Спасибо за предупреждение о нескольких вызовах, я решил это с помощью removeOnGlobalLayoutListener() метод-работает Шарм.

код:

...

// vto initialised in my onCreateView() method

vto = getView().getViewTreeObserver();
vto.addOnGlobalLayoutListener(this);

...

@Override
    public void onGlobalLayout() {

        final int i[] = new int[2];
        final Rect scrollBounds = new Rect();

        sView.getHitRect(scrollBounds);
        tempView.getLocationOnScreen(i);

        if (i[1] >= scrollBounds.bottom) {
            sView.post(new Runnable() {
                @Override
                public void run() {
                    sView.smoothScrollTo(0, sView.getScrollY() + (i[1] - scrollBounds.bottom));
                }
            });
        }

        vto.removeOnGlobalLayoutListener(this);
    }

просто нужно немного прибраться ...


Итак, если я правильно читаю эту проблему, у вас есть то, что вы хотите узнать размеры некоторого вида в своем макете, чтобы узнать, есть ли у вас пересечение с родителем ScrollView.

то, что я думаю, что вы видите (как вы упомянули), - это инструкция по рисованию отправляемого вида, а затем в каком-то гоночном состоянии визуализатор, разрешающий измерения для макета и фактический рендеринг, где объекты просмотра получают реальные размеры. Один из способов узнать, какие размеры имеет вид на экране, - использовать дерево макета-прослушиватель. Мы используем этот наблюдатель для разрешения размеров экрана при использовании API Google Charts, который требует определения ширины и высоты пикселей... что, конечно, на Android, наверное, самая большая проблема, с которой сталкиваются разработчики. Так что наблюдайте (каламбур);

final ViewTreeObserver vto = chart.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

  /**
   * @see android.view.ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout()
   */
  @SuppressWarnings("deprecation")
  @Override
  public void onGlobalLayout() {
    if (view.getVisibility() == View.GONE) {
      view.setVisibility(View.VISBLE)
      viewBounds.getDrawingRect(viewBounds);
      if (!Rect.intersects(scrollBounds, viewBounds) {
        // do something
      } 
    }
  }
});

слово предупреждение onGlobalLayout будет вызываться несколько раз, поскольку визуализатор закрывается на окончательное решение. Этот мы принимаем последний звонок.

это предоставит вам механизм для выполнения действий на нарисованном виде, например, получение ширины и высоты компонента вида. Надеюсь, это вам поможет.

в сторону: умные парни на площади разработали библиотеку Fest hamcrest, которая позволит вам написать тест для этого вместе с Robotium. зацените.