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);
}