Как получить абсолютные координаты вида

Вот еще одна вариация, использующая представления:

CREATE VIEW digits AS
  SELECT 0 AS digit UNION ALL
  SELECT 1 UNION ALL
  SELECT 2 UNION ALL
  SELECT 3 UNION ALL
  SELECT 4 UNION ALL
  SELECT 5 UNION ALL
  SELECT 6 UNION ALL
  SELECT 7 UNION ALL
  SELECT 8 UNION ALL
  SELECT 9;

CREATE VIEW numbers AS
  SELECT
    ones.digit + tens.digit * 10 + hundreds.digit * 100 + thousands.digit * 1000 AS number
  FROM
    digits as ones,
    digits as tens,
    digits as hundreds,
    digits as thousands;

CREATE VIEW dates AS
  SELECT
    SUBDATE(CURRENT_DATE(), number) AS date
  FROM
    numbers;

И тогда вы можете просто сделать (посмотрите, насколько она элегантна?):

SELECT
  date
FROM
  dates
WHERE
  date BETWEEN '2010-01-20' AND '2010-01-24'
ORDER BY
  date

Обновить

Стоит отметить, что вы сможете генерировать прошлые даты, начиная с текущей даты . Если вы хотите создать какой-либо диапазон дат (прошлый, будущий и промежуточный), вам придется использовать это представление вместо этого:

CREATE VIEW dates AS
  SELECT
    SUBDATE(CURRENT_DATE(), number) AS date
  FROM
    numbers
  UNION ALL
  SELECT
    ADDDATE(CURRENT_DATE(), number + 1) AS date
  FROM
    numbers;
366
задан Suragch 14 January 2017 в 11:24
поделиться

9 ответов

Используйте View.getLocationOnScreen() и / или getLocationInWindow() .

586
ответ дан TapanHP 14 January 2017 в 11:24
поделиться

Моя функция utils для определения местоположения, она возвращает объект Point с x value и y value

public static Point getLocationOnScreen(View view){
    int[] location = new int[2];
    view.getLocationOnScreen(location);
    return new Point(location[0], location[1]);
}

, используя

Point viewALocation = getLocationOnScreen(viewA);
5
ответ дан Phan Van Linh 14 January 2017 в 11:24
поделиться
1113 Принятый ответ на самом деле не говорит, как получить местоположение, так что здесь немного подробнее. Вы передаете массив int длины 2, и значения заменяются координатами вида (x, y) (верхнего левого угла).

int[] location = new int[2];
myView.getLocationOnScreen(location);
int x = location[0];
int y = location[1];

Примечания

  • Замена getLocationOnScreen на getLocationInWindow должна давать одинаковые результаты в большинстве случаев (см. этот ответ ). Однако, если вы находитесь в меньшем окне, таком как Dialog или пользовательская клавиатура, тогда вам нужно будет выбрать, какая из них лучше соответствует вашим потребностям.
  • Вы получите (0,0), если вызовете этот метод в onCreate, потому что вид еще не был размечен. Вы можете использовать ViewTreeObserver для прослушивания, когда макет сделан, и вы можете получить измеренные координаты. (См. этот ответ .)
99
ответ дан Suragch 14 January 2017 в 11:24
поделиться

Сначала вы должны получить локально видимый прямоугольник вида

Например:

Rect rectf = new Rect();

//For coordinates location relative to the parent
anyView.getLocalVisibleRect(rectf);

//For coordinates location relative to the screen/display
anyView.getGlobalVisibleRect(rectf);

Log.d("WIDTH        :", String.valueOf(rectf.width()));
Log.d("HEIGHT       :", String.valueOf(rectf.height()));
Log.d("left         :", String.valueOf(rectf.left));
Log.d("right        :", String.valueOf(rectf.right));
Log.d("top          :", String.valueOf(rectf.top));
Log.d("bottom       :", String.valueOf(rectf.bottom));

Надеюсь, это поможет

72
ответ дан Lavekush Agrawal 14 January 2017 в 11:24
поделиться

Использование глобального макета слушателя всегда хорошо работало для меня. Преимущество состоит в том, что он может перезаписывать вещи при изменении макета, например, если что-то установлено на View.GONE или дочерние представления добавляются / удаляются.

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);

     // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
     LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); 

     // set a global layout listener which will be called when the layout pass is completed and the view is drawn
     mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener() {
          public void onGlobalLayout() {
               //Remove the listener before proceeding
               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
               } else {
                    mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               }

               // measure your views here
          }
       }
     );

     setContentView(mainLayout);
 }
45
ответ дан Siwei Shen 申思维 14 January 2017 в 11:24
поделиться

После комментария Ромена Гая вот как я это исправил. Надеюсь, это поможет кому-нибудь еще, у кого также была эта проблема.

Я действительно пытался выяснить положение представлений до того, как они были выложены на экран, но это было совсем не очевидно. Эти строки были размещены после запуска кода инициализации, поэтому я предположил, что все было готово. Тем не менее, этот код все еще был в onCreate (); Поэкспериментировав с Thread.sleep (), я обнаружил, что макет на самом деле не завершен до тех пор, пока onCreate () полностью не завершит выполнение onResume (). И действительно, код пытался выполнить до того, как макет был размещен на экране. При добавлении кода в OnClickListener (или некоторый другой Listener) были получены правильные значения, потому что его можно было запустить только после завершения макета.


Строка ниже была предложена как правка сообщества:

, пожалуйста, используйте onWindowfocuschanged(boolean hasFocus)

17
ответ дан Adi Inbar 14 January 2017 в 11:24
поделиться

Первый путь:

В Котлин мы можем создать простое расширение для вида:

fun View.getLocationOnScreen(): Point
{
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return Point(location[0],location[1])
}

И просто получить координаты:

val location = yourView.getLocationOnScreen()
val absX = location.x
val absY = location.y

Второй путь:

Второй способ более прост:

fun View.absX(): Int
{
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return location[0]
}

fun View.absY(): Int
{
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return location[1]
}

и просто получить абсолютный X с помощью view.absX() и Y на view.absY()

5
ответ дан Amir Hossein Ghasemi 14 January 2017 в 11:24
поделиться

Используйте этот код, чтобы найти точные X и Y кординаты:

int[] array = new int[2];
ViewForWhichLocationIsToBeFound.getLocationOnScreen(array);
if (AppConstants.DEBUG)
    Log.d(AppConstants.TAG, "array  X = " + array[0] + ", Y = " + array[1]);
ViewWhichToBeMovedOnFoundLocation.setTranslationX(array[0] + 21);
ViewWhichToBeMovedOnFoundLocation.setTranslationY(array[1] - 165);

Я добавил / вычел некоторые значения, чтобы скорректировать свой вид. Пожалуйста, делайте эти строки только после того, как весь вид будет раздут.

-2
ответ дан Tarun 14 January 2017 в 11:24
поделиться

Можно получить координаты Представления с помощью getLocationOnScreen() или getLocationInWindow()

int[] point = new int[2];
view.getLocationOnScreen(point); // or getLocationInWindow(point)
int x = point[0];
int y = point[1];

Впоследствии, x и y должен быть верхний левый угол представления. Если Ваше корневое расположение меньше, чем экран (как в Диалоговом окне), с помощью getLocationInWindow будет относительно его контейнера, не всего экрана.

ПРИМЕЧАНИЕ: , Если значение всегда 0, Вы, вероятно, изменяете представление сразу прежде, чем запросить местоположение.

Для обеспечения представления имел шанс обновить, выполнить запрос местоположения после того, как новое расположение Представления было вычислено при помощи view.post:

view.post(() -> {
    // Values should no longer be 0
    int[] point = new int[2];
    view.getLocationOnScreen(point); // or getLocationInWindow(point)
    int x = point[0];
    int y = point[1];
});
1
ответ дан 22 November 2019 в 23:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: