电商项目
首先说一下需要导入的依赖
注意 : 我这里使用的是androidx
分别是Gson依赖,tablayout依赖,volley依赖,recycleView依赖和glide依赖
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation("com.github.bumptech.glide:glide:4.10.0") {
exclude group: "com.android.support"
}
接下来就是基类的抽取
IBaseView类只是一个接口
这是BaseIPresenter也就是Presenter的基类抽取
public abstract class BaseIPresenter<view> {
protected view iBaseView;
public BaseIPresenter() {
initModel();
}
//初始化model
protected abstract void initModel();
//绑定视图
public void attachView(view iBaseView) {
this.iBaseView = iBaseView;
}
//解绑视图
public void detachView() {
if (iBaseView != null) {
iBaseView = null;
}
}
}
这是BaseActivity也就是Activity的基类抽取(这里面我们不需要用这个来表示数据)
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layoutID());
initView();
initData();
}
protected abstract void initData();
protected abstract void initView();
protected abstract int layoutID();
}
这是BaseFragment也就是Fragment的基类抽取(我们从这里来展示获得到的数据)
public abstract class BaseFragment<p extends BaseIPresenter> extends Fragment {
protected p presenter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(layoutID(), container, false);
presenter = initPresenter();
if (presenter != null) {
presenter.attachView(this);
}
initView(view);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initData();
}
protected abstract p initPresenter();
protected abstract int layoutID();
protected abstract void initView(View view);
protected abstract void initData();
@Override
public void onDestroy() {
super.onDestroy();
if (presenter != null) {
presenter.detachView();
}
}
}
现在开始mvp的封装
首先是契约类
public class IModelImpl implements IConenter.IModel {
private static final String TAG = "IModelImpl";
@Override
public void onGetJson(String path, final ModelCallBack modelCallBack) {
VolleyUtils.getInstance().doGet(path, new VolleyUtils.VolleyCallBack() {
@Override
public void onGetDataSuccess(String path) {
CommodityEntity commodityEntity = new Gson().fromJson(path, CommodityEntity.class);
if (modelCallBack != null) {
Log.i(TAG, "onGetDataSuccess: "+commodityEntity.getMessage());
modelCallBack.onSuccess(commodityEntity);
}
}
@Override
public void onGetDataError(Throwable throwable) {
if (throwable != null) {
modelCallBack.onError(throwable);
}
}
});
}
}
接着是mvp中的presenter层
public class IPresenterImpl extends BaseIPresenter<IConenter.IView>
implements IConenter.IPresenter {
private IModelImpl iModel;
@Override
protected void initModel() {
iModel = new IModelImpl();
}
@Override
public void onGetJson(String path) {
iModel.onGetJson(path, new IConenter.IModel.ModelCallBack() {
@Override
public void onSuccess(CommodityEntity path) {
iBaseView.onSuccess(path);
}
@Override
public void onError(Throwable throwable) {
iBaseView.onError(throwable);
}
});
}
}
从这里开始写工具类volleyUtils
public class VolleyUtils {
private static VolleyUtils instance;
private final RequestQueue requestQueue;
private VolleyUtils() {
requestQueue = Volley.newRequestQueue(App.getContext());
}
public static VolleyUtils getInstance() {
//双重校验锁
if (instance == null) {
synchronized (VolleyUtils.class) {
instance = new VolleyUtils();
}
}
return instance;
}
//doget请求
public void doGet(String path, final VolleyCallBack volleyCallBack) {
StringRequest stringRequest = new StringRequest(path, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//注意判空
if (response != null) {
volleyCallBack.onGetDataSuccess(response);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//判空
if (error != null) {
volleyCallBack.onGetDataError(error);
}
}
});
requestQueue.add(stringRequest);
}
//dopost请求
public void doPost(String path, final Map<String, String> map, final VolleyCallBack volleyCallBack) {
StringRequest stringRequest = new StringRequest(StringRequest.Method.POST, path, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response != null) {
volleyCallBack.onGetDataSuccess(response);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error != null) {
volleyCallBack.onGetDataError(error);
}
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return map;
}
};
requestQueue.add(stringRequest);
}
//接口
public interface VolleyCallBack {
void onGetDataSuccess(String path);
void onGetDataError(Throwable throwable);
}
}
继续写view自定义布局
public class FlowLayout extends ViewGroup {
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean bn, int l, int t, int r, int b) {
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
int count = getChildCount();
if (count > 0) {
for (int i = 0; i < count; i++) {
View view = getChildAt(i);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
TextView textView = (TextView) view;
flowLayoutClick.layoutClick(textView.getText().toString());
}
});
//从这里转折
view.measure(0, 0);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
int widthPixels = getResources().getDisplayMetrics().widthPixels;
right = left + width;
if (right > widthPixels) {
left = 0;
top = bottom + 30;
right = left + width;
}
bottom = top + 30;
view.layout(left, top, right, bottom);
left = left + width + height;
}
}
}
public void AddChiledView(String str) {
TextView textView = new TextView(getContext());
textView.setText(str);
textView.setTextColor(Color.BLACK);
textView.setPadding(20, 0, 20, 0);
textView.setBackgroundResource(R.drawable.flitemlayout);
Addanimator(textView);
addView(textView);
}
private void Addanimator(View textView){
ViewPropertyAnimator animate = textView.animate();
animate.rotationX(0).rotationY(1800);
animate.setDuration(5000);
animate.start();
}
public interface FlowLayoutClick {
void layoutClick(String s);
}
public FlowLayoutClick flowLayoutClick;
public void setFlowLayoutClick(FlowLayoutClick flowLayoutClick) {
this.flowLayoutClick = flowLayoutClick;
}
}
flitemlayout的布局在res下的drawable中写
扫描二维码关注公众号,回复:
8535364 查看本文章
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="20dp" />
<size
android:width="20dp"
android:height="40dp" />
<solid android:color="@color/colortextColor" />
</shape>
这是mvp中负责展示的view层,(我们从这里开始展示数据)
首先是MainActivity,因为我们不使用这个view来进行数据展示,所以简单些只要一些viewpager和tablayout就行
public class MainActivity extends BaseActivity {
private ViewPager pager;
private TabLayout tab;
private ArrayList<String> strings;
private ArrayList<Fragment> fragments;
private HomeFragment homeFragment;
private OtherFragment otherFragment;
//本页面只提供activity加fragment的效果
@Override
protected void initData() {
}
@Override
protected void initView() {
//查询资源id
pager = (ViewPager) findViewById(R.id.viewpager);
tab = (TabLayout) findViewById(R.id.tablayout);
strings = new ArrayList<>();
fragments = new ArrayList<>();
homeFragment = new HomeFragment();
otherFragment = new OtherFragment();
strings.add("首页");
strings.add("我的");
fragments.add(homeFragment);
fragments.add(otherFragment);
pager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return strings.get(position);
}
});
tab.setupWithViewPager(pager);
}
@Override
protected int layoutID() {
return R.layout.activity_main;
}
}
我们在这里来进行数据的展示,简单点都好
public class HomeFragment extends BaseFragment<IPresenterImpl> implements IConenter.IView {
private static final String TAG = "HomeFragment";
private RecyclerView recyclerView;
private FlowLayout flow;
private EditText ed;
private Button bt;
@Override
protected IPresenterImpl initPresenter() {
return new IPresenterImpl();
}
@Override
protected int layoutID() {
return R.layout.fragment_home;
}
@Override
protected void initView(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.recylerView);
flow = (FlowLayout) view.findViewById(R.id.flow);
ed = (EditText) view.findViewById(R.id.info_edit);
bt = (Button) view.findViewById(R.id.info_bt);
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
staggeredGridLayoutManager.setOrientation(StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
}
@Override
protected void initData() {
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String sid = ed.getText().toString();
if (sid.isEmpty()) {
Toast.makeText(getActivity(), "不能为空", Toast.LENGTH_SHORT).show();
} else {
String encode = URLEncoder.encode(sid);
String path = "http://172.17.8.100/small/commodity/v1/findCommodityByKeyword?keyword=" + encode + "&page=1&count=4";
presenter.onGetJson(path);
flow.AddChiledView(sid);
}
}
});
}
@Override
public void onSuccess(CommodityEntity path) {
/* for (CommodityEntity.ResultBean bean : path.getResult()) {
String commodityName = bean.getCommodityName();
flow.AddChiledView(commodityName);
}*/
Log.i(TAG, "onSuccess: " + path.getResult());
List<CommodityEntity.ResultBean> result = path.getResult();
recyclerView.setAdapter(new MyRecyclearViewAdapter(getActivity(), result));
flow.setFlowLayoutClick(new FlowLayout.FlowLayoutClick() {
@Override
public void layoutClick(String s) {
}
});
}
@Override
public void onError(Throwable throwable) {
}
}
因为是使用的recycleView所以还有adapter
public class MyRecyclearViewAdapter extends RecyclerView.Adapter<MyRecyclearViewAdapter.ViewHolder> {
private Context context;
private List<CommodityEntity.ResultBean> result;
public MyRecyclearViewAdapter(Context context, List<CommodityEntity.ResultBean> result) {
this.context = context;
this.result = result;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
CommodityEntity.ResultBean resultBean = result.get(position);
//获得的是名字
String name = resultBean.getCommodityName();
//获得的是照片地址
String masterPic = resultBean.getMasterPic();
holder.text.setText(name);
Glide.with(context).load(masterPic).into(holder.image);
}
@Override
public int getItemCount() {
return result.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
TextView text;
public ViewHolder(@NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.item_image);
text = itemView.findViewById(R.id.item_text);
}
}
}
对了权限记得加一个联网权限
还有记得要在AndroidManifest.xml中将app注释否则呵呵