簡單暴力:直接上代碼,清晰明瞭
代碼結構
- activitys - MainActivity.Java
- fragment - BuyGoodFragment.java
- network - factory - MyCustomFactory.java
- network - factory - UserResponseConverter.java
- network - manager - MyRetrofitConverter.java
- network - service - JtmlServer.java
亮出代碼
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Type;
- import okhttp3.ResponseBody;
- import retrofit2.Converter;
- import retrofit2.Retrofit;
-
- public class MyCustomFactory extends Converter.Factory
- {
- @Override
- public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit)
- {
- //根據type判斷是否是自己能處理的類型,不能的話,return null ,交給後面的Converter.Factory
- return new UserResponseConverter(type);
- }
- }
- import com.google.gson.Gson;
- import java.io.IOException;
- import java.lang.reflect.Type;
- import okhttp3.ResponseBody;
- import retrofit2.Converter;
-
- public class UserResponseConverter<T> implements Converter<ResponseBody, T>
- {
- private Type type;
- Gson gson = new Gson();
- public UserResponseConverter(Type type) {
- this.type = type;
- }
- @Override
- public T convert(ResponseBody responseBody) throws IOException {
- String result = responseBody.string();
- T users = gson.fromJson(result, type);
- return users;
- }
- }
- import java.io.File;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.TimeUnit;
- import okhttp3.Cache;
- import okhttp3.CacheControl;
- import okhttp3.Interceptor;
- import okhttp3.OkHttpClient;
- import okhttp3.Request;
- import okhttp3.Response;
- import okhttp3.logging.HttpLoggingInterceptor;
- import retrofit2.Retrofit;
- import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
- import retrofit2.converter.gson.GsonConverterFactory;
- import rx.Observable;
- /**
- */
- public class MyRetrofitManager {
- public static final String BASE_NIUPAI_URL = "private url1";
- public static final String BASE_IMAGE_URL = "private url2";
- //短緩存有效期爲1秒鐘
- public static final int CACHE_STALE_SHORT = 1;
- //長緩存有效期爲7天
- public static final int CACHE_STALE_LONG = 60 * 60 * 24 * 7;
- public static final String CACHE_CONTROL_AGE = "Cache-Control: public, max-age=";
- //查詢緩存的Cache-Control設置,爲if-only-cache時只查詢緩存而不會請求服務器,max-stale可以配合設置緩存失效時間
- public static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_LONG;
- //查詢網絡的Cache-Control設置,頭部Cache-Control設爲max-age=0時則不會使用緩存而請求服務器
- public static final String CACHE_CONTROL_NETWORK = "max-age=0";
- private static OkHttpClient mOkHttpClient;
- private final JtmlServer mJtmlService;
- public static MyRetrofitManager builder() {
- return new MyRetrofitManager();
- }
- private MyRetrofitManager() {
- initOkHttpClient();
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl(BASE_NIUPAI_URL)
- .client(mOkHttpClient)
- .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
- // .addConverterFactory(new MyCustomFactory())
- .addConverterFactory(GsonConverterFactory.create())
- .build();
- mJtmlService = retrofit.create(JtmlServer.class);
- }
- private void initOkHttpClient() {
- HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
- interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
- if (mOkHttpClient == null) {
- synchronized (MyRetrofitManager.class) {
- if (mOkHttpClient == null) {
- // 指定緩存路徑,緩存大小100Mb
- Cache cache = new Cache(new File(App.getContext().getCacheDir(), "HttpCache"),
- 1024 * 1024 * 100);
- mOkHttpClient = new OkHttpClient.Builder()
- .cache(cache)
- .addInterceptor(mRewriteCacheControlInterceptor)
- .addNetworkInterceptor(mRewriteCacheControlInterceptor)
- .addInterceptor(interceptor)
- .retryOnConnectionFailure(true)
- .connectTimeout(15, TimeUnit.SECONDS)
- .build();
- }
- }
- }
- }
- // 雲端響應頭攔截器,用來配置緩存策略
- private Interceptor mRewriteCacheControlInterceptor = new Interceptor() {
- @Override
- public Response intercept(Chain chain) throws IOException {
- Request request = chain.request();
- if (!NetUtil.isNetworkConnected()) {
- request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
- }
- Response originalResponse = chain.proceed(request);
- if (NetUtil.isNetworkConnected()) {
- //有網的時候讀接口上的@Headers裏的配置,你可以在這裏進行統一的設置
- String cacheControl = request.cacheControl().toString();
- return originalResponse.newBuilder().header("Cache-Control", cacheControl).removeHeader("Pragma").build();
- } else {
- return originalResponse.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + CACHE_STALE_LONG).removeHeader("Pragma").build();
- }
- }
- };
- public Observable<List<Comment>> getComments() {
- return mJtmlService.getComments();
- }
- public Observable<List<Notifications>> getNotifications() {
- return mJtmlService.getNotifications();
- }
- public Observable<List<ShowBill>> getShareBills(String id, String pageNo, String pageSize) {
- return mJtmlService.getShareBills(id, pageNo, pageNo);
- }
- public Observable<GoodsDetail> getGoodsDetailById(String id) {
- return mJtmlService.getGoodsDetailById(id);
- }
- public Observable<List<IndexImgList>> getIndexImgList() {
- return mJtmlService.getIndexImgList();
- }
- public Observable<ArrayList<GoodsList>> getGoodList(String id, String pageNo, String pageSize) {
- return mJtmlService.getGoodList(id, pageNo, pageSize);
- }
- }
- import java.util.ArrayList;
- import java.util.List;
- import retrofit2.http.GET;
- import retrofit2.http.Headers;
- import retrofit2.http.Query;
- import rx.Observable;
-
- public interface JtmlServer {
- //評論接口
- @Headers(MyRetrofitManager.CACHE_CONTROL_AGE + MyRetrofitManager.CACHE_STALE_SHORT)
- @GET("share/indexSharecommentsList.action")
- Observable<List<Comment>> getComments();
- //最新揭曉接口
- @Headers(MyRetrofitManager.CACHE_CONTROL_AGE + MyRetrofitManager.CACHE_STALE_SHORT)
- @GET("lottery/lotteryproductutilList.action")
- Observable<List<Notifications>> getNotifications();
- //商品詳情接口
- @Headers(MyRetrofitManager.CACHE_CONTROL_AGE + MyRetrofitManager.CACHE_STALE_SHORT)
- @GET("products/goodsDescAjax.action")
- Observable<GoodsDetail> getGoodsDetailById(@Query("id") String id);
- //曬單接口
- @Headers(MyRetrofitManager.CACHE_CONTROL_AGE + MyRetrofitManager.CACHE_STALE_SHORT)
- @GET("share/ajaxPage.action")
- Observable<List<ShowBill>> getShareBills(@Query("id") String id, @Query("pageNo") String pageNo, @Query("pageSize") String pageSize);
- //主頁面輪播圖接口
- @Headers(MyRetrofitManager.CACHE_CONTROL_AGE + MyRetrofitManager.CACHE_STALE_SHORT)
- @GET("list/indexImgList.action")
- Observable<List<IndexImgList>> getIndexImgList();
- //主頁面商品列表接口
- @Headers(MyRetrofitManager.CACHE_CONTROL_AGE + MyRetrofitManager.CACHE_STALE_SHORT)
- @GET("list/goodsList.action")
- Observable<ArrayList<GoodsList>> getGoodList(@Query("id") String id, @Query("pageNo") String pageNo, @Query("pageSize") String pageSize);
- }
- import butterknife.Bind;
- import rx.android.schedulers.AndroidSchedulers;
- import rx.functions.Action0;
- import rx.functions.Action1;
- import rx.functions.Func1;
- import rx.schedulers.Schedulers;
-
- public class GoodsDetailActivity extends BaseActivity {
- @Bind(R.id.activity_goosdetail_img_back)
- ImageView mImgBack;
- @Bind(R.id.activity_goosdetail_img_share)
- ImageView mImgShare;
- @Bind(R.id.activity_goosdetail_img_cart)
- ImageView mImgCart;
- @Bind(R.id.activity_goosdetail_img_home)
- ImageView mImgHome;
- @Bind(R.id.activity_goosdetail_rv_detail)
- RecyclerViewBaseOnPullToRefresh mRvDetail;
- @Bind(R.id.activity_goosdetail_ll_unsell)
- LinearLayout mLlUnsell;
- @Bind(R.id.activity_goosdetail_ll_selling)
- LinearLayout mLlSelling;
- @Bind(R.id.activity_goosdetail_buy_now)
- TextView mTxtBuyNow;
- @Bind(R.id.activity_goosdetail_add_bill)
- TextView mTxtAddBill;
- @Bind(R.id.activity_goosdetail_go_now)
- TextView mTxtGoNow;
- public final static String LOTTERY_ID = "lotteryProductId";
- public final static String INTENT_FROM = "intentFrom";
- private String lotteryProductId;
- private String intentFrom;
- private Context mContext;
- private App app;
- private RecyclerView.LayoutManager mLayoutManager;
- private GoodsDetailAdapter mGoodsDetailAdapter;
- private View mHeadView;
- private Kanner mKanner;
- public static void start(Context context, String lotteryProductId, String intentFrom) {
- Intent intent = new Intent(context, GoodsDetailActivity.class);
- intent.putExtra(LOTTERY_ID, lotteryProductId);
- intent.putExtra(INTENT_FROM, intentFrom);
- context.startActivity(intent);
- }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putString(LOTTERY_ID, this.lotteryProductId);
- outState.putString(INTENT_FROM, this.intentFrom);
- }
- @Override
- protected int getLayoutId() {
- return R.layout.activity_goods_detail;
- }
- @Override
- protected void afterCreate(Bundle savedInstanceState) {
- mContext = this;
- app = (App) mContext.getApplicationContext();
- app.addClearActivity(this);
- initData(savedInstanceState);
- loadGoodsDetailById();
- }
- private void initData(Bundle savedInstanceState) {
- if (savedInstanceState != null) {
- if (savedInstanceState.containsKey(LOTTERY_ID) && savedInstanceState.containsKey(INTENT_FROM)) {
- this.lotteryProductId = savedInstanceState.getString(LOTTERY_ID);
- this.intentFrom = savedInstanceState.getString(INTENT_FROM);
- }
- }else{
- this.lotteryProductId = getIntent().getExtras().getString(LOTTERY_ID);
- this.intentFrom = getIntent().getExtras().getString(INTENT_FROM);
- }
- mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
- mRvDetail.getRefreshableView().setLayoutManager(mLayoutManager);
- mRvDetail.getRefreshableView().setItemAnimator(new DefaultItemAnimator());
- mGoodsDetailAdapter = new GoodsDetailAdapter();
- setHeader(mRvDetail.getRefreshableView());
- mRvDetail.getRefreshableView().setAdapter(mGoodsDetailAdapter);
- mGoodsDetailAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
- @Override
- public void onItemClick(int position, Object data) {
- }
- });
- //showNewsDetailFragment(news);
- }
- private void setHeader(RecyclerView view) {
- View header = LayoutInflater.from(this).inflate(R.layout.item_good_detail_first, view, false);
- mHeadView = header;
- mGoodsDetailAdapter.setHeaderView(header);
- }
- private void loadGoodsDetailById() {
- MyRetrofitManager.builder().
- getGoodsDetailById(this.lotteryProductId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnSubscribe(new Action0() {
- @Override
- public void call() {
- // showProgress();
- }
- }).map(new Func1<GoodsDetail, GoodsDetail>() {
- @Override
- public GoodsDetail call(GoodsDetail goodsDetail) {
- L.e(goodsDetail.getId());
- return goodsDetail;
- }
- }).subscribe(new Action1<GoodsDetail>() {
- @Override
- public void call(GoodsDetail goodsDetail) {
- L.e(goodsDetail.getId());
- }
- },new Action1<Throwable>() {
- @Override
- public void call(Throwable throwable) {
- L.e(throwable,"Load news detail error");
- }
- });
- }
- }
- mport java.util.ArrayList;
- import java.util.List;
- import butterknife.Bind;
- import rx.android.schedulers.AndroidSchedulers;
- import rx.functions.Action0;
- import rx.functions.Action1;
- import rx.functions.Func1;
- import rx.schedulers.Schedulers;
- /**
- * Created by pengjf on 2016/5/12.
- */
- public class FragmentBuyGood extends BaseFragment {
- @Bind(R.id.fragment_buy_txt_title)
- TextView mTxtTitle;
- @Bind(R.id.fragment_buy_img_search)
- ImageView mImgSearch;
- @Bind(R.id.fragment_buy_rv_goods)
- RecyclerViewBaseOnPullToRefresh mBuyRv;
- Kanner mKanner;
- private App app;
- private Context mContext;
- private RecyclerView.LayoutManager mLayoutManager;
- private GoodListAdapter mGoodListAdapter;
- private String[] imgUrls; //輪播圖需要的url數組
- private String id = "hot20"; //商品默認查詢id
- private String typeId; //商品默認分類id
- private String pageNo = "0"; //商品默認頁數
- private String pageSize = "10"; //商品默認每頁個數
- @Override
- protected int getLayoutId() {
- return R.layout.fragment_buy_good;
- }
- @Override
- protected void afterCreate(Bundle savedInstanceState) {
- mContext = getActivity();
- app = (App) mContext.getApplicationContext();
- initData();
- // if (mNewsListAdapter.getmNewsList().size() == 0) {
- // loadLatestNews();
- // }
- }
- public static FragmentBuyGood newInstance() {
- return new FragmentBuyGood();
- }
- private void initData() {
- mLayoutManager = new GridLayoutManager(mContext, 2);
- mGoodListAdapter = new GoodListAdapter();
- mBuyRv.getRefreshableView().setLayoutManager(mLayoutManager);
- // mBuyRv.getRefreshableView().setItemAnimator(new DefaultItemAnimator());
- // mBuyRv.getRefreshableView().addItemDecoration(new GridItemDecoration(mContext, true));
- mBuyRv.getRefreshableView().setAdapter(mGoodListAdapter);
- setHeader(mBuyRv.getRefreshableView());
- loadHeaderViewData();
- loadGoodListData();
- }
- /**
- * 給RecycleView設置頭部的View
- * @param view
- */
- private void setHeader(RecyclerView view) {
- View header = LayoutInflater.from(mContext).inflate(R.layout.item_fragment_buy_frist, view, false);
- mKanner = (Kanner) header.findViewById(R.id.fragment_buy_kanner);
- mKanner.setVisibility(View.VISIBLE);
- mGoodListAdapter.setHeaderView(header);
- }
- /**
- * 加載RecycleView頭部的View需要的數據
- */
- private void loadHeaderViewData() {
- MyRetrofitManager.builder().getIndexImgList()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnSubscribe(new Action0() {
- @Override
- public void call() {
- // showProgress();
- }
- }).map(new Func1<List<IndexImgList>, List<IndexImgList>>() {
- @Override
- public List<IndexImgList> call(List<IndexImgList> result) {
- return result;
- }
- })
- .subscribe(new Action1<List<IndexImgList>>() {
- @Override
- public void call(List<IndexImgList> result) {
- if(result!=null && result.size()>0) {
- imgUrls = new String[result.size()];
- for (int i = 0; i < result.size(); i++) {
- imgUrls[i] = MyRetrofitManager.BASE_IMAGE_URL + result.get(i).getProImg();
- }
- mKanner.setImagesUrl(imgUrls);
- }else{ //服務器返回數據異常情況待處理
- }
- }
- }, new Action1<Throwable>() {
- @Override
- public void call(Throwable throwable) {
- //mAutoLoadListener.setLoading(false);
- L.e(throwable, "Load before news error");
- throwable.printStackTrace();
- //mLoadBeforeSnackbar.show();
- }
- });
- }
- private void loadGoodListData() {
- MyRetrofitManager.builder().getGoodList(this.id,this.pageNo,this.pageSize)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnSubscribe(new Action0() {
- @Override
- public void call() {
- // showProgress();
- }
- }).map(new Func1<ArrayList<GoodsList>, ArrayList<GoodsList>>() {
- @Override
- public ArrayList<GoodsList> call(ArrayList<GoodsList> result) {
- return result;
- }
- })
- .subscribe(new Action1<ArrayList<GoodsList>>() {
- @Override
- public void call(ArrayList<GoodsList> result) {
- //服務器成功返回數據
- if(result!=null && result.size()>0) {
- mGoodListAdapter.addDatas(result);
- }else{ //服務器返回數據異常情況待處理
- }
- }
- }, new Action1<Throwable>() {
- @Override
- public void call(Throwable throwable) {
- //mAutoLoadListener.setLoading(false);
- L.e(throwable, "Load before news error");
- throwable.printStackTrace();
- //mLoadBeforeSnackbar.show();
- }
- });
- }
- }
gradle
- dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- testCompile 'junit:junit:4.12'
- compile 'com.android.support:appcompat-v7:23.2.0'
- compile 'com.android.support:support-v4:23.2.1'
- compile 'com.android.support:recyclerview-v7:23.2.1'
- compile 'com.android.support:cardview-v7:23.2.1'
- compile 'com.android.support:design:23.2.1'
- // retrofit2 + okhttp3
- compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
- compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
- compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
- compile 'com.squareup.okhttp3:okhttp:3.2.0'
- compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
- // rxjava
- compile 'io.reactivex:rxandroid:1.1.0'
- compile 'io.reactivex:rxjava:1.1.0'
- // gson react
- compile 'com.google.code.gson:gson:2.6.2'
- compile 'com.jakewharton:butterknife:7.0.1'
- compile project(':pulltorefresh_lib')
- compile 'com.android.support:support-v13:+'
- compile 'com.github.bumptech.glide:glide:3.7.0'
- compile 'com.yalantis:phoenix:1.2.3'
- }