当我单击其他片段中的搜索按钮时,java应用程序崩溃
我的天气应用程序在搜索面板上搜索城市,效果很好。唯一的问题是,如果我单击底部导航视图上的下一个选项卡(小时和每日部分),然后 单击此处的搜索按钮,它显示以下异常:
java.lang.ClassCastException: com.viz.lightweatherforecast.SecondFragment cannot be cast to com.viz.lightweatherforecast.FirstFragment
at com.viz.lightweatherforecast.Activity.HomeActivity$2.onClick(HomeActivity.java:94)
at 安卓.view.View.performClick(View.java:7044)
at 安卓.view.View.performClickInternal(View.java:7017)
at 安卓.view.View.access$3200(View.java:784)
at 安卓.view.View$PerformClick.run(View.java:26596)
at 安卓.os.Handler.handleCallback(Handler.java:873)
at 安卓.os.Handler.dispatchMessage(Handler.java:99)
at 安卓.os.Looper.loop(Looper.java:193)
at 安卓.app.ActivityThread.main(ActivityThread.java:6819)
at java.lang.reflect.Method.invoke(Native Method)
at com.安卓.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:497)
at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:912)
此错误清楚地表明错误来自活动的此行:
FirstFragment firstFragment = (FirstFragment) navHostFragment.getChildFragmentManager().getFragments().get(0);
firstFragment.getWeatherData(textfield.getText().toString().trim());
因此,我尝试添加以下内容:
SecondFragment secondFragment = (SecondFragment) navHostFragment.getChildFragmentManager().getFragments().get(0);
secondFragment.getWeatherData(textfield.getText().toString().trim());
所以它可以支持我的第二个片段,但它仍然给出了错误。我也曾在这个网站上搜索过答案,但没有找到任何解决方案
为了进一步解释这个应用程序,我有一个活动,它包含3个片段(Firstfragment、Secondfragment和Thirdfragment)。第一个片段标记为“今天”,第二个片段标记为“每小时”,第三个片段标记为“天气”
我现在不打算使用每小时和每天的标签,直到该应用的更高版本。 我的其他片段目前是空的(没有写代码),我现在只想继续使用today选项卡。 但是修复这个错误是必要的,以防用户点击它
我的目的是确保如果我单击其他选项卡上的搜索按钮,不会出现这样的错误,请帮助
我的活动代码:
public class HomeActivity extends AppCompatActivity {
// Last update time, click sound, search button, search panel.
TextView time_field;
MediaPlayer player;
ImageView Search;
EditText textfield;
// For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
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);
// use home activity layout.
time_field = findViewById(R.id.textView9);
Search = findViewById(R.id.imageView4);
textfield = findViewById(R.id.textfield);
// find the id's of specific variables.
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
// host 3 fragments along with bottom navigation.
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
// For scheduling background image change
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.dubai);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
Search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// make click sound when search button is clicked.
player = MediaPlayer.create(HomeActivity.this, R.raw.click);
player.start();
getWeatherData(textfield.getText().toString().trim());
// make use of some fragment's data
FirstFragment firstFragment = (FirstFragment) navHostFragment.getChildFragmentManager().getFragments().get(0);
firstFragment.getWeatherData(textfield.getText().toString().trim());
}
private void getWeatherData(String name) {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(@NonNull Call<Example> call, @NonNull Response<Example> response) {
try {
assert response.body() != null;
time_field.setVisibility(View.VISIBLE);
time_field.setText("Last Updated:" + " " + response.body().getDt());
} catch (Exception e) {
time_field.setVisibility(View.GONE);
time_field.setText("Last Updated: Unknown");
Log.e("TAG", "No City found");
Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
t.printStackTrace();
}
});
}
});
}
}
活动。xml代码:
<?xml version="1.0" encoding="utf-8"?>
<安卓x.constraintlayout.widget.ConstraintLayout xmlns:安卓="http://schemas.安卓.com/apk/res/安卓"
xmlns:app="http://schemas.安卓.com/apk/res-auto"
xmlns:tools="http://schemas.安卓.com/tools"
安卓:layout_width="match_parent"
安卓:layout_height="match_parent"
安卓:id="@+id/layout"
安卓:background="@drawable/dubai"
tools:context=".Activity.HomeActivity">
<com.google.安卓.material.bottomnavigation.BottomNavigationView
安卓:id="@+id/bottomNavigationView"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:background="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_menu" />
<安卓x.fragment.app.FragmentContainerView
安卓:id="@+id/fragment"
安卓:name="安卓x.navigation.fragment.NavHostFragment"
安卓:layout_width="409dp"
安卓:layout_height="599dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:navGraph="@navigation/my_nav"
/>
<EditText
安卓:id="@+id/textfield"
安卓:layout_width="250dp"
安卓:layout_height="35dp"
安卓:autofillHints="@string/change_city"
安卓:background="@color/colorPrimary"
安卓:hint="@string/search_city"
安卓:inputType="text"
安卓:labelFor="@id/imageView4"
安卓:padding="8dp"
安卓:textColor="@color/colorAccent"
安卓:textSize="16sp"
app:layout_constraintEnd_toStartOf="@+id/imageView4"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
安卓:id="@+id/imageView4"
安卓:layout_width="50dp"
安卓:layout_height="35dp"
安卓:layout_marginEnd="1dp"
安卓:contentDescription="@string/searchbtn"
安卓:src="@drawable/look"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
安卓:id="@+id/textView9"
安卓:layout_width="wrap_content"
安卓:layout_height="wrap_content"
安卓:text="@string/time_field"
安卓:visibility="gone"
安卓:textColor="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textfield" />
</安卓x.constraintlayout.widget.ConstraintLayout>
# 1 楼答案
要从NavHostFragment获得对所显示片段的正确引用,必须先检查片段类类型,然后再尝试向下转换它
根据你的问题:
在其他片段之间切换时,无法始终检索第一个片段或第二个片段实例作为可见片段
因此,只需将代码更改为如下所示: