Hello all
Im trying to learn something new and learn android for almost 4 months. I decided to use livedata and viewmodel for different usages like a network call or location request!
Both work perfect but I have a big issue for almost a week!
How to combine two livedata classes?
It might be an easy answer and would help me a lot cause Im desperate for days and don´t know how to combine two livedata classes.
My plan:
Get a result of the location livedata (which for now works well and give me some location infos) and set the result inside another livedata class Ive made where I get some network response.
I want to use the result of the location livedata as params to get local resutls out of my database.
I don´t understand how to use switchmap
I learned a bit about switchmap and map functions and think it would probably the solution but I searched now for days and don´t know how to use switchmap and how to write the function that I got working results.
Im stuck I´ve tryed everything searched everywhere but I don´t understand how to use it on the right way.
I only want to learn something new and would be very thankful for every attempt to help me!
My Viewmodel class:
public class newLiveData extends AndroidViewModel {
private static final String TAG = "Viewmodel 123332";
private LiveDataEvents data;
LocationLiveData locationLiveData;
LiveData<LiveDataEvents> newData;
public newLiveData(Application application) {
super(application);
locationLiveData = new LocationLiveData(application);
data = new LiveDataEvents(application);
data=Transformations.switchMap(locationLiveData, location -> {
data.getLocation(location);
return data;
});
}
public LiveData<ArrayList<Data>> getData() {
return data;
}
public LocationLiveData getLocation() {
return locationLiveData;
}
public void setloc(Location location){
data.getLocation(location);
}
public LiveData<LiveDataEvents> getNewData(){
return newData;
}
}
My Fragment where I got the result and display the network response in recyclerview with a custom clicklistener:
public class Home_Fragment_All extends Fragment implements LifecycleOwner {
LinearLayoutManager linearLayoutManager;
private static final String TAG = "Home_Fragment";
BottomNavigationView bottomNav;
private int scrolledDistance = 0;
private static final int HIDE_THRESHOLD = 1;
private boolean controlsVisible = true;
EventHolder eventHolder=new EventHolder();
Home_Fragment_All context;
newLiveData viewModel;
public RecyclerView recyclerView;
Recyclerheader recyclerViewAdapter;
Fragment active=this;
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
@NotNull Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home_all, container, false);
Log.d(TAG, "onCreateView: createview");
// Inflate the layout for this fragment
context=this;
viewModel = ViewModelProviders.of(context).get(newLiveData.class);
viewModel.getLocation().observe(this.getViewLifecycleOwner(), LocationObserver);
viewModel.getData().observe(this.getViewLifecycleOwner(), userListUpdateObserver);
linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
bottomNav=((MainActivity) requireActivity()).findViewById(R.id.navigation);
//Configuration Button
Button configuration_button = view.findViewById(R.id.configuration_button);
configuration_button.setOnClickListener(view1 -> openDialog());
Button button = view.findViewById(R.id.menu_button);
button.setOnClickListener(v -> ((MainActivity) getActivity()).hamMenu(view));
recyclerView = view.findViewById(R.id.recyclerview);
recyclerView.setNestedScrollingEnabled(true);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NotNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
scrolledDistance = dy;
if (scrolledDistance > HIDE_THRESHOLD && controlsVisible) {
hideViews();
controlsVisible = false;
} else if (scrolledDistance < -HIDE_THRESHOLD && !controlsVisible) {
showViews();
controlsVisible = true;
}
}
});
return view;
}
Observer<ArrayList<Data>> userListUpdateObserver = new Observer<ArrayList<Data>>() {
@Override
public void onChanged(ArrayList<Data> DATA) {
recyclerViewAdapter = new Recyclerheader(getContext(), DATA, new OnClickListenerEvent() {
@Override
public void respond(int position, String EventName, String Location, String Eventhost, String Genre, String Artist, String City, String Adress, String Information, String Date, String StartTime, String EndTime, String Price) {
Bundle bundle=new Bundle();
bundle.putString("name", Name);
bundle.putString("Event", Location);
bundle.putString("Eventhost",Eventhost);
bundle.putString("Genre",Genre);
bundle.putString("Artist",Artist);
bundle.putString("City",City);
bundle.putString("Adress",Adress);
bundle.putString("Information",Information);
bundle.putString("Date",Date);
bundle.putString("StartTime",StartTime);
bundle.putString("EndTime",EndTime);
bundle.putString("Price",Price);
eventHolder.setArguments(bundle);
FragmentTransaction transaction= requireActivity().getSupportFragmentManager().beginTransaction();
bottomNav=((MainActivity) requireActivity()).findViewById(R.id.navigation);
((MainActivity) requireActivity()).hideBottomNavigationView(bottomNav);
requireActivity().getSupportFragmentManager().beginTransaction().add(R.id.main_container, eventHolder, "4").hide(eventHolder).addToBackStack("4").commit();
transaction.setCustomAnimations( R.animator.fragmentsliderightout,R.animator.leftslideout,
R.animator.leftslidein,R.animator.fragementslideinright).hide(active).show(eventHolder).addToBackStack("4").commit();
active = eventHolder;
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.notifyDataSetChanged();
}
};
Observer<Location> LocationObserver = new Observer<Location>() {
@Override
public void onChanged(@Nullable Location location) {
Log.d(TAG, "onChanged: location updated " + location);
String lat1= String.valueOf(location.getLatitude());
String lng1= String.valueOf(location.getLongitude());
Log.d(TAG, "onChanged: "+lat1+lng1);
Log.d(TAG, "onChanged: worked?");
}
};
private void openDialog()
{
Config_Fragment.display(getActivity().getSupportFragmentManager());
}
private void hideViews() {
bottomNav.animate().translationY(bottomNav.getHeight()).setInterpolator(new AccelerateInterpolator(2));
}
private void showViews() {
bottomNav.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
}
@Override
public void onResume() {
new MainActivity().showBottomNavigationView(bottomNav);
super.onResume();
}
}
My location livedata:
public class LocationLiveData extends MediatorLiveData<Location> {
public LocationManager locationManager;
private static final String TAG = "Viewmodel";
private final Context context;
Location Location;
public LocationLiveData(Context context) {
this.context = context;
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
public LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
setValue(location);
Location=location;
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
@Override
protected void onActive() {
super.onActive();
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 10, locationListener);
}
@Override
protected void onInactive() {
super.onInactive();
locationManager.removeUpdates(locationListener);
}
}
My Networkcall livedata class
public class LiveDataEvents extends LiveData<ArrayList<Data>>{
private static final String TAG = "Viewmodel";
private final Context context;
private final FileObserver fileObserver;
MutableLiveData<ArrayList<Data>> userlivedata;
ArrayList<Data> DATA;
LocationLiveData LocationLiveData;
String lat1;//="49.984738";
String lng1;//="8.673877";
String Account="[email protected]";
LiveData<Double> liveLat;
LiveData<Double> livelng;
Location loc;
public LiveDataEvents(Context context) {
this.context = context;
String path = new File(context.getFilesDir(),
Config.URL_ADD).getPath();
fileObserver = new FileObserver(path) {
@Override
public void onEvent(int event, String path) {
// The file has changed, so let’s reload the data
loadData();
}
};
loadData();
}
public void getLocation(Location location){
loc=location;
if (loc!=null) {
lat1 = String.valueOf(loc.getLatitude());
lng1 = String.valueOf(loc.getLongitude());
}
}
@Override
protected void onActive() {
fileObserver.startWatching();
}
@Override
protected void onInactive() {
fileObserver.stopWatching();
}
public void loadData() {
Account=getGE.getEmail(context);
StringRequest request = new StringRequest(Request.Method.POST, Config.URL_ADD, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
DATA=new ArrayList<>();
try {
JSONArray responsearray = new JSONArray(response);
//Populate the EmployeeDetails list from response
for (int i = 0; i < responsearray.length(); i++) {
JSONObject event = responsearray.getJSONObject(i);
Data events = new Data();
events.setId(event.getInt("ID"));
events.setName(event.getString("name"));
events.setEvent(event.getString("location"));
events.setEventHost(event.getString("Eventhost"));
events.setGENRE(event.getString("Genre"));
events.setArt(event.getString("Art"));
events.setArtist(event.getString("Artist"));
events.setFloor(event.getString("Floor"));
events.setInformation(event.getString("Information"));
events.setDATE(event.getString("Date"));
events.setCITY(event.getString("City"));
events.setAdress(event.getString("Adress"));
events.setStartTIME(event.getString("StartTime"));
events.setEndTIME(event.getString("EndTime"));
events.setPRICE(event.getString("Price"));
events.setUserLikedState(event.getInt("State"));
events.setId(event.getInt("Likes"));
DATA.add(events);
}
setValue(DATA);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String,String> params = new HashMap<>();
Log.d(TAG, "getParams: "+lat1+lng1);
params.put(Config.KEY_EMP_LAT,lat1);
params.put(Config.KEY_EMP_LNG,lng1);
params.put(Config.KEY_UserEmail,Account);
return params;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(30000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingelton.getmInstance(context).addToRequestQueue(request);
}
}
Source: Android Questions