我的布局值没有更新

My layout values are not updating

所以我有 Track.java 其布局只是想用 myTextLatmyTextLong 向我显示更新的 GPS 坐标。还有一个 MainActivity.java 有一个方法 locationChanged 可以在新的 GPS 数据可用时吐出新的 GPS 数据,但无论出于何种原因我的布局都没有更新新数据,尽管能够看到新的坐标数据即将到来out of locationChanged in system out。我可以通过在 onCreateView 中执行 settext 来静态设置它们,但由于某些原因它们不会通过 setMyCoords 更新。有人可以帮我弄清楚为什么数据在可用时没有传递到我的布局中吗?是否有另一种更好的方法将数据从 activity 传递到片段中的对象,以便它们始终更新?谢谢。

MainActivity's locationChanged

 @Override
    public void locationChanged(double longitude, double latitude) {
        try {
            System.out.println("Longitude: " +longitude);
            System.out.println("Latitude: " + latitude);
            Track f = new Track();
            f.setMyCoords(latitude,longitude);
        } catch (NullPointerException e) {

        }

Track.java

package "";

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Track extends Fragment {
    MiddleMan mCallBack;
    TextView myTextLat;
    TextView myTextLong;


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallBack = (MiddleMan) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement ReqestConnect");
        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.track_display, container, false);

        myTextLat = (TextView) view.findViewById(R.id.textView_lat);
        myTextLong = (TextView) view.findViewById(R.id.textView_long);
        mCallBack.DisplayHome();

        return view;
    }

    public void setMyCoords(final double slat, final double slong) {
        myTextLat.setText(Double.toString(slat));
        myTextLong.setText(Double.toString(slong));
    }
}

这可能也有帮助。每个片段在调用时都会替换 MainActivity 中的一个框架布局。看起来像这样。

@Override
     public void ShiftView(Object obj) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.activity_main_framelayout, (Fragment) obj);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.addToBackStack(null);
        ft.commit();
    }

实际调用是这样的。

Track f = new Track();
ShiftView(f);

结论

在 Joel Min 的帮助下,我得出了解决问题的结论。我只有一个activity,但使用多个片段来承担多个活动的角色,从用户的角度来看:

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical" tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#27b"
        android:layout_weight=".04">
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/activity_main_framelayout">
        </FrameLayout>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight=".9"
        android:orientation="horizontal">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#1B5F96"
            android:layout_weight=".9"
            android:id="@+id/activity_main_status_title"
            android:text="@string/activity_main_status_title"
            tools:ignore="NestedWeights" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#AD3333"
            android:layout_weight=".15"
            android:id="@+id/activity_main_status_value"
            android:text="@string/activity_main_status_value"/>
    </LinearLayout>
</LinearLayout>

Framelayout 占据了显示的绝大部分,ShiftView 基本上通过调用片段 class 来交换片段的布局,如上所述。问题?移动视图是通过 onOptionsitemSelected 方法完成的,其中每个条目基本上如下所示:

if (id == R.id.action_track_display) {
            Track f = new Track();           
            ShiftView(f);
            return true;

到目前为止,这对项目来说还不错,但是,Track.java 需要做一些其他 class 不做的事情,它需要接收和保留 gps 数据,无论用户在应用程序中的位置。我的菜单生成一个新的 Track 对象,我的 locationChanged 方法在每次位置改变时生成一个新的 Track 对象[这是很多对象],none 个对象相同并且 none 连接到MainActivity.java 无论如何。结果,您将获得一个无崩溃的应用程序,该应用程序具有用户可见且永不更新的 Track 对象布局,以及一系列仅存在几分之一秒的背景 Track 对象,每个对象包含一组 gps 点。修复,非常简单:

MainActivity.java

public class MainActivity extends AppCompatActivity {
    Track my_track;
    ...



 @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_track_display) {
            if (my_track==null) {
                my_track = new Track();
            }
            ShiftView((my_track);
            return true;
        }
    ....

@Override
    public void locationChanged(final double longitude, final double latitude) {
        try {
            System.out.println("Main-Longitude: " +longitude);
            System.out.println("Main-Latitude: " + latitude);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {                    
                    my_track.setMyCoords(latitude,longitude);
                }
            });
        } catch (NullPointerException e) {}

您似乎是从非 ui 线程调用 setText。 考虑像这样在 UI 线程中调用它:

  getActivity().runOnUiThread(new Runnable() { 
    @Override
    public void run() {
        myTextLat.setText(Double.toString(slat));
        myTextLong.setText(Double.toString(slong));

    }
});

Each fragment replaces a framelayout in MainActivity when called

但是您是在创建片段并按原样返回主 UI 后调用 f.setMyCoords(latitude,longitude);(未应用 setMyCoords)。因此,将 f.setMyCoords(latitude,longitude); 从您的 locationChanged 方法移动到 ShitView 方法。当然你需要有全局变量 tempLongtempLat 将经度和纬度值临时存储在 locationChanged 中,并在 ShiftView 中访问它们。下面是修改后的代码:

private double tempLong, tempLat; //declare it at class level

@Override
public void locationChanged(double longitude, double latitude) {
    try {
        System.out.println("Longitude: " +longitude);
        System.out.println("Latitude: " + latitude);
        Track f = new Track();
        tempLong = longitude;
        tempLat = latitude;
    } catch (NullPointerException e) {

    }
@Override
 public void ShiftView(Object obj) {
    (Fragment) obj.setMyCoords(tempLat, tempLong);
    //if above line causes error try the line below;
    //Track f = (Fragment) obj;
    //f.setMyCoords(tempLat, tempLong);
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.activity_main_framelayout, (Fragment) obj); 
    //ft.replace(R.id.activity_main_framelayout, f);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.addToBackStack(null);
    ft.commit();
}

我不能保证上面的代码可以工作,因为我没有完整的代码。但基本上你要么需要在 main activity 中的片段转换发生之前设置经度和纬度,要么在你的 setMyCoords 方法中设置一个回调机制,这样当它被调用时它会回调 main activity 来更新具有新经度和纬度的文本视图。