Which would be the best solution to combine two livedata classes?

  android, android-livedata, switchmap, viewmodel

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

LEAVE A COMMENT