簡體   English   中英

在Android中更改ImageView位置時出現問題

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

我似乎無法在我的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方法中沒有任何onServiceUpdate運行。

但是,如果我將這3行放在onCreate或任何其他方法中,它的效果很好。 ImageView能夠成功移動。

我還注意到,如果我在onServiceUpdate添加ToastAlertonServiceUpdate發生同樣的事情。 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>

好吃的有點意思。 我下載了SDK並查看了示例應用程序。 請注意你在你的代碼片段中提到的log()函數。 在示例應用程序中是這樣的:

    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行添加到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);
        }
    });
}

並查看它是否運行,如果它只是使圖像視圖與X和Y參數一起成為私有成員; 更新onServiceUpdate上的X和Y,並將其值設置為UI線程上的日志中的ImageView。

(如果它顯然有效,那么之后必須進行一些重構,但它會為你提供一個好的和快速的測試)。

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

希望這有幫助!

是否在非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();
    //....
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM