Procházet zdrojové kódy

网络调试成功

詹子聪 před 5 roky
rodič
revize
ddd9c8a148

+ 2 - 5
app/build.gradle

@@ -36,19 +36,16 @@ android {
         dev {
             // 开发环境宿舍服务器
             buildConfigField("String", "BASE_URL", '"http://192.168.0.190:8080/"')
-            buildConfigField("String", "HOST_STATIC_RESOURCE_IMAGE", '"http://192.168.0.190/"')
         }
 
         rel {
             // 正式上线
-            buildConfigField("String", "BASE_URL", '"http://app.icsmabc.cyou:8856/"')
-            buildConfigField("String", "HOST_STATIC_RESOURCE_IMAGE", '"http://icsmabc.cyou/eden/images/"')
+            buildConfigField("String", "BASE_URL", '"http://app.jianjie.life:11111/"')
         }
 
         company {
             // 开发2
-            buildConfigField("String", "BASE_URL", '"http://10.16.0.153:8080/"')
-            buildConfigField("String", "HOST_STATIC_RESOURCE_IMAGE", '"http://10.16.0.153/"')
+            buildConfigField("String", "BASE_URL", '"http://10.16.0.184:8080/"')
         }
     }
 }

+ 15 - 0
app/src/main/java/com/miekir/ym/constant/FragmentType.java

@@ -0,0 +1,15 @@
+package com.miekir.ym.constant;
+
+/**
+ * Copyright (C), 2019-2020, Miekir
+ *
+ * @author Miekir
+ * @date 2020/11/24 22:49
+ * Description:
+ */
+public interface FragmentType {
+    /**
+     * 数码产品
+     */
+    int DIGITAL = 0;
+}

+ 10 - 0
app/src/main/java/com/miekir/ym/listener/OnBottomListener.java

@@ -0,0 +1,10 @@
+package com.miekir.ym.listener;
+
+/**
+ * @author Jack Tony
+ * @brief
+ * @date 2015/4/6
+ */
+public interface OnBottomListener {
+    public void onBottom();
+}

+ 117 - 0
app/src/main/java/com/miekir/ym/listener/OnRcvScrollListener.java

@@ -0,0 +1,117 @@
+package com.miekir.ym.listener;
+
+
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+
+/**
+ * @author Jack Tony
+ * @brief recyle view 滚动监听器
+ * @date 2015/4/6
+ */
+public class OnRcvScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener {
+    private String TAG = getClass().getSimpleName();
+
+    public static enum LAYOUT_MANAGER_TYPE {
+        LINEAR,
+        GRID,
+        STAGGERED_GRID
+    }
+
+    /**
+     * layoutManager的类型(枚举)
+     */
+    protected LAYOUT_MANAGER_TYPE layoutManagerType;
+
+    /**
+     * 最后一个的位置
+     */
+    private int[] lastPositions;
+
+    /**
+     * 最后一个可见的item的位置
+     */
+    private int lastVisibleItemPosition;
+/*    *//**
+     * 是否正在加载
+     *//*
+    private boolean isLoadingMore = false;*/
+
+    /**
+     * 当前滑动的状态
+     */
+    private int currentScrollState = 0;
+
+    @Override
+    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+        super.onScrolled(recyclerView, dx, dy);
+
+        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+        //  int lastVisibleItemPosition = -1;
+        if (layoutManagerType == null) {
+            if (layoutManager instanceof LinearLayoutManager) {
+                layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR;
+            } else if (layoutManager instanceof GridLayoutManager) {
+                layoutManagerType = LAYOUT_MANAGER_TYPE.GRID;
+            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
+                layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID;
+            } else {
+                throw new RuntimeException(
+                        "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");
+            }
+        }
+
+        switch (layoutManagerType) {
+            case LINEAR:
+                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager)
+                        .findLastCompletelyVisibleItemPosition();
+                break;
+            case GRID:
+                lastVisibleItemPosition = ((GridLayoutManager) layoutManager)
+                        .findLastVisibleItemPosition();
+                break;
+            case STAGGERED_GRID:
+                StaggeredGridLayoutManager staggeredGridLayoutManager
+                        = (StaggeredGridLayoutManager) layoutManager;
+                if (lastPositions == null) {
+                    lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];
+                }
+                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
+                lastVisibleItemPosition = findMax(lastPositions);
+                break;
+        }
+
+    }
+
+    @Override
+    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+        super.onScrollStateChanged(recyclerView, newState);
+        currentScrollState = newState;
+        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+        int visibleItemCount = layoutManager.getChildCount();
+        int totalItemCount = layoutManager.getItemCount();
+        if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE &&
+                (lastVisibleItemPosition) >= totalItemCount - 1)) {
+            //Log.d(TAG, "is loading more");
+            onBottom();
+        }
+    }
+
+
+    @Override
+    public void onBottom() {
+        //Log.d(TAG, "is onBottom");
+    }
+
+    private int findMax(int[] lastPositions) {
+        int max = lastPositions[0];
+        for (int value : lastPositions) {
+            if (value > max) {
+                max = value;
+            }
+        }
+        return max;
+    }
+}

+ 6 - 4
app/src/main/java/com/miekir/ym/ui/MainActivity.kt

@@ -6,9 +6,11 @@ import com.flyco.tablayout.listener.OnTabSelectListener
 import com.miekir.common.adapter.TabFragmentAdapter
 import com.miekir.ym.R
 import com.miekir.ym.base.YangActivity
+import com.miekir.ym.constant.FragmentType
 import com.miekir.ym.listener.AppbarTranslateListener
 import com.miekir.ym.listener.ITopActionListener
 import com.miekir.ym.ui.about.AboutFragment
+import com.miekir.ym.ui.coupon.CouponFragment
 import kotlinx.android.synthetic.main.activity_main.*
 import java.util.*
 
@@ -20,10 +22,10 @@ class MainActivity : YangActivity() {
     override fun initViews(savedInstanceState: Bundle?) {
         val titles = arrayOf("数码", "美食", "工具", "关于")
         val fragments: ArrayList<Fragment> = ArrayList()
-        fragments.add(AboutFragment())
-        fragments.add(AboutFragment())
-        fragments.add(AboutFragment())
-        fragments.add(AboutFragment())
+        fragments.add(CouponFragment(FragmentType.DIGITAL))
+        fragments.add(CouponFragment(FragmentType.DIGITAL))
+        fragments.add(CouponFragment(FragmentType.DIGITAL))
+        fragments.add(CouponFragment(FragmentType.DIGITAL))
 
         val adapter = TabFragmentAdapter(supportFragmentManager, fragments)
         vp_main.adapter = adapter

+ 219 - 0
app/src/main/java/com/miekir/ym/ui/coupon/CouponFragment.java

@@ -0,0 +1,219 @@
+package com.miekir.ym.ui.coupon;
+
+import android.content.DialogInterface;
+import android.content.Intent;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+
+import com.miekir.common.utils.ToastTool;
+import com.miekir.mvp.presenter.InjectPresenter;
+import com.miekir.mvp.view.BaseMvpFragment;
+import com.miekir.ym.R;
+import com.miekir.ym.constant.FragmentType;
+import com.miekir.ym.listener.ITopActionListener;
+import com.miekir.ym.listener.OnRcvScrollListener;
+import com.miekir.ym.widget.NormalDividerItemDecoration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 模板Fragment
+ */
+public class CouponFragment extends BaseMvpFragment implements ICouponView<CouponBean>, ITopActionListener {
+    private static final int PAGE_START = 0;
+    private static final int PAGE_SIZE = 20;
+
+    private int mTemplateType = FragmentType.DIGITAL;
+
+    @InjectPresenter
+    CouponPresenter mPresenter;
+
+    private SwipeRefreshLayout srl_template;
+    private List<CouponBean> mCouponBeanList = new ArrayList<>();
+    private CouponAdapter mAdapter;
+    private RecyclerView rv_template;
+
+    /**当前页*/
+    private int mCurrentPage = PAGE_START;
+    /**是否下拉获取数据*/
+    private boolean mIsRefresh = true;
+
+    public CouponFragment(int templateType) {
+        mTemplateType = templateType;
+    }
+
+    @Override
+    public int getLayoutId() {
+        return R.layout.fragment_coupon;
+    }
+
+    @Override
+    protected void onViewInit() {
+        rv_template = rootView.findViewById(R.id.rv_template);
+        // 必须要设置LayoutManager,否则RecyclerView不知道要使用什么布局,从而在界面上不显示
+        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
+        rv_template.setLayoutManager(layoutManager);
+
+        int dividerWidth = (int) getResources().getDimension(R.dimen.margin_s);
+        NormalDividerItemDecoration decoration = new NormalDividerItemDecoration(dividerWidth);
+        rv_template.addItemDecoration(decoration);
+        mAdapter = new CouponAdapter(getActivity(), mCouponBeanList);
+        mAdapter.setCouponLongClickListener(this::showAdminDialog);
+        rv_template.setAdapter(mAdapter);
+        // 必须先绑定RecyclerView
+        mAdapter.setEmptyView(R.layout.view_empty, rv_template);
+
+        // 不要滑动一段距离
+        rv_template.smoothScrollToPosition(0);
+        srl_template = rootView.findViewById(R.id.srl_template);
+        srl_template.setColorSchemeResources(R.color.black_theme, R.color.blue_droid, R.color.yellow_droid, R.color.red_droid);
+
+        // 下拉刷新
+        srl_template.setOnRefreshListener(() -> {
+            mIsRefresh = true;
+            mCurrentPage = PAGE_START;
+            mPresenter.getTemplateData(mCurrentPage, PAGE_SIZE);
+        });
+
+        // 加载更多
+        rv_template.addOnScrollListener(new OnRcvScrollListener(){
+            @Override
+            public void onBottom() {
+                super.onBottom();
+                // 如果到底部了,而且不是正在加载状态,就变为正在加载状态,并及时去加载数据
+                if (!srl_template.isRefreshing()) {
+                    mIsRefresh = false;
+                    srl_template.setRefreshing(true);
+                    mPresenter.getTemplateData(mCurrentPage, PAGE_SIZE);
+                }
+            }
+        });
+    }
+
+    @Override
+    protected void onLazyLoad() {
+        // 获取数据
+        srl_template.setRefreshing(true);
+        mPresenter.getTemplateData(mCurrentPage, PAGE_SIZE);
+    }
+
+    /**
+     * 修改商品或者删除商品
+     */
+    private void showAdminDialog(int position) {
+        CouponBean couponBean = mCouponBeanList.get(position);
+        if (couponBean.isLocal) {
+            // 本地写死的不能删除
+            return;
+        }
+        AlertDialog alertDialog = new AlertDialog.Builder(getActivity())
+                .setMessage("选择操作")
+                .setPositiveButton("修改", (dialog, which) -> {
+                    dialog.dismiss();
+//                    Intent modifyIntent = new Intent(getActivity(), AddCouponActivity.class);
+//                    modifyIntent.putExtra(AddCouponActivity.KEY_MODIFY_COUPON, couponBean);
+//                    RxActivityResult.on(getActivity())
+//                            .startIntent(modifyIntent)
+//                            .filter(result -> result.resultCode() == RESULT_OK)
+//                            .doOnNext(result -> {
+//                                // 修改商品成功之后刷新item
+//                                CouponBean modifiedBean = (CouponBean) result.data().getSerializableExtra(AddCouponActivity.KEY_MODIFY_COUPON);
+//                                if (modifiedBean == null) {
+//                                    return;
+//                                }
+//                                couponBean.updateData(modifiedBean);
+//                                mAdapter.notifyItemChanged(position);
+//                            })
+//                            .subscribe();
+                })
+                .setNeutralButton("取消", (dialog, which) -> {
+                    dialog.dismiss();
+                })
+                .setNegativeButton("删除", (DialogInterface dialog, int which) -> {
+                    dialog.dismiss();
+                    showDeleteDialog(position);
+                }).create();
+        alertDialog.setCanceledOnTouchOutside(false);
+        alertDialog.setCancelable(false);
+        alertDialog.show();
+    }
+
+    /**
+     * 是否删除商品
+     */
+    private void showDeleteDialog(int position) {
+        CouponBean couponBean = mCouponBeanList.get(position);
+        AlertDialog alertDialog = new AlertDialog.Builder(getActivity())
+                .setMessage("确定删除优惠券:" + couponBean.couponName)
+                .setNegativeButton("取消", (dialog, which) -> dialog.dismiss())
+                .setPositiveButton("确定", (DialogInterface dialog, int which) -> {
+                    dialog.dismiss();
+                    // 删除商品
+                    mPresenter.deleteCouponById(position, couponBean.id);
+                }).create();
+        alertDialog.show();
+    }
+
+    @Override
+    public void onCouponDataCome(boolean success, String message, List<CouponBean> couponBeanList) {
+        srl_template.setRefreshing(false);
+        if (!success) {
+            ToastTool.showShort(message);
+            return;
+        }
+
+        if (mCurrentPage == PAGE_START) {
+            mCouponBeanList.clear();
+            if (couponBeanList != null) {
+                mCouponBeanList.addAll(couponBeanList);
+            }
+
+            mAdapter.notifyDataSetChanged();
+            // 如果是下拉刷新获取的第0页数据,item不要自动滚动一段距离
+            // 或者用这个mLayoutManager.scrollToPositionWithOffset(0, 0);
+            if (mIsRefresh) {
+                ToastTool.showShort("刷新成功");
+                rv_template.smoothScrollToPosition(0);
+            }
+        } else {
+            if (couponBeanList != null) {
+                mCouponBeanList.addAll(couponBeanList);
+            }
+
+            mAdapter.notifyDataSetChanged();
+        }
+
+        // 请求到数据了,页数自增
+        if (couponBeanList != null && couponBeanList.size() > 0) {
+            mCurrentPage++;
+        } else {
+            ToastTool.showShort("没有更多数据了");
+        }
+    }
+
+    /**
+     * 删除商品结果
+     * @param success
+     * @param message
+     * @param position
+     */
+    @Override
+    public void onDeleteCoupon(boolean success, String message, int position) {
+        if (success) {
+            mAdapter.notifyItemRemoved(position);
+            ToastTool.showShort("删除成功");
+        } else {
+            ToastTool.showShort(message);
+        }
+    }
+
+    @Override
+    public void onTopAction() {
+        rv_template.smoothScrollToPosition(0);
+    }
+}

+ 0 - 4
app/src/main/java/com/miekir/ym/ui/coupon/CouponPresenter.java

@@ -4,16 +4,12 @@ import android.text.TextUtils;
 
 import com.miekir.mvp.presenter.BasePresenter;
 import com.miekir.network.RetrofitHelper;
-import com.miekir.network.base.BaseResponse;
-import com.miekir.network.widget.observe.MvpObserver;
 import com.miekir.network.widget.observe.NetMvpObserver;
 import com.miekir.ym.base.ApiService;
 
 import java.util.List;
 
 import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.observers.DisposableObserver;
 import io.reactivex.schedulers.Schedulers;
 
 /**

+ 54 - 0
app/src/main/java/com/miekir/ym/widget/NormalDividerItemDecoration.java

@@ -0,0 +1,54 @@
+package com.miekir.ym.widget;
+
+import android.graphics.Rect;
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * 均等分割线,对于CardView,默认有8dp的margin_bottom,可根据需要进行加减
+ */
+public class NormalDividerItemDecoration extends RecyclerView.ItemDecoration {
+    private int mSpace;
+
+    public NormalDividerItemDecoration(int space) {
+        this.mSpace = space;
+    }
+
+    @Override
+    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
+        super.getItemOffsets(outRect, view, parent, state);
+        /*if (parent.getPaddingLeft() != halfSpace) {
+            parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace);
+            parent.setClipToPadding(false);
+        }*/
+
+        /*outRect.left = halfSpace;
+        outRect.right = halfSpace;
+        outRect.top = halfSpace;
+        if (parent.getChildAdapterPosition(view) == parent.getAdapter().getItemCount() - 1) {
+            outRect.bottom = halfSpace;
+        } else {
+            outRect.bottom = 0;
+        }*/
+
+        /*parent.setClipToPadding(false);
+        if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
+            parent.setPadding(halfSpace, halfSpace, halfSpace, 0);
+        } else {
+            parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace);
+        }*/
+
+        // Rect outRect表示 item 的上下左右所留下的边距。其中 outRect 的 left,top,right,bottom 即为 item 四周留下的边距的距离,默认都为 0 ;
+        // 让分割线一致
+        parent.setClipToPadding(false);
+        outRect.left = mSpace;
+        outRect.top = mSpace;
+        outRect.right = mSpace;
+        if (parent.getChildAdapterPosition(view) == parent.getAdapter().getItemCount() - 1) {
+            outRect.bottom = mSpace;
+        } else {
+            outRect.bottom = 0;
+        }
+    }
+}

+ 16 - 0
app/src/main/res/layout/view_empty.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--搜索栏-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/iv_empty"
+        android:layout_width="@dimen/size_image_big"
+        android:layout_height="@dimen/size_image_big"
+        android:layout_marginTop="@dimen/size_image_normal"
+        android:layout_gravity="center_horizontal"
+        android:scaleType="fitXY"
+        android:src="@mipmap/logo_gray"
+        android:tint="@color/gray_text_hint"/>
+</FrameLayout>

+ 2 - 5
network/build.gradle

@@ -32,19 +32,16 @@ android {
         dev {
             // 开发环境宿舍服务器
             buildConfigField("String", "BASE_URL", '"http://192.168.0.190:8080/"')
-            buildConfigField("String", "HOST_STATIC_RESOURCE_IMAGE", '"http://192.168.0.190/"')
         }
 
         rel {
             // 正式上线
-            buildConfigField("String", "BASE_URL", '"http://app.icsmabc.cyou:8856/"')
-            buildConfigField("String", "HOST_STATIC_RESOURCE_IMAGE", '"http://icsmabc.cyou/eden/images/"')
+            buildConfigField("String", "BASE_URL", '"http://app.jianjie.life:11111/"')
         }
 
         company {
             // 开发2
-            buildConfigField("String", "BASE_URL", '"http://10.16.0.153:8080/"')
-            buildConfigField("String", "HOST_STATIC_RESOURCE_IMAGE", '"http://10.16.0.153/"')
+            buildConfigField("String", "BASE_URL", '"http://10.16.0.184:8080/"')
         }
     }
 }