我的布局值没有更新
My layout values are not updating
所以我有 Track.java
其布局只是想用 myTextLat
和 myTextLong
向我显示更新的 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 方法。当然你需要有全局变量 tempLong
和 tempLat
将经度和纬度值临时存储在 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 来更新具有新经度和纬度的文本视图。
所以我有 Track.java
其布局只是想用 myTextLat
和 myTextLong
向我显示更新的 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 方法。当然你需要有全局变量 tempLong
和 tempLat
将经度和纬度值临时存储在 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 来更新具有新经度和纬度的文本视图。