Проблемы с изменением положения ImageView в Android

Я не могу изменить положение ImageView в своем приложении для Android. Это происходит, когда я помещаю свой код в конкретный метод, как описано ниже.

Я использую библиотеку IndoorAtlas в своем проекте Android. Я загрузил образец приложения и получил его на моем телефоне. Прекрасно работает.

Эта библиотека имеет метод onServiceUpdate который используется для обработки обновлений местоположения. Моя цель – перемещать ImageView всякий раз, когда местоположение обновляется. Довольно просто.

Вот оригинальный метод, представленный в примере (отлично работает для меня):

 /* IndoorAtlasListener interface */ /** * This is where you will handle location updates. */ public void onServiceUpdate(ServiceState state) { mSharedBuilder.setLength(0); mSharedBuilder.append("Location: ") .append("\n\troundtrip : ").append(state.getRoundtrip()).append("ms") .append("\n\tlat : ").append(state.getGeoPoint().getLatitude()) .append("\n\tlon : ").append(state.getGeoPoint().getLongitude()) .append("\n\tX [meter] : ").append(state.getMetricPoint().getX()) .append("\n\tY [meter] : ").append(state.getMetricPoint().getY()) .append("\n\tI [pixel] : ").append(state.getImagePoint().getI()) .append("\n\tJ [pixel] : ").append(state.getImagePoint().getJ()) .append("\n\theading : ").append(state.getHeadingDegrees()) .append("\n\tuncertainty: ").append(state.getUncertainty()); log(mSharedBuilder.toString()); } 

Ниже приведен код, который я использую для обновления местоположения моего ImageView :

 ImageView imgPoint = (ImageView) findViewById(R.id.imagePoint); imgPoint.setX(250); imgPoint.setY(200); 

Если я добавлю эти строки в метод onServiceUpdate , метод не работает. Ничего в методе onServiceUpdate выполняется.

Однако, если я onCreate эти 3 строки в onCreate или любой другой метод, он отлично работает. ImageView способен успешно перемещаться.

Я также заметил, что если я добавлю Toast или Alert в onServiceUpdate , onServiceUpdate то же самое. Метод onServiceUpdate не onServiceUpdate вообще.

 Toast.makeText(getApplicationContext(), "Hello!", Toast.LENGTH_LONG).show(); 

Это мой activity_main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="300dp" android:layout_weight="1"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/imageView" android:layout_weight="1" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:layout_marginTop="1dp" android:layout_marginLeft="1dp" android:id="@+id/imagePoint" android:layout_weight="1" /> </RelativeLayout> </RelativeLayout> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> 1 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="300dp" android:layout_weight="1"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/imageView" android:layout_weight="1" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:layout_marginTop="1dp" android:layout_marginLeft="1dp" android:id="@+id/imagePoint" android:layout_weight="1" /> </RelativeLayout> </RelativeLayout> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> 1 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="300dp" android:layout_weight="1"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/imageView" android:layout_weight="1" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:layout_marginTop="1dp" android:layout_marginLeft="1dp" android:id="@+id/imagePoint" android:layout_weight="1" /> </RelativeLayout> </RelativeLayout> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> 

Yummy вид имеет точку. Я загрузил SDK и посмотрел пример приложения. Обратите внимание на функцию log (), о которой вы говорите в своем фрагменте кода, чей impl. В примере это приложение:

  private void log(final String msg) { Log.d(TAG, msg); runOnUiThread(new Runnable() { @Override public void run() { mLogAdapter.add(msg); mLogAdapter.notifyDataSetChanged(); } }); } 

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

Я предлагаю добавить три линии к методу журнала

  private void log(final String msg) { Log.d(TAG, msg); runOnUiThread(new Runnable() { @Override public void run() { mLogAdapter.add(msg); mLogAdapter.notifyDataSetChanged(); ImageView imgPoint = (ImageView)findViewById(R.id.imagePoint); imgPoint.setX(250); imgPoint.setY(200); } }); } 

И посмотрите, работает ли он, если он просто делает просмотр изображения частным членом вместе с параметрами X и Y; Обновите X и Y в onServiceUpdate и установите их значение в ImageView в журнале в потоке пользовательского интерфейса.

(Некоторые рефакторинги должны будут быть сделаны позже, если они будут работать, но это даст вам хороший и быстрый тест).

From onServiceUpdate(...) – это метод обратного вызова из IndoorAtlas в фоновом потоке, поэтому, если вы хотите общаться с основным потоком пользовательского интерфейса, вам нужно runOnUIThread(...) :

 public void onServiceUpdate(ServiceState state) { mSharedBuilder.setLength(0); mSharedBuilder.append("Location: ") .append("\n\troundtrip : ").append(state.getRoundtrip()).append("ms") .append("\n\tlat : ").append(state.getGeoPoint().getLatitude()) .append("\n\tlon : ").append(state.getGeoPoint().getLongitude()) .append("\n\tX [meter] : ").append(state.getMetricPoint().getX()) .append("\n\tY [meter] : ").append(state.getMetricPoint().getY()) .append("\n\tI [pixel] : ").append(state.getImagePoint().getI()) .append("\n\tJ [pixel] : ").append(state.getImagePoint().getJ()) .append("\n\theading : ").append(state.getHeadingDegrees()) .append("\n\tuncertainty: ").append(state.getUncertainty()); log(mSharedBuilder.toString()); setImagePoint(state.getImagePoint()); } private void setImagePoint(final ImagePoint imgPt) { runOnUiThread(new Runnable() { @Override public void run() { ImageView imgPoint = (ImageView) findViewById(R.id.imagePoint); imageMan.setX(imgPt.getI()); imageMan.setY(imgPt.getJ()); } }); } 

Надеюсь эта помощь!

Вызывается метод onServiceUpdate для потока, отличного от UI, но игнорируется ошибкой при попытке? Затем попробуйте Handle.

 private Handler mUpdateHandler = new Handler() { public void handleMessage(Message msg){ if (msg.obj instanceof ServiceState) { ServiceState state = (ServiceState) msg.obj; ImageView imgPoint = (ImageView) findViewById(R.id.imagePoint); imgPoint.setX(state.getMetricPoint().getX()); imgPoint.setY(state.getMetricPoint().getY()); } } } public void onServiceUpdate(ServiceState state) { mUpdateHandler.obtainMessage(0, state).sendToTarget(); //.... }