我似乎无法在我的Android应用程序中更改ImageView
的位置。当我将代码放在特定方法中时会发生这种情况,如下所述。
我在我的android项目中使用IndoorAtlas库。我下载了示例应用程序并在手机上运行它。效果很好。
此库具有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
方法中没有任何内容可以运行。
但是,如果我将这3行放在onCreate
或任何其他方法中,它的效果很好。 ImageView
能够成功移动。
我还注意到,如果我在Toast
中添加Alert
或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>
答案 0 :(得分:6)
private void log(final String msg) {
Log.d(TAG, msg);
runOnUiThread(new Runnable() {
@Override
public void run() {
mLogAdapter.add(msg);
mLogAdapter.notifyDataSetChanged();
}
});
}
这意味着onServiceUpdate没有在UI线程上运行,这意味着如果它崩溃,您可能无法获得任何日志或访问断点。
我建议将3行添加到日志方法
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参数;更新onServiceUpdate上的X和Y,并将其值设置为UI线程中日志中的ImageView。
(如果它显然有效,则必须在之后进行一些重构,但它会给你一个很好的快速测试。)
答案 1 :(得分:3)
来自onServiceUpdate(...)
的后台线程中来自IndoorAtlas
的回调方法,所以如果你想与主UI线程进行通信,那么你需要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());
}
});
}
希望这有帮助!
答案 2 :(得分:2)
在非UI线程上调用 onServiceUpdate 方法但是try-catch忽略了错误吗?然后尝试处理。
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();
//....
}