java如何使我的片段利用我的活动数据?
我有一个活动承载3个片段,我的活动包含一些我希望我的第一个片段使用的数据。 我尝试调用以下方法,以便活动可以与片段通信:
FirstFragment fragmentFirst = (FirstFragment)
getSupportFragmentManager().findFragmentById(R.id.firstFragment);
assert fragmentFirst != null;
fragmentFirst.doSomething("some param");
对于活动类和:
public void doSomething(String param) {
// do something in fragment
}
对于fragment类,但它产生了一个:Attempt to invoke virtual method 'void com.tex.lightweatherforecast.FirstFragment.doSomething(java.lang.String)' on a null object reference
运行时出错
我的活动代码是:
public class HomeActivity extends AppCompatActivity {
public static String BaseUrl = "http://api.openweathermap.org/";
public static String AppId = "9c547bfc852923c3b30d0d62a5ae35e8";
public static String lat = "9.0574";
public static String lon = "7.4898";
// User Timezone name, current time, current temperature, current condition, sunrise, sunset, temperature, pressure, humidity, wind_speed, visibility, UV Index
TextView time_zone, time_field, current_temp, current_output, rise_time, set_time, temp_out, Press_out, Humid_out, Ws_out, Visi_out, UV_out;
ConstraintLayout constraintLayout;
public static int count=0;
int[] drawable =new int[]{R.drawable.dubai,R.drawable.central_bank_of_nigeria,R.drawable.eiffel_tower,R.drawable.hong_kong,R.drawable.statue_of_liberty};
Timer _t;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
FirstFragment fragmentFirst = (FirstFragment)
getSupportFragmentManager().findFragmentById(R.id.firstFragment);
assert fragmentFirst != null;
fragmentFirst.doSomething("some param");
time_zone = findViewById(R.id.textView9);
time_field = findViewById(R.id.textView4);
current_temp = findViewById(R.id.textView10);
current_output = findViewById(R.id.textView11);
rise_time = findViewById(R.id.textView25);
set_time = findViewById(R.id.textView26);
temp_out = findViewById(R.id.textView28);
Press_out = findViewById(R.id.textView29);
Humid_out = findViewById(R.id.textView30);
Ws_out = findViewById(R.id.textView33);
Visi_out = findViewById(R.id.textView34);
UV_out = findViewById(R.id.textView35);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
NavController navController = Navigation.findNavController(this, R.id.fragment);
NavigationUI.setupWithNavController(bottomNavigationView, navController);
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getCurrentData();
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.dubai);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() { // run on ui thread
@Override
public void run() {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
}
});
}
}, 5000, 5000);
}
void getCurrentData() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
WeatherService service = retrofit.create(WeatherService.class);
Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
call.enqueue(new Callback<WeatherResponse>() {
@Override
public void onResponse(@NonNull Call<WeatherResponse> call, @NonNull Response<WeatherResponse> response) {
if (response.code() == 200) {
WeatherResponse weatherResponse = response.body();
assert weatherResponse != null;
assert response.body() != null;
time_zone.setText(response.body().getTimezone());
time_field.setText(response.body().getCurrent().getDt());
current_temp.setText(response.body().getCurrent().getTemp() + " ℃");
current_output.setText(response.body().getCurrent().getWeather().get(0).getDescription());
rise_time.setText(response.body().getCurrent().getSunrise() + " AM");
set_time.setText(response.body().getCurrent().getSunset() + " PM");
temp_out.setText(response.body().getCurrent().getTemp() + " ℃");
Press_out.setText(response.body().getCurrent().getPressure() + " hpa");
Humid_out.setText(response.body().getCurrent().getHumidity() + " %");
Ws_out.setText(response.body().getCurrent().getWindSpeed() + " Km/h");
Visi_out.setText(response.body().getCurrent().getVisibility() + " m");
}
}
@Override
public void onFailure(@NonNull Call<WeatherResponse> call, @NonNull Throwable t) {
}
});
}
});
}
}
任何帮助都将不胜感激
# 1 楼答案
我认为您得到这个错误是因为片段不活动。如果它是活动的,并且这种方法有效,那么这是非常糟糕的方法,当我们使用新的LiveData和ViewModel arch样式时,还有其他方法
如果您认为子级(片段)将需要数据源(通常是LiveData),则将此数据源归父级(活动)所有,并在片段内监视该数据源(即,在不同片段内观察此LiveData)
如果需要从片段回调到活动,请使用契约(接口)并在活动内部实现该契约(该契约可能包含doSomething()之类的函数),然后从片段内部调用该契约,如下所示:
# 2 楼答案
若要在第一个目标片段中传递活动数据,请避免在活动布局文件中设置图形
从活动布局中删除图形实现。并在活动的onCreate方法中实现它,如下所示
通过参考以下代码更新图形文件
在主片段中,获取参数值