简体   繁体   English

在Android中更改ImageView位置时出现问题

[英]Problems changing the position of an ImageView in Android

I cannot seem to change the position of an ImageView in my android application. 我似乎无法在我的Android应用程序中更改ImageView的位置。 It happens when I place my code in a specific method as explained below. 当我将代码放在特定方法中时会发生这种情况,如下所述。

I am using the IndoorAtlas library in my android project. 我在我的android项目中使用IndoorAtlas库。 I downloaded the sample application and got it running on my phone. 我下载了示例应用程序并在手机上运行它。 Works great. 效果很好。

This library has an onServiceUpdate method which is used to handle the location updates. 该库有一个onServiceUpdate方法,用于处理位置更新。 My aim is to move an ImageView whenever the location is updated. 我的目标是每当位置更新时移动ImageView Pretty simple. 很简单。

Here is the original method as provided by the example (works fine for me): 这是示例提供的原始方法(对我来说很好):

/* 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());
}

Below is the code which I use to update my ImageView 's location: 下面是我用来更新ImageView位置的代码:

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

If I add these lines to the onServiceUpdate method above, the method doesn't work. 如果我将这些行添加到上面的onServiceUpdate方法,则该方法不起作用。 Nothing in the onServiceUpdate method runs. onServiceUpdate方法中没有任何onServiceUpdate运行。

However, if I place these 3 lines in onCreate or any other method, it works great. 但是,如果我将这3行放在onCreate或任何其他方法中,它的效果很好。 The ImageView is able to move successfully. ImageView能够成功移动。

I have also noticed that if I add a Toast or Alert in onServiceUpdate , the same thing happens. 我还注意到,如果我在onServiceUpdate添加ToastAlertonServiceUpdate发生同样的事情。 The onServiceUpdate method doesn't fire at all. onServiceUpdate方法根本不会触发。

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

This is my activity_main.xml 这是我的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>

yummy kind of has a point. 好吃的有点意思。 I downloaded the SDK and looked at the example application. 我下载了SDK并查看了示例应用程序。 Please pay attention to the log() function you're referring to in your code snippet whose impl. 请注意你在你的代码片段中提到的log()函数。 in the example app is this: 在示例应用程序中是这样的:

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

This means that the onServiceUpdate is not running on the UI thread which means that if it crashes you might not get any log or access to breakpoints. 这意味着onServiceUpdate未在UI线程上运行,这意味着如果它崩溃,您可能无法获得任何日志或访问断点。

What i suggest is to add your 3 lines to the log method 我建议将3行添加到log方法中

        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);
        }
    });
}

And see if it runs, if it does simply make the image view a private member along with the X and Y parameters; 并查看它是否运行,如果它只是使图像视图与X和Y参数一起成为私有成员; update X and Y on the onServiceUpdate and set their value to the ImageView in log on the UI thread. 更新onServiceUpdate上的X和Y,并将其值设置为UI线程上的日志中的ImageView。

(some refactoring will have to be made afterwards if it works obviously but it will give you a good and quick test). (如果它显然有效,那么之后必须进行一些重构,但它会为你提供一个好的和快速的测试)。

From onServiceUpdate(...) is callback method from IndoorAtlas in background thread, so if you want to communicate with main UI thread, then you need runOnUIThread(...) : 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());
        }
    });
}

Hope this help! 希望这有帮助!

Is the method onServiceUpdate invoked on non-UI thread but ignored error by try-catch? 是否在非UI线程上调用onServiceUpdate方法,但是try-catch忽略了错误? then try 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();
    //....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM