首先导入依赖
//黄油刀依赖
implementation 'com.jakewharton:butterknife:8.6.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
//Fresco加载图片依赖
implementation 'com.facebook.fresco:fresco:1.12.1'
// 支持 GIF 动图,需要就添加
implementation 'com.facebook.fresco:animated-gif:1.12.1'
//EventBus依赖
implementation 'org.greenrobot:eventbus:3.1.1'
//Retrofit网络加载框架依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
//XRecycleView依赖
implementation 'com.jcodecraeer:xrecyclerview:1.2.6'
//V4库依赖(不报错不加)
implementation 'com.android.support:support-v4:28.0.0'
//CardView依赖,卡片式布局
implementation 'com.android.support:cardview-v7:28.0.0'
//EventBus依赖
implementation 'org.greenrobot:eventbus:3.1.1'
//RecyclerView依赖
implementation 'com.android.support:recyclerview-v7:28.0.0'
然后配置API
public class ApiService {
//请求头
public static final String BASE_URL="http://172.17.8.100/";
//搜索
public static final String SEEK_URL="small/commodity/v1/findCommodityByKeyword?page=1&count=10";
请求方式以及参数
public interface UserApiService {
//搜索
@GET
Observable<SeekBean> getSeek(@Url String url, @Query("keyword")String keyword);
}
MVP请求数据
M层
public interface SeekModel {
//请求参数
void getSeekData(String url,String keyword,ModelCallBack callBack);
interface ModelCallBack{
void onSuccess(Object obj);
void onFail(Throwable e);
}
}
public class Model implements IModel {
@Override
public void getSeekData(String url, String keyword, final ModelCallBack callBack) {
UserApiService userApiService = RetrofitUtils.getInstance().create(UserApiService.class);
userApiService.getSeek(url,keyword)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<SeekBean>() {
//成功回调
@Override
public void onNext(SeekBean value) {
callBack.onSuccess(value);
}
//失败回调
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
P层
public interface IHomeLitsPresenter {
//创建获取Model的数据的方法
void getModel(String keyword);
}
//继承Presenter的接口,继承Model类的内部接口
public class Presenter<T> implements IPresenter {
HomeFragment homeFragment;
private final Model model;
private Reference reference;
public Presenter(HomeFragment homeFragment) {
this.homeFragment = homeFragment;
model = new Model();
}
public void attach(T t){
reference = new WeakReference<>(t);
}
public void detach(){
if (reference.get()!= null) {
reference.clear();
reference=null;
}
}
@Override
public void getModel(String keyword) {
model.getSeekData(ApiService.SEEK_URL, keyword, new IModel.ModelCallBack() {
@Override
public void onSuccess(Object object) {
SeekBean seekBean = (SeekBean) object;
homeFragment.getPreData(seekBean);
}
@Override
public void onShiBai() {
}
});
}
}
V层
public interface IView {
void getPreData(SeekBean seekBean);
}
Fragment内容
public class HomeFragment extends Fragment implements IView {
@BindView(R.id.myedit)
CustomSearchView myedit;
@BindView(R.id.myrecy)
RecyclerView myrecy;
Unbinder unbinder;
private Presenter presenter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.frag_home, container, false);
unbinder = ButterKnife.bind(this, inflate);
//自定义搜索框的接口回调
myedit.setOnEditSearchClickListener(new CustomSearchView.setOnBtnSearchClickListener() {
@Override
public void setOnBtnSearchClick(String searchdata) {
presenter.getModel(searchdata);
}
});
//布局管理器
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
myrecy.setLayoutManager(gridLayoutManager);
return inflate;
}
//简单的Fragment懒加载
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
if (isVisibleToUser) {
presenter = new Presenter(this);
presenter.getModel("板鞋");
presenter.attach(this);
}else {
}
}
@Override
public void getPreData(SeekBean seekBean) {
List<SeekBean.ResultBean> list = seekBean.getResult();
//创建适配器并将集合传入适配器
SeekAdapter seekAdapter = new SeekAdapter(getActivity(), list);
//设置适配器
myrecy.setAdapter(seekAdapter);
}
//解绑MVP以及黄油刀
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
presenter.detach();
}
}
适配器以及RecycleView点击事件接口回调
public class SeekAdapter extends RecyclerView.Adapter<SeekAdapter.MyHodel> {
private final List<SeekBean.ResultBean> list;
private final Context context;
public SeekAdapter(Context context, List<SeekBean.ResultBean> list) {
this.list = list;
this.context = context;
}
@Override
public MyHodel onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.seekitem, null);
MyHodel myHodel = new MyHodel(view);
return myHodel;
}
@Override
public void onBindViewHolder(MyHodel holder, final int position) {
//获取名称
holder.textView1.setText(list.get(position).getCommodityName());
//获取价格
holder.textView2.setText("¥"+list.get(position).getPrice()+"");
//Fresco获取图片
holder.imageview.setImageURI(list.get(position).getMasterPic());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//EventBus传值
EventBus.getDefault().postSticky(list.get(position).getCommodityId()+"");
context.startActivity(new Intent(context,DetailsActivity.class));
}
});
}
@Override
public int getItemCount() {
return list.size();
}
public class MyHodel extends RecyclerView.ViewHolder {
private final SimpleDraweeView imageview;
private final TextView textView1;
private final TextView textView2;
public MyHodel(View itemView) {
super(itemView);
imageview = itemView.findViewById(R.id.imageview);
textView1 = itemView.findViewById(R.id.textview1);
textView2 = itemView.findViewById(R.id.textview2);
}
}
}
点击进入详情界面使用EventBus传值
public class DetailsActivity extends AppCompatActivity implements IView {
@BindView(R.id.detailsfly)
FlyBanner detailsfly;
@BindView(R.id.qian)
TextView qian;
@BindView(R.id.sold)
TextView sold;
@BindView(R.id.particulars)
TextView particulars;
@BindView(R.id.myshang)
TextView myshang;
@BindView(R.id.webview)
WebView webview;
private Presenter presenter;
private ArrayList<String> imageurl = new ArrayList<>();
private String id1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
ButterKnife.bind(this);
ButterKnife.bind(this);
EventBus.getDefault().register(this);
presenter = new Presenter(this);
presenter.getModelDetails(id1);
presenter.attach(this);
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void getEventBus(String s) {
//首页传入详情的ID
id1 = s;
presenter.getModelDetails(s);
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
}
@Override
public void getPreData(DetailsBean detailsBean) {
String picture = detailsBean.getResult().getPicture();
String[] split = picture.split("\\,");
for (String a : split) {
imageurl.add(a);
}
detailsfly.setImagesUrl(imageurl);
//获取价格
int price = detailsBean.getResult().getPrice();
qian.setText("¥" + price);
//获取已售数量
int stock = detailsBean.getResult().getStock();
sold.setText("已售" + stock + "件");
//获取商品介绍
String commodityName = detailsBean.getResult().getCommodityName();
particulars.setText(commodityName);
//获取WebView网页
String details = detailsBean.getResult().getDetails();
webview.loadDataWithBaseURL(null, details, "text/html", "UTF-8", null);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
presenter.detach();
}
}
在App内配置Fresco
public class app extends Application {
@Override
public void onCreate() {
super.onCreate();
//设置磁盘缓存
DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder(this)
.setBaseDirectoryName("images_ytw")
.setBaseDirectoryPath(Environment.getExternalStorageDirectory())
.build();
//设置磁盘缓存的配置,生成配置文件
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
.setMainDiskCacheConfig(diskCacheConfig)
.build();
Fresco.initialize(this,config);
}
}
解决文字溢出的问题的布局
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:maxLines="1"//单行显示
android:maxEms="9"//最多显示9个字符
android:ellipsize="end"//跑马灯效果
/>
沉浸式
<style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">true</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
setAndroidNativeLightStatusBar(MainActivity.this, true);、
// 状态栏文字颜色的修改 false为白色 true为黑色
private static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {
View decor = activity.getWindow().getDecorView();
if (dark) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}