1. 程式人生 > >MVP+Recycleview實現輪播圖實現京東秒殺效果

MVP+Recycleview實現輪播圖實現京東秒殺效果

MVP+Recycleview實現輪播圖,京東秒殺

2018年12月02日 19:55:26 遷就 閱讀數:830

1:先看看效果
在這裡插入圖片描述

2:build.gradle中匯入依賴

//依賴
implementation ‘com.jakewharton:butterknife:8.8.1’
annotationProcessor ‘com.jakewharton:butterknife-compiler:8.8.1’
implementation ‘com.google.code.gson:gson:2.8.5’
compile ‘com.squareup.okhttp3:okhttp:3.4.2’
implementation ‘com.facebook.fresco:fresco:0.14.1’
compile ‘com.nostra13.universalimageloader:universal-image-loader:1.9.5’
compile ‘com.android.support:recyclerview-v7:27.1.1’
implementation ‘com.github.bumptech.glide:glide:4.8.0’
annotationProcessor ‘com.github.bumptech.glide:compiler:4.8.0’

3:AndroidManifest.xml清單檔案中加入許可權

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  • 1
  • 2
  • 3
  • 4

4:主佈局

在這裡插入圖片描述
程式碼:

<?xml version="1.0" encoding="utf-8"?>

 

<!--輪播圖的RecyclerView佈局-->
<android.support.v7.widget.RecyclerView
    android:id="@+id/img_rcv"
    android:layout_width="match_parent"
    android:layout_height="300px">
</android.support.v7.widget.RecyclerView>

<!--倒計時佈局-->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="京東秒殺"
        android:textSize="28px"
        android:textColor="#FF0000"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30px"
        android:text="秒殺剩餘時間5s"
        />
</LinearLayout>

<!--秒殺的RecyclerView佈局-->
<android.support.v7.widget.RecyclerView
    android:id="@+id/my_rcv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ></android.support.v7.widget.RecyclerView>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

分包:

在這裡插入圖片描述

5.建立MVP框架實現

5.0:請求資料介面

http://result.eolinker.com/umIPmfS6c83237d9c70c7c9510c9b0f97171a308d13b611?uri=homepage

5.1:建立bean類:

5.2:OkHttpUtils工具類

public class OkHttpUtils {
//單例模式,把構造方法進行私有化
//
private OkHttpUtils(){};
static OkHttpClient client;

public static OkHttpClient getInstance(){

    if (client==null) {
  • 1
  • 2
  • 3

//更加安全
synchronized (OkHttpUtils.class) {
//快取的地方 mnt/sdcard
File file = new File(Environment.getExternalStorageDirectory(), “cache11”);
client = new OkHttpClient().newBuilder()
.readTimeout(3000, TimeUnit.SECONDS) //設定讀取超時時間
.connectTimeout(3000, TimeUnit.SECONDS) //設定連線的超時時間

                    .cache(new Cache(file, 10 * 1024))
                    .build();
        }
    }
    return client;
}


/**
 * get請求
 * Callback  是一個介面
 */
public static void doGet(String url, Callback callback){

    //1:拿到okhttpclient  對像

    OkHttpClient client = getInstance();
    //2:進行請求的操作

    Request request = new Request.Builder()
            .url(url)
            .build();
    client.newCall(request).enqueue(callback);


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

//post請求

/**
 *
 * @param url  請求的地址
 * @param parms   請求的引數
 * @param callback  callback
 */
public static void doPost(String url, Map<String,String> parms, Callback callback){

    //得到客戶端的對像
    OkHttpClient client = getInstance();

    //不是FormBody,而是一個Builder
    FormBody.Builder body = new FormBody.Builder();
    //key   value
    for (String key:parms.keySet()){
        //value的值
        body.add(key,parms.get(key));
    }
    Request request = new Request.Builder()
            .url(url)
            .post(body.build())
            .build();

    client.newCall(request).enqueue(callback);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

//用來上傳圖片的

//url  , 圖片  ,引數    Callback
public static  void upImage(String url,File file,String filenName,Map<String,String> params,Callback callback){

    OkHttpClient client = getInstance();


    //requestBody的實現類  Formbody
    MultipartBody.Builder builder = new MultipartBody.Builder();

    if (params!=null){
        for (String key :params.keySet()){
            builder.addFormDataPart(key,params.get(key));
        }
    }

    //設定型別
    builder.setType(MultipartBody.FORM);


    builder.addFormDataPart("file",filenName, RequestBody.create(MediaType.parse("application/octet-stream"),file));

    // builder.setType(MultipartBody.FORM);
    // builder.addFormDataPart("file",filenName,RequestBody.create(MediaType.parse("application/octet-stream"),file));
    //builder.addFormDataPart("file","aa.png",builder.build());

    Request request = new Request.Builder()
            .url(url)
            .post(builder.build())
            .build();

    client.newCall(request).enqueue(callback);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

}

5.3:model層

1:
public interface DataModel {
//請求資料的方法
void getData(String url, DataPresenter presenter);
}
2:
public class MyDataModel implements DataModel {
//請求資料的方法
@Override
public void getData(String url, final DataPresenter presenter) {

    OkHttpUtils.doGet(url, new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {}

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //接收返回的資料
            String json = response.body().string();

            //進行解析 得到集合
            Gson gson = new Gson();
            Shop myDataBean = gson.fromJson(json, Shop.class);
            Shop.DataBean data = myDataBean.getData();

            //呼叫P層方法將資料傳給P層
            presenter.Success(data);
        }
    });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

}

view層

public interface DataView {
//接收資料的方法
void toBackHome(Shop.DataBean data);
}

presenter層

1:
public interface DataPresenter {
//成功與失敗的方法
void Success(Shop.DataBean data);
void Error();
}

2:
public class MyDataPresenter implements DataPresenter {
DataView dataView;
private final MyDataModel myDataModel;
public MyDataPresenter(DataView dataView) {
this.dataView=dataView;
myDataModel = new MyDataModel();
}

//成功
@Override
public void Success(Shop.DataBean data) {
    dataView.toBackHome(data);

}
//失敗
@Override
public void Error() {}

public void netWork(String url){
    myDataModel.getData(url,this);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

}

application類

public class App extends Application{
@Override
public void onCreate() {
super.onCreate();

    //初始化Fresco使用預設配置
    Fresco.initialize(this);
}
  • 1
  • 2
  • 3

}

實現輪播圖的介面卡

1:佈局SimpleDraweeView控制元件實現:

<?xml version="1.0" encoding="utf-8"?>

 

<!--輪播圖的圖片控制元件-->
<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/item_sdv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop">
</com.facebook.drawee.view.SimpleDraweeView>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2:adapter中

public class ImgAdapter extends RecyclerView.Adapter{
Context context;
List<Shop.DataBean.Ad1Bean> list;
public ImgAdapter(Context context, List<Shop.DataBean.Ad1Bean> list) {
this.context=context;
this.list=list;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    //引入輪播圖佈局
    View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.img_item,parent,false);

    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    MyViewHolder myViewHolder = (MyViewHolder) holder;

    //為輪播圖賦圖片
    myViewHolder.item_sdv.setImageURI(list.get(position%list.size()).getImage());

}

@Override
public int getItemCount() {
    return Integer.MAX_VALUE;
}
class MyViewHolder extends RecyclerView.ViewHolder{

    private final SimpleDraweeView item_sdv;

    public MyViewHolder(View view) {
        super(view);

        //找到佈局檔案中的ID
        item_sdv = view.findViewById(R.id.item_sdv);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

}

京東秒殺介面卡:

1:佈局SimpleDraweeView+textview實現

<?xml version="1.0" encoding="utf-8"?>

 

<!--秒殺圖的圖片控制元件-->
<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/rcv_sdv"
    android:layout_width="200px"
    android:layout_height="200px"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    fresco:actualImageScaleType="centerCrop"
    fresco:placeholderImageScaleType="centerCrop"
    fresco:roundAsCircle="true"
    fresco:placeholderImage="@drawable/ic_launcher_background" />

<!--秒殺顯示價格的控制元件-->
<TextView
    android:id="@+id/rcv_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10px"
    android:layout_marginLeft="30px"
    android:layout_marginTop="20px"
    android:textColor="#FF0000"
    android:text="¥49.90"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2:adapter中

public class MsAdapter extends RecyclerView.Adapter{
Context context;
List<Shop.DataBean.DefaultGoodsListBean> list;
public MsAdapter(Context context, List<Shop.DataBean.DefaultGoodsListBean> list) {
this.context=context;
this.list=list;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    //引入秒殺佈局檔案
    View view = View.inflate(context, R.layout.ms_item, null);
    MyViewHolder myViewHolder = new MyViewHolder(view);

    return myViewHolder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    MyViewHolder myViewHolder = (MyViewHolder) holder;

    //為秒殺賦值
    myViewHolder.rcv_tv.setText("¥"+list.get(position).getShop_price());
    myViewHolder.rcv_sdv.setImageURI(list.get(position).getGoods_img());
}

@Override
public int getItemCount() {
    return list.size();
}

class MyViewHolder extends RecyclerView.ViewHolder{

    private final SimpleDraweeView rcv_sdv;
    private final TextView rcv_tv;

    public MyViewHolder(View view) {
        super(view);
        //找到秒殺佈局中的控制元件ID
        rcv_sdv = view.findViewById(R.id.rcv_sdv);
        rcv_tv = view.findViewById(R.id.rcv_tv);

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

}

最後一個Actvity中

public class MainActivity extends Activity implements DataView {
String url = “http://result.eolinker.com/umIPmfS6c83237d9c70c7c9510c9b0f97171a308d13b611?uri=homepage”;

private List<Shop.DataBean.Ad1Bean> imglist;
private int item=5;

Handler handler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //接收資料
        Shop.DataBean data = (Shop.DataBean) msg.obj;

        //設定輪播圖 進入輪播圖介面卡
        imglist = data.getAd1();
        ImgAdapter imgAdapter = new ImgAdapter(MainActivity.this, imglist);
        final LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
        imgRcv.setLayoutManager(layoutManager);
        imgRcv.setHasFixedSize(true);
        imgRcv.setAdapter(imgAdapter);

        PagerSnapHelper snapHelper = new PagerSnapHelper();
        snapHelper.attachToRecyclerView(imgRcv);

        imgRcv.scrollToPosition(imglist.size() * 10);

        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                imgRcv.smoothScrollToPosition(layoutManager.findFirstVisibleItemPosition() + 1);
            }
        }, 2000, 2000, TimeUnit.MILLISECONDS);


        //設定秒殺,進入秒殺介面卡
        List<Shop.DataBean.DefaultGoodsListBean> defaultGoodsList = data.getDefaultGoodsList();
        MsAdapter adapter = new MsAdapter(MainActivity.this, defaultGoodsList);
        myRcv.setAdapter(adapter);

    }
};

Handler handler2 = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if(msg.what==0){
            item--;
            tvItem.setText("秒殺剩餘時間"+item+"s");
            handler2.sendEmptyMessageDelayed(0,1000);
        }
        if(item==0){
            //實現頁面跳轉
            //這裡的跳轉actvity是京東秒殺倒計時跳轉的頁面,沒有什麼東西,建立一個actvity就好
            Intent intent = new Intent(MainActivity.this,MsActivity.class);
            startActivity(intent);
            finish();
        }

    }
};

@BindView(R.id.my_rcv)
RecyclerView myRcv;
@BindView(R.id.img_rcv)
RecyclerView imgRcv;
@BindView(R.id.tv_item)
TextView tvItem;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    //例項化P層
    MyDataPresenter myDataPresenter = new MyDataPresenter(this);
    myDataPresenter.netWork(url);

    //設定管理器
    myRcv.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false));

    //設定倒計時跳轉頁面
    handler2.sendEmptyMessageDelayed(0,1000);

}

//接收資料的方法
@Override
public void toBackHome(Shop.DataBean data) {
    Message msg = new Message();
    msg.obj = data;
    handler.sendMessage(msg);
}