首先先写接口
public interface ApiService {
/**
* 首页接口
* http://172.17.8.100/small/commodity/v1/findCommodityByKeyword?keyword=手机&page=1&count=10
*
* public static final String ShowUrl="http://172.17.8.100/small/commodity/v1/";
*/
@GET("findCommodityByKeyword")
Flowable<ShowBean> getShow(@Query("keyword") String keyword, @Query("page") int page, @Query("count")int count);
/**
* 点击详情的接口
* http://172.17.8.100/small/commodity/v1/findCommodityDetailsById?commodityId=105
*
* public static final String DetailsUrl="http://172.17.8.100/small/commodity/v1/";
*/
@GET("findCommodityDetailsById")
Flowable<DetailsBean> getDetails(@Query("commodityId") int commodityId);
然后去写网络工具类
public class RetrofitUtils {
/**
* 单例模式
*/
public static RetrofitUtils retrofitUtils;
public RetrofitUtils(){
}
public static RetrofitUtils getInstance(){
if (retrofitUtils==null){
synchronized (RetrofitUtils.class){
if (retrofitUtils==null){
retrofitUtils=new RetrofitUtils();
}
}
}
return retrofitUtils;
}
/**
* 获取OkHttp
*/
private static OkHttpClient okHttpClient;
public static synchronized OkHttpClient getOkHttpClient(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
}
});
okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY))
.connectTimeout(2000,TimeUnit.SECONDS)
.readTimeout(2000,TimeUnit.SECONDS)
.build();
return okHttpClient;
}
/**
* 获取Retrofit
*/
private static Retrofit retrofit;
public static synchronized Retrofit getRetrofit(String url){
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient())
.build();
return retrofit;
}
/**
* 获取动态权限
*/
public <T> T doGet(String url,Class<T> apiService){
retrofit = getRetrofit(url);
T t = retrofit.create(apiService);
return t;
}
}
接下来写M,V,P 首先先写P层 我们可以吧防止内存泄漏抽基类
public abstract class BasePresenter<T> {
private Reference<T> tReference;
public void attachView(T t){
tReference = new WeakReference<>(t);
}
public void deatchView(){
if (tReference!=null){
tReference.clear();
tReference=null;
}
}
}
展示页面的V,M
页面展示的M
public class ShowModel {
public void getHttpData(String keyword,int page,int count){
ApiService apiService = RetrofitUtils.getInstance().doGet(Api.ShowUrl, ApiService.class);
Flowable<ShowBean> show = apiService.getShow(keyword, page, count);
show.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSubscriber<ShowBean>() {
@Override
public void onNext(ShowBean resultBean) {
if (showLisetener!=null){
showLisetener.getShow(resultBean);
}
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
/**
* 接口回调
*/
public interface onShowLisetener{
void getShow(ShowBean showBean);
}
onShowLisetener showLisetener;
public void setShowLisetener(onShowLisetener showLisetener){
this.showLisetener=showLisetener;
}
}
v就写一个接口
public interface ShowView {
void getShowData(ShowBean showBean);
}
展示数据页面的P
public class ShowPresneter extends BasePresenter<ShowView>{
private ShowView showView;
private ShowModel showModel;
public ShowPresneter(ShowView view){
this.showView=view;
showModel=new ShowModel();
}
public void onRelated(String keyword,int page,int count){
showModel.getHttpData(keyword,page,count);
showModel.setShowLisetener(new ShowModel.onShowLisetener() {
@Override
public void getShow(ShowBean showBean) {
showView.getShowData(showBean);
}
});
}
}
然后写展示首页的适配器
public class ShowAdapter extends RecyclerView.Adapter<ShowAdapter.ViewHoder> {
private Context context;
private List<ShowBean.ResultBean> list;
public ShowAdapter(Context context, List<ShowBean.ResultBean> list) {
this.context = context;
this.list = list;
}
@NonNull
@Override
public ViewHoder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
//这个地方是加载布局使用错误了 LayoutInflater 这个来加载
//刚刚错误的是用的是线性布局去加载了 之后看方法参数 可以用快捷键 ctrl+p可以看出需要传入几个参数及类型
View view = LayoutInflater.from(context).inflate(R.layout.showitem, viewGroup, false);
return new ViewHoder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHoder viewHoder, final int i) {
//list = new ArrayList<>();
viewHoder.name.setText(list.get(i).getCommodityName());
viewHoder.price.setText(list.get(i).getPrice() + "¥");
Glide.with(context).load(list.get(i).getMasterPic()).into(viewHoder.image);
/**
* 点击详情
*/
viewHoder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (searchListener!=null){
searchListener.onSearch(i);
}
}
});
}
@Override
public int getItemCount() {
return list.size();
}
public class ViewHoder extends RecyclerView.ViewHolder {
private final SimpleDraweeView image;
private final TextView name;
private final TextView price;
public ViewHoder(@NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.item_image);
name = itemView.findViewById(R.id.itme_name);
price = itemView.findViewById(R.id.itme_price);
}
}
/**
* 接口回调
*/
public interface onSearchListener{
void onSearch(int i);
}
onSearchListener searchListener;
public void setSearchListener(onSearchListener searchListener){
this.searchListener=searchListener;
}
}
对应的布局文件
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/item_image"
android:layout_width="120dp"
android:layout_height="120dp"
app:roundedCornerRadius="20dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/itme_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:text="222"/>
<TextView
android:id="@+id/itme_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:textColor="#f55"
android:text="111"/>
</LinearLayout>
</LinearLayout>
然后写抽基类
public abstract class BaseFragment<T extends BasePresenter> extends Fragment {
private T presenter;
private View view;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(getLayout(), container, false);
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
presenter = getPresenter();
presenter.attachView(presenter);
intoview(view);
initdata();
}
protected abstract int getLayout();
protected abstract void intoview(View view);
protected abstract T getPresenter();
protected abstract void initdata();
@Override
public void onDetach() {
super.onDetach();
presenter.deatchView();
}
}
主页代码
public class FragmentOne extends BaseFragment<ShowPresneter> implements ShowView {
@BindView(R.id.myview)
MyView myview;
@BindView(R.id.rec)
RecyclerView rec;
Unbinder unbinder;
private ShowPresneter presneter;
private List<ShowBean.ResultBean> list = new ArrayList<>();
private ShowAdapter adapter;
private String keyword = "手机";
private int page = 1;
private int count = 10;
@Override
protected int getLayout() {
return R.layout.fragmentone;
}
@Override
protected void initdata() {
presneter.onRelated(keyword, page, count);
}
@Override
protected void intoview(View view) {
unbinder = ButterKnife.bind(this, view);
rec.setLayoutManager(new GridLayoutManager(getContext(), 2));
myview.setSearchName(new MyView.onSearchName() {
@Override
public void ongetName(String s) {
Log.e("namess", s);
presneter.onRelated(s, page, count);
//清空一下集合
list.clear();
}
});
}
@Override
protected ShowPresneter getPresenter() {
presneter = new ShowPresneter(this);
return presneter;
}
@Override
public void getShowData(ShowBean showBean) {
Log.e("xxx", showBean.toString());
list.addAll(showBean.getResult()/* 这个result是一个集合类型所以list可以使用addall全部添加 */);
Log.d("size", "getShowData: "+list.size());
//就是这个适配器最好不要这样写 因为你刷新 加载都会走这个回调的。
// 所以不做适配器对象判断的话 它回调一次就会创建一次适配器对象和设置item点击回调
setAdapter();
}
private void setAdapter() {
//就是如果这个适配器对象为空创建 和设置接口回调
if (adapter == null) {
adapter = new ShowAdapter(getActivity(), list);
rec.setAdapter(adapter);
//这个地方应该用适配器点出来的那个回调
adapter.setSearchListener(new ShowAdapter.onSearchListener() {
//这个点击列表item回调的参数不是当前这个item对应的id 它呢只是一个对应列表的下标也就是和集合里面的数据对应的。
@Override
public void onSearch(int id) {
ShowBean.ResultBean resultBean = list.get(id);
//这个只要获取下标就可以获取到当前对象的所有数据
int commodityId = resultBean.getCommodityId();//
Intent intent = new Intent(getContext(), DetailsActivity.class);
intent.putExtra("commodityId", commodityId);
startActivity(intent);
}
});
} else {
//如果有这个对象的话,不创建只需要刷新适配器就行了
adapter.notifyDataSetChanged();
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
对应的布局文件
<com.example.moni2.view.MyView
android:id="@+id/myview"
android:layout_width="match_parent"
android:layout_height="wrap_content"></com.example.moni2.view.MyView>
<android.support.v7.widget.RecyclerView
android:id="@+id/rec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView>
自定义View主页代码
public class MyView extends LinearLayout {
private Button but;
private EditText name;
public MyView(Context context) {
super(context);
}
public MyView(final Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
View view = LayoutInflater.from(context).inflate(R.layout.myview, this, true);
name=view.findViewById(R.id.myview_name);
but=view.findViewById(R.id.myview_but);
but.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String name = MyView.this.name.getText().toString();
if (name.isEmpty()){
Toast.makeText(context,"请输入你要搜索的内容",Toast.LENGTH_SHORT).show();
}else {
searchName.ongetName(name);
}
}
});
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 接口回调
*/
public interface onSearchName{
void ongetName(String s);
}
onSearchName searchName;
public void setSearchName(onSearchName searchName){
this.searchName=searchName;
}
}
对应的布局文件
<EditText
android:id="@+id/myview_name"
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="wrap_content"
android:hint="请输入你要查询的商品"
android:gravity="center"/>
<Button
android:id="@+id/myview_but"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="搜索"/>
点击详情的M,V,P
首先M
public class DetailsModel {
public void getHttpData(int commodityId){
ApiService apiService = RetrofitUtils.getInstance().doGet(Api.DetailsUrl, ApiService.class);
Flowable<DetailsBean> show = apiService.getDetails(commodityId);
show.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSubscriber<DetailsBean>() {
@Override
public void onNext(DetailsBean resultBean) {
if (detailsListener!=null){
detailsListener.onDetails(resultBean);
}
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
/**
* 接口回调
*
*/
public interface onDetailsListener{
void onDetails(DetailsBean detailsBean);
}
onDetailsListener detailsListener;
public void setShoppingListener( onDetailsListener detailsListener){
this.detailsListener=detailsListener;
}
}
然后写v层的接口
public interface DetailsView {
void getDetailsData(DetailsBean data);
}
P层
public class DetailsPresenter extends BasePresenter<DetailsView>{
private DetailsView detailsView;
private DetailsModel detailsModel;
public DetailsPresenter(DetailsView view){
this.detailsView=view;
this.detailsModel=new DetailsModel();
}
public void onRelsted(int commodityId){
detailsModel.getHttpData(commodityId);
detailsModel.setShoppingListener(new DetailsModel.onDetailsListener() {
@Override
public void onDetails(DetailsBean detailsBean) {
detailsView.getDetailsData(detailsBean);
}
});
}
}
详情页面没有适配器
点击之后跳转到Activitt
Activity的抽基类
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity {
private T presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayout());
initView();
presenter=getPresenter();
presenter.attachView(presenter);
initData();
}
protected abstract int getLayout();
protected abstract void initView();
protected abstract T getPresenter();
protected abstract void initData();
@Override
protected void onDestroy() {
super.onDestroy();
presenter.deatchView();
EventBus.getDefault().unregister(this);
}
}
展示详情的Activity
public class DetailsActivity extends BaseActivity<DetailsPresenter> implements DetailsView {
@BindView(R.id.return_btu)
TextView returnBtu;
@BindView(R.id.banner)
com.stx.xhb.xbanner.XBanner banner;
@BindView(R.id.price_details)
TextView priceDetails;
@BindView(R.id.num_details)
TextView numDetails;
@BindView(R.id.details_xp)
TextView detailsXp;
@BindView(R.id.details_zl)
TextView detailsZl;
@BindView(R.id.webview)
WebView webview;
private int commodityId;
private DetailsPresenter detailsPresenter;
@Override
protected int getLayout() {
return R.layout.activity_details;
}
@Override
protected void initView() {
ButterKnife.bind(this);
//这个地方是需要获取传入过来的数据
commodityId = getIntent().getIntExtra("commodityId",0);
returnBtu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
//现在写的是传入数据
//getIntent().putExtra("commodityId", this.commodityId);
}
@Override
protected DetailsPresenter getPresenter() {
detailsPresenter = new DetailsPresenter(this);
detailsPresenter.onRelsted(commodityId);
return detailsPresenter;
}
@Override
protected void initData() {
}
@Override
public void getDetailsData(DetailsBean data) {
DetailsBean resultBean = data;
final List<String> list = new ArrayList<>();
String picture = resultBean.getResult().getPicture();
String[] split = picture.split(",");
for (int i = 0; i < split.length; i++) {
//不是从第一个图片取吗?
list.add(split[i]);
}
banner.setData(list, null);
banner.loadImage(new XBanner.XBannerAdapter() {
@Override
public void loadBanner(XBanner banner, Object model, View view, int position) {
Glide.with(DetailsActivity.this).load(list.get(position)).into((ImageView) view);
}
});
/**
* 其它赋值
*/
priceDetails.setText("¥" + resultBean.getResult().getPrice());
numDetails.setText("已售" + resultBean.getResult().getStock() + "件");
detailsXp.setText(resultBean.getResult().getCommodityName());
detailsZl.setText("重量" + resultBean.getResult().getCommentNum());
WebSettings settings = webview.getSettings();
//webwiew可以执行 脚本
settings.setJavaScriptEnabled(true);
//支持缩放
settings.setBuiltInZoomControls(true);
String s2 = "<script type=\"text/javascript\">" +
"var imgs=document.getElementsByTagName('img');" +
"for(var i = 0; i<imgs.length; i++){" +
"imgs[i].style.width='100%';" +
"imgs[i].style.height='auto';" +
"}" +
"</script>";
String details = resultBean.getResult().getDetails();
webview.loadDataWithBaseURL(null, details + s2 + "<html><body>", "text/html", "utf-8", null);
}
}
对应的布局文件
<LinearLayout
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:orientation="horizontal"
android:background="#99FFFFFF"
android:layout_alignParentLeft="true">
<TextView
android:id="@+id/return_btu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="<"
android:textSize="30sp" />
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="商品"
android:textColor="#000"
android:textSize="16sp" />
<TextView
android:id="@+id/titlel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:gravity="center"
android:text="详情"
android:textColor="#000"
android:textSize="16sp" />
<TextView
android:id="@+id/titler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="评价"
android:textColor="#000"
android:textSize="16sp" />
</LinearLayout>
<ScrollView
android:layout_below="@id/button"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.stx.xhb.xbanner.XBanner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
/>
<RelativeLayout
android:background="#fff"
android:id="@+id/l"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/banner"
android:orientation="horizontal">
<TextView
android:id="@+id/price_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:text="159"
android:textColor="#f00"
android:textSize="30sp" />
<TextView
android:id="@+id/num_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:text="已售"
android:textSize="25sp" />
</RelativeLayout>
<TextView
android:id="@+id/details_xp"
android:layout_below="@id/l"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="详情"/>
<TextView
android:id="@+id/details_zl"
android:layout_below="@id/details_xp"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="重量"/>
<TextView
android:id="@+id/spxq"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/details_zl"
android:layout_margin="10dp"
android:text="商品详情"
android:textSize="25sp" />
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/spxq"
android:layout_marginRight="24dp"
android:layout_marginLeft="24dp"></WebView>
</RelativeLayout>
</ScrollView>