左晓为主开发手持机充值管理机
zuoxiao
2023-12-18 8226f232c39359b36aff8a9b0453c2fb48ee4372
用户列表分页加载
11个文件已修改
3个文件已添加
490 ■■■■ 已修改文件
app/build.gradle 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/NewCardActivity.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/NewCardListActivity.java 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/ReplacementActivity.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/adapter/BaseRecyclerAdapter.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/adapter/NewCardAdapter.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/dao/BaseDaoSingleton.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/dao/UserCardDao.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_newcard_list.xml 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_recharge_list.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_new_card.xml 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_no_more.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/mipmap-xhdpi/ic_no_more.png 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/colors.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle
@@ -1,6 +1,14 @@
apply plugin: 'com.android.application'
android {
    signingConfigs {
        debug {
            storeFile file('dycz.jks')
            storePassword 'dycz@2023'
            keyAlias 'dayu'
            keyPassword 'dycz@2023'
        }
    }
    namespace 'com.dayu.recharge'
    compileSdk 33
@@ -16,6 +24,7 @@
        ndk{
            abiFilters 'armeabi-v7a'
        }
        signingConfig signingConfigs.debug
    }
@@ -28,6 +37,9 @@
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    dataBinding {
        enabled = true;
    }
    viewBinding {
        enabled = true;
@@ -70,4 +82,11 @@
    }
    //滚动选择框
    implementation 'com.contrarywind:Android-PickerView:4.1.9'
    //列表
    implementation 'io.github.scwang90:refresh-layout-kernel:2.0.5'
    implementation 'io.github.scwang90:refresh-header-classics:2.0.5'
    implementation 'androidx.recyclerview:recyclerview:1.2.0'//经典刷新头
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
}
app/src/main/java/com/dayu/recharge/activity/NewCardActivity.java
@@ -36,6 +36,8 @@
import org.json.JSONObject;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Copyright (C), 2023,
@@ -93,7 +95,7 @@
                    if (userName.length() <= 1 || !validateName(userName)) {
                        TipUtil.show(NewCardActivity.this, "请输入正确姓名");
                        return;
                    } else if (phone.length() < 11) {
                    } else if (phone.length() < 11 || !isValidPhoneNumber(phone)) {
                        TipUtil.show(NewCardActivity.this, "请输入正确手机号");
                        return;
                    } else if (!Utils.check(userID)) {
@@ -115,6 +117,45 @@
            }
        });
    }
    private boolean isValidPhoneNumber(String phoneNumber) {
        // 定义手机号的正则表达式,确保数字部分没有连续6位相同的数字
        String phoneRegex = "^1[0-9]{10}$";
        // 创建 Pattern 对象
        Pattern pattern = Pattern.compile(phoneRegex);
        // 创建 matcher 对象
        Matcher matcher = pattern.matcher(phoneNumber);
        // 判断手机号是否匹配正则表达式
        return matcher.matches() && !hasSixConsecutiveSameDigits(phoneNumber);
    }
    /**
     * 判断是否有6个相同的连续数字
     *
     * @param input
     * @return
     */
    public static boolean hasSixConsecutiveSameDigits(String input) {
        char[] digits = input.toCharArray();
        for (int i = 0; i <= digits.length - 6; i++) {
            boolean consecutiveSame = true;
            for (int j = 1; j < 6; j++) {
                if (digits[i + j] != digits[i + j - 1]) {
                    consecutiveSame = false;
                    break;
                }
            }
            if (consecutiveSame) {
                return true;
            }
        }
        return false;
    }
    private void rxPermission() {
        PermissionX.init(NewCardActivity.this).permissions(Manifest.permission.CAMERA)
@@ -320,10 +361,11 @@
            return (c >= 0x4e00 && c <= 0x9fa5);
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        newCardActivity=null;
        newCardActivity = null;
    }
}
app/src/main/java/com/dayu/recharge/activity/NewCardListActivity.java
@@ -3,8 +3,13 @@
import static com.dayu.recharge.view.TitleBar.ClickType_RIGHT_TEXT;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.dayu.recharge.adapter.NewCardAdapter;
import com.dayu.recharge.databinding.ActivityNewcardListBinding;
@@ -12,8 +17,19 @@
import com.dayu.recharge.utils.TipUtil;
import com.dayu.recharge.view.datepicker.CustomDatePicker;
import com.dayu.recharge.view.datepicker.DateFormatUtils;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.rxjava3.schedulers.Schedulers;
/**
 * Copyright (C), 2023,
@@ -26,12 +42,19 @@
    ActivityNewcardListBinding newcardListBinding;
    List<UserCardBean> userCardBeanList;
    List<UserCardBean> userCardBeanList = new ArrayList<>();
    NewCardAdapter adapter;
    private CustomDatePicker beginDatePicker;
    private CustomDatePicker endDatePicker;
    long beginTime;
    long endTime;
    int page = 0;
    //每页数据条数
    int limit = 30;
    RefreshLayout myRefreshLayout;
    Handler handler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
@@ -39,21 +62,68 @@
        newcardListBinding = ActivityNewcardListBinding.inflate(LayoutInflater.from(this));
        setContentView(newcardListBinding.getRoot());
        setRightButton();
        setData();
        initDatePicker();
        initList();
        getList();
    }
    private void setData() {
        try {
            userCardBeanList = baseDao.userCardDao().findAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
    private void initList() {
        myRefreshLayout = (RefreshLayout) newcardListBinding.refreshLayout;
        myRefreshLayout.setEnableRefresh(false);
        myRefreshLayout.setRefreshFooter(new ClassicsFooter(this));
        myRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(RefreshLayout refreshlayout) {
                page = page + 1;
                getList();
            }
        });
        adapter = new NewCardAdapter(this, userCardBeanList);
        newcardListBinding.newCardListView.setAdapter(adapter);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        newcardListBinding.recyclerView.setLayoutManager(layoutManager);
        newcardListBinding.recyclerView.setAdapter(adapter);
        int totale = baseDao.userCardDao().getUserTotale();
        newcardListBinding.userTotal.setText(totale + "");
    }
    private void getList() {
        // 创建一个 Observable
        Observable<List<UserCardBean>> observable = Observable.create(emitter -> {
            // 在这里执行异步操作
            List<UserCardBean> beanList;
            if (beginTime == 0 && endTime == 0) {
                beanList = asynchBaseDao.userCardDao().findAll(page * limit, limit);
            } else {
                beanList = asynchBaseDao.userCardDao().findByTime(beginTime, endTime);
            }
            // 将结果发送给观察者
            emitter.onNext(beanList);
            emitter.onComplete();
        });
        // 订阅观察者
        observable.subscribeOn(Schedulers.io()) // 指定在 IO 线程执行
                .observeOn(AndroidSchedulers.mainThread()) // 指定在单一线程观察结果
                .subscribe(
                        result -> {
                            // 在这里处理结果,这里是在主线程中
//                            System.out.println("Result: " + result);
                            if (result.size() < limit) {
                                myRefreshLayout.finishLoadMoreWithNoMoreData();
                            }
                            if (result != null && result.size() > 0) {
                                userCardBeanList.addAll(result);
                            }
                            adapter.notifyDataSetChanged();
                        },
                        error -> {
                            // 处理错误
                            System.err.println("Error: " + error.getMessage());
                        }
                );
    }
    private void setRightButton() {
        titleBar.setOnItemclickListner(ClickType_RIGHT_TEXT, new View.OnClickListener() {
            @Override
app/src/main/java/com/dayu/recharge/activity/ReplacementActivity.java
@@ -57,7 +57,7 @@
            e.printStackTrace();
        }
        adapter = new NewCardAdapter(this, userCardBeanList);
        binding.newCardListView.setAdapter(adapter);
//        binding.newCardListView.setAdapter(adapter);
    }
    EdtDialog edtDialog;
app/src/main/java/com/dayu/recharge/adapter/BaseRecyclerAdapter.java
New file
@@ -0,0 +1,64 @@
package com.dayu.recharge.adapter;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.dayu.recharge.databinding.ItemNoMoreBinding;
/**
 * Copyright (C), 2023,
 * Author: zuo
 * Date: 2023-04-20 8:48
 * Description:
 */
public class BaseRecyclerAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> {
    /**
     * viewType--分别为item以及空view
     */
    public static final int VIEW_TYPE_ITEM = 1;
    public static final int VIEW_TYPE_EMPTY = 0;
    public int myiewType;
    @NonNull
    @Override
    public T onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }
    @Override
    public void onBindViewHolder(@NonNull T holder, int position) {
    }
    @Override
    public int getItemCount() {
        return 0;
    }
    static class ViewHolderEmpty extends RecyclerView.ViewHolder {
        ItemNoMoreBinding mBinding;
        public ItemNoMoreBinding getBinding() {
            return mBinding;
        }
        public void setBinding(ItemNoMoreBinding binding) {
            this.mBinding = binding;
        }
        public ViewHolderEmpty(ItemNoMoreBinding itemView) {
            super(itemView.getRoot());
            this.mBinding = itemView;
        }
    }
}
app/src/main/java/com/dayu/recharge/adapter/NewCardAdapter.java
@@ -1,12 +1,20 @@
package com.dayu.recharge.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.RecyclerView;
import com.dayu.recharge.R;
import com.dayu.recharge.databinding.ItemNewCardBinding;
import com.dayu.recharge.databinding.ItemNoMoreBinding;
import com.dayu.recharge.dbBean.UserCardBean;
import com.dayu.recharge.utils.DateUtil;
@@ -16,7 +24,7 @@
 * Created by zuoxiao on 2018/12/24.
 */
public class NewCardAdapter extends BaseAdapter {
public class NewCardAdapter extends BaseRecyclerAdapter<RecyclerView.ViewHolder> {
    List<UserCardBean> rechargeList;
    Context mContext;
@@ -26,51 +34,69 @@
        this.rechargeList = rechargeList;
    }
    @NonNull
    @Override
    public int getCount() {
        if (rechargeList == null) {
            return 0;
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_EMPTY) {
            ItemNoMoreBinding emptyView = DataBindingUtil.inflate((LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE), R.layout.item_no_more, parent, false);
            return new ViewHolderEmpty(emptyView);
        } else {
            ItemNewCardBinding binding = DataBindingUtil.inflate((LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE), R.layout.item_new_card, parent, false);
            return new ViewHolder(binding);
        }
    }
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ViewHolder) {
            if (rechargeList.size() > 0) {
                ((ViewHolder) holder).getBinding().userName.setText("用户名:" + rechargeList.get(position).getUserName());
                ((ViewHolder) holder).getBinding().userNo.setText("身份证号:" + rechargeList.get(position).getUserID());
                ((ViewHolder) holder).getBinding().water.setText("电话:" + rechargeList.get(position).getPhone());
                ((ViewHolder) holder).getBinding().date.setText("日期:" + DateUtil.dateToStamp(rechargeList.get(position).getDate(), DateUtil.type1));
            }
        }
    }
    @Override
    public int getItemCount() {
        //同时这里也需要添加判断,如果mData.size()为0的话,只引入一个布局,就是emptyView
        // 那么,这个recyclerView的itemCount为1
        if (rechargeList.size() == 0) {
            return 1;
        }
        return rechargeList.size();
    }
    @Override
    public Object getItem(int position) {
        return position;
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        NewCardAdapter.ViewHolder holder = null;
        if (convertView == null) {
            holder = new NewCardAdapter.ViewHolder();
            convertView = View.inflate(mContext, R.layout.item_new_card, null);
            holder.userName = (TextView) convertView.findViewById(R.id.userName);
            holder.userNo = (TextView) convertView.findViewById(R.id.userNo);
            holder.water = (TextView) convertView.findViewById(R.id.water);
            holder.date = (TextView) convertView.findViewById(R.id.date);
            convertView.setTag(holder);
    public int getItemViewType(int position) {
        if (rechargeList.size() == 0) {
            return VIEW_TYPE_EMPTY;
        } else {
            holder = (NewCardAdapter.ViewHolder) convertView.getTag();
            return VIEW_TYPE_ITEM;
        }
        holder.userName.setText("用户名:" + rechargeList.get(position).getUserName());
        holder.userNo.setText("身份证号:" + rechargeList.get(position).getUserID());
        holder.water.setText("电话:" + rechargeList.get(position).getPhone());
        holder.date.setText("日期:" + DateUtil.dateToStamp(rechargeList.get(position).getDate(), DateUtil.type1));
        return convertView;
    }
    class ViewHolder {
        TextView userName;
        TextView userNo;
        TextView water;
        TextView date;
    static class ViewHolder extends RecyclerView.ViewHolder {
        ItemNewCardBinding mBinding;
        public ItemNewCardBinding getBinding() {
            return mBinding;
        }
        public void setBinding(ItemNewCardBinding binding) {
            this.mBinding = binding;
        }
        public ViewHolder(ItemNewCardBinding itemView) {
            super(itemView.getRoot());
            this.mBinding = itemView;
        }
    }
}
app/src/main/java/com/dayu/recharge/dao/BaseDaoSingleton.java
@@ -39,7 +39,7 @@
            AsynchBaseDao = Room.databaseBuilder(
                    context,
                    AppDatabase.class,
                    "ConfigurationData"
                    SqlitePath + "ConfigurationData"
            ).build();
        }
        return AsynchBaseDao;
app/src/main/java/com/dayu/recharge/dao/UserCardDao.java
@@ -35,4 +35,9 @@
    List<UserCardBean> findByTime(long beginTime, long endTime);
    @Query("select  * from UserCardBean where userName like :data or userID like :data or  phone like :data")
    List<UserCardBean> findByData(String data);
    @Query("select  * from UserCardBean order by date desc LIMIT :limit OFFSET :offset")
    List<UserCardBean> findAll(int offset,int limit);
    @Query("select COUNT(*) from UserCardBean")
    int getUserTotale();
}
app/src/main/res/layout/activity_newcard_list.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
@@ -14,13 +14,36 @@
        app:leftImage="@mipmap/icon_back"
        app:rightText="筛选" />
    <ListView
        android:id="@+id/newCard_listView"
    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="#ffffff"
        android:divider="@null"
        android:dividerHeight="0dp" />
        android:layout_above="@id/user_total"
        android:layout_below="@+id/titleBar">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#fff"
            android:overScrollMode="never"
            android:padding="10dp" />
        <com.scwang.smart.refresh.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
</LinearLayout>
    <TextView
        android:id="@+id/user_total"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:background="@color/title_bg"
        android:gravity="center"
        android:text="已创建用户:"
        android:textSize="@dimen/text_size" />
</RelativeLayout>
app/src/main/res/layout/activity_recharge_list.xml
@@ -31,7 +31,7 @@
        android:layout_alignParentBottom="true"
        android:background="@color/title_bg"
        android:gravity="center"
        android:text="累计充值:"
        android:text="已加载数据累计充值:"
        android:textSize="@dimen/text_size" />
</RelativeLayout>
app/src/main/res/layout/item_new_card.xml
@@ -1,57 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="15dp"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/userName"
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="用户名"
            android:textSize="14sp" />
            android:layout_marginLeft="15dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="15dp"
            android:orientation="vertical">
        <TextView
            android:id="@+id/userNo"
            <TextView
                android:id="@+id/userName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="用户名"
                android:textSize="14sp" />
            <TextView
                android:id="@+id/userNo"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="户号:123123"
                android:textSize="14sp" />
            <TextView
                android:id="@+id/water"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="水量:123123"
                android:textSize="14sp" />
            <TextView
                android:id="@+id/date"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="日期"
                android:textSize="14sp" />
        </LinearLayout>
        <View
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="户号:123123"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/water"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="水量:123123"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/date"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="日期"
            android:textSize="14sp" />
            android:layout_height="1px"
            android:layout_marginTop="15dp"
            android:background="#000000" />
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginTop="15dp"
        android:background="#000000" />
</layout>
</LinearLayout>
app/src/main/res/layout/item_no_more.xml
New file
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginRight="50dp"
            android:src="@mipmap/ic_no_more" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="没有数据"
            android:textColor="@color/choose_grey" />
    </LinearLayout>
</layout>
app/src/main/res/mipmap-xhdpi/ic_no_more.png
app/src/main/res/values/colors.xml
@@ -20,6 +20,7 @@
    <color name="date_picker_text_dark">#333333</color>
    <color name="ws_pay_alpha">#00000000</color>
    <color name="red">#ff0000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="text_wite">#ffffff</color>
    <color name="choose_grey">#cdcdcd</color>
</resources>