Back to project page u2020-v2.
The source code is released under:
Apache License
If you think the Android project u2020-v2 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.gabor.recyclerview; /* www .j a va2 s. c om*/ import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.gabor.database.Car; import com.gabor.database.CarT; import com.gabor.database.DbHelper; import com.google.gson.Gson; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; import rx.Observable; import rx.Subscriber; import rx.Subscription; import rx.functions.Action1; import rx.schedulers.Schedulers; import rx.subscriptions.Subscriptions; import static rx.android.app.AppObservable.bindFragment; /** * Problem: * You have a data source (where that data is potentially expensive to obtain), and you want to * emit this data into a fragment. However, you want to gracefully deal with rotation changes and * not lose any data already emitted. * <p/> * Solution: * Combine {@link android.app.Fragment#setRetainInstance(boolean)} with * {@link rx.android.schedulers.AndroidSchedulers#mainThread()} and {@link rx.Observable#cache()} */ public class RecyclerViewFragment extends Fragment { private Observable<Car> observables; private Subscription subscription = Subscriptions.empty(); private static int density; private static final String TAG = "RecyclerViewFragment"; public RecyclerViewFragment() { setRetainInstance(true); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); density = getActivity().getResources().getDisplayMetrics().densityDpi; InputStream is = null; try { is = getActivity().getAssets().open("car_list.json"); } catch (Exception e) { Log.i(TAG, e.getMessage()); } if (is != null) observables = bindFragment(this, fakeApiCall(is).cache()); // in retained fragments, it's sufficient to bind the fragment in onCreate, since // Android takes care of detaching the Activity for us, and holding a reference for // the duration of the observable does not harm. } @Override public void onDestroyView() { subscription.unsubscribe(); super.onDestroyView(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getActivity().setProgressBarIndeterminateVisibility(true); return inflater.inflate(R.layout.recycler_view_frag, container, false); } @Override public void onViewCreated(final View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); // (re-)subscribe to the sequence, which either emits the cached result or simply re- // attaches the subscriber to wait for it to arrive subscription = observables.subscribe(new Action1<Car>() { @Override public void call(Car result) { recyclerView.setAdapter(new CustomAdapter(result, density)); getActivity().setProgressBarIndeterminateVisibility(false); } }); } // this would go to a networking class in a production app public static Observable<Car> fakeApiCall(final InputStream is) { return Observable.create(new Observable.OnSubscribe<Car>() { @Override public void call(Subscriber<? super Car> subscriber) { List<CarT> cars = DbHelper.getCars(); Car car; if (cars.size() != 0) car = DbHelper.toCar(cars); else { car = new Gson().fromJson(new InputStreamReader(is), Car.class); DbHelper.save(car); } subscriber.onNext(car); subscriber.onCompleted(); } }).subscribeOn(Schedulers.io()); } }