首先导入依赖
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.squareup.okhttp3:okhttp:3.1.2'
implementation 'com.facebook.fresco:fresco:0.12.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
implementation 'com.squareup.okhttp3:okhttp:3.7.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.google.code.gson:gson:2.8.5'
//导入eventBus的依赖
implementation 'org.greenrobot:eventbus:3.1.1'
//butterknife依赖
implementation 'com.jakewharton:butterknife:9.0.0-rc1'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc1'
//拦截器
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'
//及解决冲突
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '28.0.0'
}
}
}
}
(用的是Retrofit+OkHttp+RxJava)MVP框架
首先搭建好MVP框架(这个不用说)
然后解析一个二级列表购物车Bean类
model层创建一个Api接口类用来跟网络封装类拼接口
public class RetrofitOkRxUtils {
public OkHttpClient okHttpClient;
public final Api api;
private RetrofitOkRxUtils(){
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.SECONDS)
.readTimeout(5,TimeUnit.SECONDS)
.writeTimeout(5,TimeUnit.SECONDS)
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))//拦截器
.build();
//Retrofit+RxJava
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("http://172.17.8.100/")
.build();
api = retrofit.create(Api.class);
}
public static RetrofitOkRxUtils getInstance(){
return OkHolder.instance;
}
private static class OkHolder{
private static RetrofitOkRxUtils instance = new RetrofitOkRxUtils();
}
}
封装类的代码也就这些(感觉相比较okHttp代码少了很多)
View层可以写一个接口包第一个base写成功失败的方法(如下)
然后第二个继承第一个也可以只写一个接口类
接下来是Presenter层两个类
里面有内存泄漏的方法写Activity的时候直接调用就可以
public class MainPresenter extends BasePresenter{
private final RetrofitOkRxUtils retrofitOkRxUtils;
public MainPresenter(){
retrofitOkRxUtils = RetrofitOkRxUtils.getInstance();
}
public void loadData(){
Observable show = retrofitOkRxUtils.api.show_one();
show.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(ShopBean shopBean) throws Exception {
getView().CallBackSuccess(shopBean);
}
});
}
}
这是MainPresenter类
//这是一级列表的Adapter(对应的item就不放上来了)
public class ShopAdapter extends RecyclerView.Adapter
private Context context;
private RecyclerView recyclerView_sp;
private ShopTwoAdapter twoAdapter;
private List mList = new ArrayList<>();
public ShopAdapter(Context context) {
this.context = context;
}
public void setData(List list){
mList.addAll(list);
notifyDataSetChanged();
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.item1,null);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.textView_sj.setText(mList.get(i).getSellerName());
recyclerView_sp.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false));
twoAdapter = new ShopTwoAdapter(context,mList.get(i).getList());
recyclerView_sp.setAdapter(twoAdapter);
}
@Override
public int getItemCount() {
return mList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView textView_sj;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView_sj = itemView.findViewById(R.id.text_sj);
recyclerView_sp =itemView.findViewById(R.id.recyclerView_sp);
}
}
}
//这是二级列表Adapter(命名不是很规范)
public class ShopTwoAdapter extends RecyclerView.Adapter
private Context context;
private List mList = new ArrayList<>();
public ShopTwoAdapter(Context context, List list) {
this.context = context;
mList.addAll(list);
notifyDataSetChanged();
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.item_sp,null);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.textView_sp.setText(mList.get(i).getTitle());
myViewHolder.textView_price.setText("¥:"+mList.get(i).getPrice());
Glide.with(context).load(mList.get(i).getDetailUrl()).into(myViewHolder.imageView);
}
@Override
public int getItemCount() {
return mList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView textView_sp;
private final TextView textView_price;
private final ImageView imageView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView_sp = itemView.findViewById(R.id.text_sp);
textView_price = itemView.findViewById(R.id.text_price);
imageView = itemView.findViewById(R.id.image);
}
}
}
//这就是最后activity要写的东西 实现iMainView 接口类就会导入一个成功一个失败的方法(内存泄漏也在这里面写)
public class MainActivity extends AppCompatActivity implements IMainView {
private RecyclerView recyclerView_sj;
private ShopAdapter shopAdapter;
private MainPresenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainPresenter = new MainPresenter();
mainPresenter.setView(this);
mainPresenter.loadData();
recyclerView_sj = findViewById(R.id.recyclerView_sj);
recyclerView_sj.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
shopAdapter = new ShopAdapter(this);
recyclerView_sj.setAdapter(shopAdapter);
}
@Override
protected void onDestroy() {
super.onDestroy();
mainPresenter.detachView();
}
@Override
public void CallBackSuccess(ShopBean shopBean) {
List data = shopBean.getData();
shopAdapter.setData(data);
}
@Override
public void CallBackFail(String errMsg) {
}
}
最后不要忘记写网络权限!!!
还有二级列表的思路无非就是外面一个recyclerView有一个对应的item.xml
然后写一个Adapter请求实现一级列表,二级列表想要实现就必须在里面嵌套一个recyclerView, 就是在第一个recyclerView对应的item里再写一个recyclerView,接着再写一个对应的item和一个adapter类去实现二级列表,二级列表的具体实现可以写在一级列表的adapter里面。
最后就是这个效果了。(接口给的图片都一样)
这是商品适配器里面的逻辑
这是activity的
public class MyView extends LinearLayout implements View.OnClickListener {
private TextView textView_add;
private TextView textView_jian;
private TextView textView_num;
private int num = 1;
private int position;
private SpAdapter spAdapter;
private List mList = new ArrayList<>();
public MyView(Context context) {
super(context);
initView(context);
}
public MyView(Context context,AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public MyView(Context context,AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.myview,null);
textView_add = view.findViewById(R.id.add);
textView_jian = view.findViewById(R.id.jian);
textView_num = view.findViewById(R.id.text_num);
textView_add.setOnClickListener(this);
textView_jian.setOnClickListener(this);
addView(view);
/*textView_num.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
num = Integer.parseInt(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});*/
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.add:
num++;
textView_num.setText(num+"");
mList.get(position).setCount(num);
mCallBackListener.callBack();
break;
case R.id.jian:
if (num>1){
num--;
}else {
Toast.makeText(getContext(),"不能再减了",Toast.LENGTH_LONG).show();
}
textView_num.setText(num+"");
mList.get(position).setCount(num);
mCallBackListener.callBack();
break;
default:
break;
}
}
public void setData(SpAdapter spAdapter, List mList, int i) {
this.mList = mList;
this.spAdapter = spAdapter;
position = i;
num = mList.get(i).getCount();
textView_num.setText(num+"");
}
private CallBackListener mCallBackListener;
public void setOnCallBack(CallBackListener listener) {
this.mCallBackListener = listener;
}
public interface CallBackListener {
void callBack();
}
}
商品适配器里面调用一下setdata方法就能实现价格联动了