Android之電商Demo模組
本次實現的就是 登入註冊,商品列表 ,商品詳情 購物車,以及視訊ijkplayer的簡單實用:
先來看登入註冊 : 這裡用的網路請求是:Retorfit+Rxjava Mvp的模式
bean類就不用說了 大多都是自動生成的
因為整個模組都是mvp架構和Retorfit+Rxjava組成的所以簡單做了個基類,減少程式碼的複用
Retrofit:的工具類主要實現:
獲取拼接介面的共同部分
實現新增攔截器
實現動態代理模式
預設Gson解析
設定支援Rxjava2
public class RetrofitManager { public static finalString BASE_URL = "http://120.27.23.105/"; private final Retrofit mRetrofit; public static class SINGLE_HOLDER { public static final RetrofitManager INSTANCE = new RetrofitManager(BASE_URL); } public static RetrofitManager getInstance() { return SINGLE_HOLDER.INSTANCE; } privateRetrofitManager(String baseUrl) { mRetrofit = buildRetrofit(); } private OkHttpClient buildOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(10000, TimeUnit.MILLISECONDS) .build(); } private Retrofit buildRetrofit() { return newRetrofit.Builder() .client(buildOkHttpClient()) .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } public <T> T create(Class<T> clazz) { return mRetrofit.create(clazz); } } 下面是 M V層的父類介面 這裡就定義一個空介面即可,為了配合P層的基類public interface Iview { }
public interface Imodel { }重點P層
抽取所操作的共同點public abstract class Ipresenter <T extends Iview>{ protected T view; public Ipresenter(T view) { this.view = view; init(); } protected abstract void init(); }下面的登入註冊的模組
bean都是通過介面自動提取的
V層:public interface Login_view extends Iview { void getYs(bean bean); void getNo(Throwable throwable); }M層:public interface Login_model { @GET("user/login?source=android") Observable<bean>setLoginData(@Query("mobile")String mobile,@Query("password")String password); }public class LoginModel implements Imodel { public Observable<bean> setData(String mobile,String password){ Login_model login_model = RetrofitManager.getInstance().create(Login_model.class); return login_model.setLoginData(mobile,password); } }P層:public class LoginPresenter extends Ipresenter<Login_view> { private LoginModel loginModel; public LoginPresenter(Login_view view) { super(view); } @Override protected void init() { loginModel = new LoginModel(); } public void getLoginJs(String mobile,String password){ Observable<bean> beanObservable = loginModel.setData(mobile, password); beanObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<bean>() { @Override public void accept(bean bean) throws Exception { view.getYs(bean); } } , new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { view.getNo(throwable); } } ); } }登入主類:public class MainActivity extends AppCompatActivity implements Login_view { @InjectView(R.id.mobile) EditText mobile; @InjectView(R.id.password) EditText password; @InjectView(R.id.register) TextView register; @InjectView(R.id.login_but) Button loginBut; PlayerView playerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); } @Override public void getYs(bean bean) { Log.e("login", bean.getMsg() ); UidBean uidBean = new UidBean(bean.getData().getUid()); Log.e("login","uid=="+uidBean.getUid()+""); EventBus.getDefault().postSticky(uidBean); startActivity(new Intent(this, Shop_listActivity.class)); } @Override public void getNo(Throwable throwable) { Log.e("login", throwable.getMessage() ); } @OnClick({R.id.register, R.id.login_but}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.register: startActivity(new Intent(MainActivity.this, RegisterActivity.class)); break; case R.id.login_but: mobile.setText("18236019866"); password.setText("123654"); String mobil= mobile.getText().toString(); String pass = password.getText().toString(); LoginPresenter loginPresenter = new LoginPresenter(this); loginPresenter.getLoginJs(mobil,pass); Log.e("login", mobil+"***"+pass ); break; } } }註冊:
V層:public interface Reg_View extends Iview{ void getYs(RegisterBean bean); void getNo(Throwable throwable); }M層:public interface Reg_Model { @GET("user/reg?source=android") Observable<RegisterBean> setRegnData(@Query("mobile")String mobile, @Query("password")String password); }public class RegModel implements Imodel { public Observable<RegisterBean> setData(String mobile, String password){ Reg_Model Reg_Model = RetrofitManager.getInstance().create(Reg_Model.class); return Reg_Model.setRegnData(mobile,password); } }P層:public class RegPresenter extends Ipresenter<Reg_View> { private RegModel regModel; public RegPresenter(Reg_View view) { super(view); } @Override protected void init() { regModel = new RegModel(); } public void setRegbeanJs(String mobile,String password){ Observable<RegisterBean> registerBeanObservable = regModel.setData(mobile, password); registerBeanObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<RegisterBean>() { @Override public void accept(RegisterBean registerBean) throws Exception { view.getYs(registerBean); } } , new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { view.getNo(throwable); } } ); } }註冊的主類程式碼:public class RegisterActivity extends AppCompatActivity implements Reg_View{ @InjectView(R.id.back) ImageView back; @InjectView(R.id.mobile) EditText mobile; @InjectView(R.id.password) EditText password; @InjectView(R.id.repassword) EditText repassword; @InjectView(R.id.regiser_but) Button regiserBut; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); ButterKnife.inject(this); } @OnClick({R.id.back, R.id.regiser_but}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.back: finish(); break; case R.id.regiser_but: String smobile = mobile.getText().toString(); String spass = password.getText().toString(); String repass = repassword.getText().toString(); if (spass.equals(repass)){ RegPresenter regPresenter = new RegPresenter(this); regPresenter.setRegbeanJs(smobile,spass); }else { Toast.makeText(RegisterActivity.this,"兩次密碼不一致",Toast.LENGTH_LONG).show(); return; } break; } } @Override public void getYs(RegisterBean bean) { Log.e("Register", bean.getMsg() ); if (bean.getCode().equals("0")){ finish(); } } @Override public void getNo(Throwable throwable) { Log.e("Register", throwable.getMessage() ); } }下面是商品分類的:
V層:public interface Shoplist_View extends Iview { void getShopListBean(ShoplistBean bean); }M層:public interface Shoplist_Model { @GET("product/getProducts?pscid=39&source=android") Observable<ShoplistBean>setShoplistData(@Query("page")String page); }public class ShoplistModel implements Imodel { public Observable<ShoplistBean>setShoplistData(String page){ Shoplist_Model shoplist_model = RetrofitManager.getInstance().create(Shoplist_Model.class); return shoplist_model.setShoplistData(page); } }P層:public class ShoplistPresenter extends Ipresenter<Shoplist_View> { private ShoplistModel shoplistModel; public ShoplistPresenter(Shoplist_View view) { super(view); } @Override protected void init() { shoplistModel = new ShoplistModel(); } public void setShoplistData(String page){ Observable<ShoplistBean> shoplistBeanObservable = shoplistModel.setShoplistData(page); shoplistBeanObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<ShoplistBean>() { @Override public void accept(ShoplistBean bean) throws Exception { view.getShopListBean(bean); } }); } }介面卡:public class ShoplistAdapter extends XRecyclerView.Adapter<ShoplistAdapter.Myhoder> { Context context; List<ShoplistBean.DataBean> list; setOnclickitem onclickitem; public void setOnclickitem(setOnclickitem onclickitem) { this.onclickitem = onclickitem; } public ShoplistAdapter(Context context, List<ShoplistBean.DataBean> list) { this.context = context; this.list = list; } @Override public Myhoder onCreateViewHolder(ViewGroup parent, int viewType) { Fresco.initialize(context); View inflate = View.inflate(context, R.layout.shoplist_item, null); Myhoder myhoder = new Myhoder(inflate); return myhoder; } @Override public void onBindViewHolder(Myhoder holder, final int position) { final ShoplistBean.DataBean dataBean = list.get(position); holder.shoplist_price.setText(dataBean.getBargainPrice()+""); holder.shoplist_title.setText(dataBean.getTitle()+""); Uri parse = Uri.parse(dataBean.getImages().split("!")[0]); holder.shoplist_simp.setImageURI(parse); holder.shoplist_title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onclickitem.setitemClick(v,position); } }); } @Override public int getItemCount() { return list.size(); } public interface setOnclickitem{ void setitemClick(View v ,int position); } public class Myhoder extends RecyclerView.ViewHolder { SimpleDraweeView shoplist_simp; TextView shoplist_title,shoplist_price; public Myhoder(View itemView) { super(itemView); shoplist_simp=itemView.findViewById(R.id.shoplist_simp); shoplist_title=itemView.findViewById(R.id.shoplist_title); shoplist_price=itemView.findViewById(R.id.shoplist_price); } } }
商品分類主類程式碼:public class Shop_listActivity extends AppCompatActivity implements Shoplist_View{ @InjectView(R.id.shoplist_xlv) XRecyclerView shoplistXlv; int page=1; private ShoplistPresenter shoplistPresenter; private ShoplistAdapter shoplistAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop_list); ButterKnife.inject(this); shoplistPresenter = new ShoplistPresenter(this); shoplistPresenter.setShoplistData(page+""); } @Override public void getShopListBean(final ShoplistBean bean) { Log.e("shoplist", bean.getMsg() ); shoplistXlv.setLayoutManager(new LinearLayoutManager(this)); shoplistAdapter = new ShoplistAdapter(Shop_listActivity.this, bean.getData()); if (bean.getData()!=null) { shoplistXlv.setAdapter(shoplistAdapter); } shoplistAdapter.setOnclickitem(new ShoplistAdapter.setOnclickitem() { @Override public void setitemClick(View v, int position) { int pid = bean.getData().get(position).getPid(); EventBus.getDefault().postSticky(new Pidbean(pid)); startActivity(new Intent(Shop_listActivity.this,DetailsActivity.class)); } }); shoplistXlv.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { page=1; bean.getData().clear(); shoplistPresenter.setShoplistData(page+""); shoplistXlv.refreshComplete(); } @Override public void onLoadMore() { page=page++; shoplistPresenter.setShoplistData(page+""); shoplistXlv.refreshComplete(); } }); } }
商品詳情:
V層:public interface Details_view extends Iview { void getDetailsData(DetailsBean bean); void addYes(AddBean addBean); }M層:public interface Details_model { @GET("product/getProductDetail?source=android") Observable<DetailsBean> setShoplistData(@Query("pid")String pid); @GET("product/addCart?source=android") Observable<AddBean>AddShopcart(@Query("uid")String uid,@Query("pid")String pid); }public class DetailsModel implements Imodel { public Observable<DetailsBean> setDetailsData(String pid){ Details_model details_model = RetrofitManager.getInstance().create(Details_model.class); return details_model.setShoplistData(pid); } public Observable<AddBean>Addshopcart(String uid ,String pid){ Details_model details_model = RetrofitManager.getInstance().create(Details_model.class); return details_model.AddShopcart(uid,pid); } }P層:public class DetailsPresent extends Ipresenter<Details_view> { private DetailsModel detailsModel; public DetailsPresent(Details_view view) { super(view); } @Override protected void init() { detailsModel = new DetailsModel(); } public void getDetails(String pid){ Observable<DetailsBean> detailsBeanObservable = detailsModel.setDetailsData(pid); detailsBeanObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<DetailsBean>() { @Override public void accept(DetailsBean bean) throws Exception { view.getDetailsData(bean); } }); } public void AddShopcart(String uid,String pid){ Observable<AddBean> addshopcart = detailsModel.Addshopcart(uid, pid); addshopcart .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<AddBean>() { @Override public void accept(AddBean addBean) throws Exception { view.addYes(addBean); } }); } }詳情的主類:public class DetailsActivity extends AppCompatActivity implements Details_view { @InjectView(R.id.details_img) SimpleDraweeView detailsImg; @InjectView(R.id.details_title) TextView detailsTitle; @InjectView(R.id.details_price) TextView detailsPrice; @InjectView(R.id.details_shoper) TextView detailsShoper; @InjectView(R.id.details_add) Button detailsAdd; @InjectView(R.id.details_buy) Button detailsBuy; PlayerView playerView; private int uid; private int pid; private DetailsPresent detailsPresent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fresco.initialize(this); setContentView(R.layout.activity_details); ButterKnife.inject(this); EventBus.getDefault().register(this); playerView = new PlayerView(this) //建立視訊容器 .setTitle("週考3") .setScaleType(PlayStateParams.fitparent) .hideMenu(true) .forbidTouch(false) .setPlaySource("http://ips.ifeng.com/video19.ifeng.com/video09/2014/06/16/1989823-102-086-0009.mp4"); playerView.startPlay(); } @Subscribe(sticky = true) public void getid(Pidbean bean) { int pid = bean.getPid(); detailsPresent = new DetailsPresent(this); detailsPresent.getDetails(pid + ""); Log.e("pid", bean.getPid() + ""); } @Subscribe(sticky = true) public void getUid(UidBean bean) { uid = bean.getUid(); Log.e("Details", uid + "=uid***"); } @Override public void getDetailsData(DetailsBean bean) { Log.e("Details", bean.getMsg()); DetailsBean.DataBean data = bean.getData(); Uri parse = Uri.parse(data.getImages().split("!")[0]); detailsImg.setImageURI(parse); detailsTitle.setText(data.getTitle() + ""); detailsPrice.setText("¥" + data.getBargainPrice() + ""); detailsShoper.setText(bean.getSeller().getName()); pid = data.getPid(); } @Override public void addYes(AddBean addBean) { Toast.makeText(DetailsActivity.this, addBean.getMsg(), Toast.LENGTH_LONG).show(); if (addBean.getMsg().equals("加購成功")){ startActivity(new Intent(DetailsActivity.this,ShopcarActivity.class)); } } @Override public void onStop() { super.onStop(); playerView.stopPlay(); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } @OnClick(R.id.details_add) public void onViewClicked() { Log.e("Details", uid + "***" + pid + ""); detailsPresent.AddShopcart(uid+"",pid+""); } }
登入的佈局:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.bwei.ssp.yuekao.MainActivity" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:gravity="center" > <ImageView android:layout_width="100dp" android:layout_height="100dp" android:background="@mipmap/loge" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:orientation="vertical"> > <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="手機號/會員號/郵箱" android:layout_marginTop="10dp" android:id="@+id/mobile" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="請輸入密碼" android:layout_marginTop="10dp" android:id="@+id/password" android:password="true" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="忘記密碼" /> <TextView android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="點選註冊" android:id="@+id/register" /> </RelativeLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:orientation="vertical" android:gravity="center_horizontal" > <Button android:id="@+id/login_but" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登入" android:textColor="#FFFFFF" android:textSize="35sp"相關推薦
Android之電商Demo模組
本次實現的就是 登入註冊,商品列表 ,商品詳情 購物車,以及視訊ijkplayer的簡單實用: 先來看登入註冊 : 這裡用的網路請求是:Retorfit+Rxjava Mvp的模式 bean類就不用說了 大多都是自動生成的 因為整個模組都是mvp架
Android實現電商購物車模組
前言:先上一張效果圖我們分析分析由上圖可知,一個功能完備的購物車至少要包括:店鋪,店鋪滿減活動,店鋪滿減資訊,商品,滿多少免配送費,頁面商品全選,同一店鋪商品全選(包括反選),選中合計金額,總額,刪除購物車商品,結算調起支付頁面,實時修改商品數量 首先我們去實現介面
分布式架構設計之電商平臺
用戶服 base 介紹 val 重要 本地 交互 pac 一定的 分布式架構設計之電商平臺 何為軟件架構?不同人的答案會有所不同,而我認為一個好的軟件架構除了要具備業務功能外,還應該具備一定的高性能、高可用、高伸縮性及可拓展等非功能需求。而軟件架構是由業務架構和技術架構
ElasticSearch最佳入門實踐(六)案例實戰之電商網站商品管理:多種搜尋方式
1、query string search 搜尋全部商品 took:耗費了幾毫秒 timed_out:是否超時,這裡是沒有 _shards:資料拆成了5個分片,所以對於搜尋請求,會打到所有的primary shard(或者是它的某個replica shard也可以) hits.tot
SSM項目之電商項目easymall(一)
打包 add wire 版本 技術 mapper 分享圖片 json 查詢 一 環境準備 軟件環境: 1 jdk1.8 JAVA_HOME:是給軟件用的,各種啟動的軟件都會尋找JAVA_HOME的環境變量; Path:給windows用的;
推薦系統之電商適用
01 概述: 推薦一直是電商平臺的重要流量入口。以往在電商平臺上,推薦的場景更多的覆蓋在交易的各個環節,比如詳情頁、購物車、訂單及支付等。近年來推薦發展逐漸的多樣化,場景上逐漸覆蓋到各流量入口,推薦的實體也擴充套件到活動、類目、運營位等。 在電商網站裡進行商品推薦,可以
圖片輪播圖之電商大廣告
就按鈕,還有自動播放。有幾個難點,就是最後一張到第一張,和第一張到最後一張的效果無縫切換需要注意一下。然後就是右下角的li根據圖片的索引進行繫結。 程式碼如下 <!DOCTYPE html> <html lang="en"> <head>
Kotlin打造完整電商APP 模組化+MVP+主流框架
第2章 模組化實戰與主流框架配置 本章首先以使用者模組為例,帶大家進行模組化實戰,同時通過使用者註冊功能完善開發環境,最後帶大家配置主流框架,如AndroidExtensions,MVP,Anko、RxKotlin、RxAndroid、Retrofit及Dagger2等,並帶大家優化及拓展前面寫過的程
從0到電商——使用者模組
建立返回物件 根據返回值建立返回物件 返回值 ServerResponse 類:包含三個資料 狀態(status)、資訊(msg)、[ 泛型 ]資料(data) public class ServerResponse<T> imp
年終總結之電商交易系統
年終用最近整理的幾張圖來做一下總結,加入創業團隊代表著做的事情不再是一小塊系統和模組,短、平、快的模式從一開始就註定沒有太多的規範、容忍不影響主流程的一些問題、24小時準備起來修問題。知識廣度的積累會
elasticsearch快速入門案例實戰之電商網站商品管理:叢集健康檢查,CRUD
主要內容: 1、document資料格式 2、電商網站商品管理案例:背景介紹 3、簡單的叢集管理 4、商品的CRUD操作(document CRUD操作) -----------------------------------------------------------------
Solr應用之電商商品搜尋備忘
把以前做電商商品搜尋的經驗歸檔一下。電商的搜尋功能大體上比較相同,從京東、蘇寧、易訊等大型電商都可以觀察出來。電商搜尋功能大致分為幾塊: 1. 商品搜尋、列表的展示,帶排序功能;可能有些產品會要求一個商品不同規格也聚合成一個展示。 2. 類別導航區塊、屬性過濾區塊
【Android開發—電商系列】(二):仿淘寶商品屬性標籤頁
一睹為快 需求 1.動態載入屬性,如尺碼,顏色,款式等 由於每件商品的屬性是不確定的,有的商品的屬性是顏色和尺碼,有的是口味,有的是大小,所以這些屬性不能直接寫死到頁面上。 2.動態載入屬性下的標籤
快速入門案例實戰之電商網站商品管理:巢狀聚合,下鑽分析,聚合分析
第一個分析需求:計算每個tag下的商品數量 GET /ecommerce/product/_search { "aggs": { "group_by_tags": { "terms": { "field": "tags" } } } }
[資料倉庫]電商核心業務知識之訂單商品模組
電商核心業務知識 訂單商品模組(9張表) --訂單主要資訊表 drop table if exists itqsc.ods_b2c_orders; create external table itqsc.ods_b2c_orders ( order_id bigint, -
電商專案之對接支付寶的DEMO
第一步:在支付寶官網下載一個TradePayDemo的原始碼 第二步:設定支付寶閘道器(進入支付寶沙箱網站https://openhome.alipay.com/platform/appDaily.htm?tab=info) open_api_domain = https://openapi
電商專案之支付模組
一、功能 1、支付寶對接 2、支付回撥 3、查詢支付狀態 二、目標 1、熟悉支付寶對接核心文件,調通支付寶支付功能官方的demo 2、解析支付寶SDK對接原始碼 3、RSA1和RSA2驗證簽名及加解密 4、避免支付寶重複通知和資料校驗 5、natapp外網穿透和t
電商專案之商品模組理解(重點加難點)
一、客戶端商品 1、查詢商品詳情(請求引數:Integer productId) a、通過商品id查詢商品 b、判斷查詢出來的商品的狀態是否下架 c、如下架,提示下架,沒下架,將查出來的商品進行組裝成ProductDetailVo返回給前端 2、通過關鍵詞查詢商品詳情(請求參數:
電商專案之訂單模組
一、功能 前臺: 1、建立訂單 2、商品資訊 3、訂單列表 4、訂單詳情 5、取消訂單 後臺: 1、訂單列表 2、訂單搜尋 3、訂單詳情 4、訂單發貨 二、目標 1、避免業務邏輯中橫向越權和縱向越權等安全漏洞 2、設計實用、安全、擴充套件性強大
Android肝帝戰紀之基於上篇單Activity+多Fragment框架,開發電商式導航欄,多Fragment切換
電商式導航欄,多Fragment切換 介面構思示意圖 設計思路 在底部的LinearLayout中新增相應的圖示,然後設定tag繫結相應的 Fragment陣列對應的下標值,再點選切換的時候,根據獲取到的tag值,取出陣列中對應下標的Fragment,在