'Android binding data from activity to fragment using ViewModel
I have used a android studio project with BottomNavigationView and it creates an activity and 3 fragments (home, dashboard amd notifications) In the main activity i have a AsyncTask and it works fine since i receive the data.The problem is that i want to send this data to Fragment using the ViewModel but i'm not getting this working When the apk start goes directly to home Fragment....
This is what i have in activity
public class MainActivity extends AppCompatActivity implements MyWeatherTaskListener
{
final String mApiKey = "ec34c9eacb4b79a523b5e6ac7a8exxxx";
final String mCity = "Viana do Castelo";
final String mCountry = "Portugal";
private ActivityMainBinding binding;
private FragmentHomeBinding fragmentHomeBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
BottomNavigationView navView = findViewById(R.id.nav_view);
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home,
R.id.navigation_dashboard,
R.id.navigation_notifications,
R.id.navigation_login)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(binding.navView, navController);
String weatherURL = "https://api.openweathermap.org/data/2.5/weather?q=" + mCity + "," + mCountry + "&lang=pt" + "&APPID=" + mApiKey;
new MyWeatherTask(this).execute(weatherURL);
}
@Override
public void onMyWeatherTaskPreExecute() {
}
public void onMyWeatherTaskPostExecute(MyWeather myWeather)
{
if (myWeather != null)
{
//Calling the Fragment?? Not sure if it is right
fragmentHomeBinding.weatherConditionTextView.setText(myWeather.getWeatherCondition());
fragmentHomeBinding.weatherDescriptionTextView.setText(myWeather.getWeatherDescription());
int temp = Math.round(myWeather.getTemperature() - 273.15f);
String tempStr = String.valueOf(temp);
fragmentHomeBinding.temperatureTextView.setText(tempStr);
String imgUrl = "http://openweathermap.org/img/wn/" + myWeather.getWeatherIconStr() + "@2x.png";
Glide.with(MainActivity.this)
.asBitmap()
.load(imgUrl)
.placeholder(R.mipmap.ic_launcher)
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
.into(fragmentHomeBinding.weatherIconImageView);
}
fragmentHomeBinding.myLoadingLayout.setVisibility(View.GONE);
}
}
My HomeViewModel
public class HomeViewModel extends ViewModel {
private final MutableLiveData<MyWeather> selectedItem = new MutableLiveData<MyWeather>();
public void selectItem(MyWeather item) {
selectedItem.setValue(item);
}
public MutableLiveData<MyWeather> getSelectedItem() {
return selectedItem;
}
}
Then my HomeFragment is called...
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
private FragmentHomeBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
my HomeFrgment layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".ui.home.HomeFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<TextView
android:id="@+id/cityTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/viana_do_castelo"
android:textColor="@color/black"
android:textSize="22sp"/>
<TextView
android:id="@+id/countryTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/portugal"
android:textColor="@color/black"
android:textSize="16sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:orientation="horizontal"
android:baselineAligned="false">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end|center"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/temperatureTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/_temp"
android:textColor="@color/black"
android:textSize="52sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="@string/u2103"
android:textColor="@color/black"
android:textSize="22sp"/>
</LinearLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:padding="10dp">
<ImageView
android:id="@+id/weatherIconImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
tools:ignore="ContentDescription"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
</LinearLayout>
<TextView
android:id="@+id/weatherConditionTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:gravity="center"
android:text="@string/condition_"
android:textColor="@color/black"
android:textSize="18sp"/>
<TextView
android:id="@+id/weatherDescriptionTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/description_"
android:textColor="@color/black"
android:textSize="14sp"/>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="@+id/myLoadingLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#33000000"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/esperar"
android:textColor="@color/black"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Errors
java.lang.NullPointerException: Attempt to read from field 'android.widget.TextView com.gmc.esmaior.databinding.FragmentHomeBinding.weatherConditionTextView' on a null object reference
at com.gmc.esmaior.MainActivity.onMyWeatherTaskPostExecute(MainActivity.java:64)
at com.gmc.esmaior.tempo.MyWeatherTask.onPostExecute(MyWeatherTask.java:43)
at com.gmc.esmaior.tempo.MyWeatherTask.onPostExecute(MyWeatherTask.java:6)
at android.os.AsyncTask.finish(AsyncTask.java:771)
at android.os.AsyncTask.access$900(AsyncTask.java:199)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
