11 files added
1 files deleted
20 files modified
| | |
| | | <activity android:name=".ui.msg.MsgDetailActivity" /> |
| | | <activity android:name=".ui.sign.SignInActivity" /> |
| | | <activity android:name=".ui.coin.CoinSettingActivity" /> |
| | | <activity android:name=".ui.coin.WithDrawActivity" /> |
| | | <activity android:name=".ui.paypass.PaypassActivity" /> |
| | | <activity android:name=".ui.loadpage.PageActivitys$CoinRecordActivity" tools:ignore="Instantiatable"/> |
| | | |
| | | </application> |
| | |
| | | import android.content.Context; |
| | | import android.os.Bundle; |
| | | |
| | | import android.os.Process; |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | |
| | |
| | | }); |
| | | |
| | | CrashHandler crashHandler = CrashHandler.getInstance(); |
| | | crashHandler.init(getApplicationContext(), new CrashHandler.CrashListener() { |
| | | @Override |
| | | public void onCrash() { |
| | | crashHandler.init(getApplicationContext(), () -> { |
| | | for(Activity activity : activities){ |
| | | activity.finish(); |
| | | } |
| | | Process.killProcess(Process.myPid()); |
| | | System.exit(0); |
| | | } |
| | | }); |
| | | } |
| | | |
| | |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | setTitle(initTitle()); |
| | | try { |
| | | Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2]; |
| | | this.adapter = entityClass.newInstance();//实例化泛型 |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | refresh = mBinding.getRoot().findViewById(R.id.refresh); |
| | | refresh.setRefreshHeader(new ClassicsHeader(mContext)); |
| | | refresh.setRefreshFooter(new ClassicsFooter(mContext)); |
| | | refresh.setOnRefreshLoadMoreListener(this); |
| | | RecyclerView recycler = mBinding.getRoot().findViewById(R.id.recycler); |
| | | recycler.setLayoutManager(new LinearLayoutManager(mContext)); |
| | | recycler.setAdapter(adapter); |
| | | refresh = mBinding.getRoot().findViewById(R.id.refresh); |
| | | refresh.setOnRefreshLoadMoreListener(this); |
| | | mViewModel.getLiveData().observe(this, (Observer<List<RESULT>>) list -> { |
| | | adapter.showNull = true; |
| | |
| | | import android.util.Log; |
| | | import android.view.LayoutInflater; |
| | | import android.view.ViewGroup; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.recyclerview.widget.RecyclerView; |
| | | import androidx.viewbinding.ViewBinding; |
| | | |
| | | import com.runt.open.mvvm.databinding.LayoutNullBinding; |
| | | import com.runt.open.mvvm.util.DeviceUtil; |
| | | import com.runt.open.mvvm.util.DimensionUtils; |
| | | |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.lang.reflect.Method; |
| | |
| | | protected void setBottomMargin(RecyclerView.ViewHolder holder, int position, float dp, float defaultDp){ |
| | | ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams) holder.itemView.getLayoutParams(); |
| | | if(position == dataList.size() -1){ |
| | | params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, DeviceUtil.convertDpToPixel(dp,holder.itemView.getContext())); |
| | | params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, (int) DimensionUtils.convertDpToPixel(dp,holder.itemView.getContext())); |
| | | }else{ |
| | | params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, DeviceUtil.convertDpToPixel(defaultDp,holder.itemView.getContext())); |
| | | params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, (int) DimensionUtils.convertDpToPixel(defaultDp,holder.itemView.getContext())); |
| | | } |
| | | } |
| | | |
| | |
| | | import android.util.Log; |
| | | import androidx.annotation.NonNull; |
| | | import androidx.core.content.FileProvider; |
| | | import androidx.lifecycle.MutableLiveData; |
| | | import androidx.lifecycle.ViewModel; |
| | | import com.runt.open.mvvm.BuildConfig; |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | |
| | | import com.runt.open.mvvm.retrofit.api.CommonApiCenter; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | import com.runt.open.mvvm.retrofit.utils.RetrofitUtils; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | import io.reactivex.Observable; |
| | | import io.reactivex.functions.Consumer; |
| | | import io.reactivex.schedulers.Schedulers; |
| | | import okhttp3.*; |
| | | |
| | |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/11/11 0011. |
| | |
| | | |
| | | protected BaseActivity mActivity; |
| | | protected CommonApiCenter commonApi = RetrofitUtils.getInstance().getCommonApi(); |
| | | MutableLiveData<Integer> verifyResult = new MutableLiveData<>(); |
| | | public MutableLiveData<Integer> getVerifyResult() { |
| | | return verifyResult; |
| | | } |
| | | |
| | | public void onCreate(BaseActivity activity) { |
| | | this.mActivity = activity; |
| | | } |
| | | |
| | | public void getUserBean(){ |
| | | httpObserverOn(commonApi.getUserBean(), new HttpObserver<UserBean>() { |
| | | @Override |
| | | protected void onSuccess(UserBean data) { |
| | | UserBean.setUser(data); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 获取验证码 |
| | | * @param url 验证码地址 |
| | | * @param phone 手机号 |
| | | */ |
| | | public void getVerifyCode(String url,String phone){ |
| | | String time = new Date().getTime()+""; |
| | | httpObserverOnLoading(commonApi.getVerifyCode(url, phone, randomString(phone, time), time), new HttpObserver<Results.SmsResult>(){ |
| | | @Override |
| | | protected void onSuccess(Results.SmsResult data) { |
| | | verifyResult.setValue(0); |
| | | } |
| | | |
| | | @Override |
| | | protected void onFailed(HttpApiResult httpResult) { |
| | | super.onFailed(httpResult); |
| | | verifyResult.setValue(-1); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 随机字符串 |
| | | * @param phone |
| | | * @param time |
| | | * @return |
| | | */ |
| | | private String randomString(String phone,String time){ |
| | | int p = (int) Math.round(phone.length()/6.0); |
| | | int t = time.length()/6; |
| | | List<String> list = new ArrayList<String>(); |
| | | for(int i = 0 ; i < 6 ; i ++){ |
| | | String str = ""; |
| | | if(i*p>phone.length()){ |
| | | str = phone.substring((i-1)*p); |
| | | }else if((i+1)*p>phone.length()){ |
| | | str = phone.substring(i*p); |
| | | }else{ |
| | | str = phone.substring(i*p,(i+1)*p); |
| | | } |
| | | String num = ((Integer.parseInt(str)*Long.parseLong(time))+"") ; |
| | | list.add(num); |
| | | } |
| | | //return sb.toString(); |
| | | return plusSingle2(list); |
| | | } |
| | | |
| | | private String plusSingle2(List<String> list){ |
| | | StringBuilder sb = new StringBuilder(); |
| | | for(int i = 0 ; i < list.size() ; i ++){ |
| | | sb.append(list.get(i).substring(list.get(i).length()-2<0?0:list.get(i).length()-2)); |
| | | } |
| | | return sb.toString(); |
| | | |
| | | } |
| | | |
| | | public void checkUpdate(boolean showTip){ |
| | |
| | | mActivity.showLoadingDialog(""); |
| | | }) |
| | | .observeOn(AndroidScheduler.mainThread()) |
| | | .doOnError(new Consumer<Throwable>() { |
| | | @Override |
| | | public void accept(Throwable throwable) throws Exception { |
| | | |
| | | } |
| | | .doOnError(throwable -> { |
| | | mActivity.dissmissLoadingDialog(); |
| | | Log.e("ViewModel",hashCode()+" httpObserverOnLoading "+throwable); |
| | | }) |
| | | .doOnComplete(() -> { |
| | | mActivity.dissmissLoadingDialog(); |
| | |
| | | public String id; |
| | | public UserBean toUser,fromUser; |
| | | public int count,after,before,type; |
| | | public Date cTime; |
| | | public String cTime; |
| | | /** |
| | | * 备注 |
| | | **/ |
| | |
| | | import android.content.pm.PackageManager; |
| | | import android.os.Build; |
| | | import android.os.Environment; |
| | | import android.os.Looper; |
| | | import android.util.Log; |
| | | import android.widget.Toast; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileNotFoundException; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStreamReader; |
| | | import java.io.PrintWriter; |
| | | import java.io.StringWriter; |
| | | import java.io.Writer; |
| | | import java.io.*; |
| | | import java.lang.reflect.Field; |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | |
| | | |
| | | //系统默认的UncaughtException处理类 |
| | | private Thread.UncaughtExceptionHandler mDefaultHandler; |
| | | |
| | | CrashListener crashListener; |
| | | |
| | | //CrashHandler实例 |
| | | private static CrashHandler instance; |
| | | CrashListener crashListener; |
| | | //程序的Context对象 |
| | | private Context mContext; |
| | | //用来存储设备信息和异常信息 |
| | |
| | | Thread.setDefaultUncaughtExceptionHandler(this); |
| | | } |
| | | |
| | | /** |
| | | * 初始化 |
| | | */ |
| | | public void init(Context context,CrashListener crashListener) { |
| | | Log.i(TAG, "init context:"+context); |
| | | mContext = context; |
| | |
| | | Thread.setDefaultUncaughtExceptionHandler(this); |
| | | } |
| | | |
| | | public interface CrashListener { |
| | | void onCrash(); |
| | | } |
| | | /** |
| | | * 当UncaughtException发生时会转入该函数来处理 |
| | | */ |
| | |
| | | if (!handleException(ex) && mDefaultHandler != null) { |
| | | //如果用户没有处理则让系统默认的异常处理器来处理 |
| | | mDefaultHandler.uncaughtException(thread, ex); |
| | | } else if(crashListener != null){ |
| | | crashListener.onCrash(); |
| | | } else { |
| | | try { |
| | | Thread.sleep(3000); |
| | | } catch (InterruptedException e) { |
| | | Log.e(TAG, "error : ", e); |
| | | } |
| | | //退出程序 |
| | | android.os.Process.killProcess(android.os.Process.myPid()); |
| | | System.exit(1); |
| | | if (crashListener != null) { |
| | | crashListener.onCrash(); |
| | | } |
| | | } |
| | | |
| | |
| | | //收集设备参数信息 |
| | | collectDeviceInfo(mContext); |
| | | |
| | | //使用Toast来显示异常信息 |
| | | new Thread() { |
| | | @Override |
| | | public void run() { |
| | | Looper.prepare(); |
| | | Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show(); |
| | | Looper.loop(); |
| | | } |
| | | }.start(); |
| | | //保存日志文件 |
| | | saveCatchInfo2File(ex); |
| | | saveCatchInfoFile(ex); |
| | | return true; |
| | | } |
| | | |
| | |
| | | * @param ex |
| | | * @return 返回文件名称,便于将文件传送到服务器 |
| | | */ |
| | | private String saveCatchInfo2File(Throwable ex) { |
| | | private String saveCatchInfoFile(Throwable ex) { |
| | | ex.printStackTrace(); |
| | | Log.i(TAG, "saveCatchInfo2File Throwable:"+ex); |
| | | |
| | |
| | | String time = formatter.format(new Date()); |
| | | String fileName = "crash-" + time + "-" + timestamp + ".log"; |
| | | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
| | | String path = "/mnt/sdcard/crash/"; |
| | | String path = mContext.getExternalFilesDir(null).getAbsolutePath()+"/crash/"; |
| | | File dir = new File(path); |
| | | if (!dir.exists()) { |
| | | dir.mkdirs(); |
| | | } |
| | | FileOutputStream fos = new FileOutputStream(path + fileName); |
| | | String newFileName = path + fileName; |
| | | Log.i(TAG,"exc newFileName:"+newFileName); |
| | | File file = new File(newFileName); |
| | | file.mkdirs(); |
| | | if(file.exists()){ |
| | | file.delete(); |
| | | } |
| | | file.createNewFile(); |
| | | FileOutputStream fos = new FileOutputStream(file); |
| | | fos.write(sb.toString().getBytes()); |
| | | //发送给开发人员 |
| | | sendCrashLog2PM(path+fileName); |
| | |
| | | s = reader.readLine(); |
| | | if(s == null) break; |
| | | //由于目前尚未确定以何种方式发送,所以先打出log日志。 |
| | | //Log.i("info", s.toString()); |
| | | Log.i("info", s.toString()); |
| | | } |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static interface CrashListener{ |
| | | void onCrash(); |
| | | } |
| | | } |
| | |
| | | package com.runt.open.mvvm.retrofit.api; |
| | | |
| | | |
| | | import com.runt.open.mvvm.config.Configuration; |
| | | import com.runt.open.mvvm.data.HttpApiResult; |
| | | import com.runt.open.mvvm.data.PageResult; |
| | | import com.runt.open.mvvm.data.Results; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | import io.reactivex.Observable; |
| | | import okhttp3.MultipartBody; |
| | | import retrofit2.http.*; |
| | |
| | | Observable<Object> postPageData(@Url String url, @Field("page") int pageNum, @Field("size") int pageSize, @FieldMap Map<String,String> param); |
| | | |
| | | /** |
| | | * 登录 |
| | | * @return |
| | | */ |
| | | @POST("loginToken") |
| | | Observable<HttpApiResult<UserBean>> getUserBean(); |
| | | |
| | | @FormUrlEncoded |
| | | @POST |
| | | Observable<HttpApiResult<Results.SmsResult>> getVerifyCode(@Url String url, @Field(Configuration.KEY_PHONE) String phone, @Field(Configuration.KEY_CODE) String code, @Field("time") String time); |
| | | /** |
| | | * app更新 |
| | | * @return |
| | | */ |
| | | @GET("getControlVersion") |
| | | Observable<HttpApiResult<Results.ApkVersion>> getAppUpdate(); |
| | | |
| | | @FormUrlEncoded |
| | | @POST("updateName") |
| | | Observable<Results.StringApiResult> updateName(@Field("username") String name); |
| | | |
| | |
| | | @GET("getMsgDetail") |
| | | Observable<HttpApiResult<Results.Message>> getMsgDetail(@Query("id") String id); |
| | | |
| | | @FormUrlEncoded |
| | | @POST("updateAlipay") |
| | | Observable<Results.StringApiResult> updateAlipay(@Field("account") String account,@Field("paypass") String paypass); |
| | | |
| | | @FormUrlEncoded |
| | | @POST("updateRealname") |
| | | Observable<Results.StringApiResult> updateRealname(@Field("account") String account,@Field("paypass") String paypass); |
| | | |
| | | @FormUrlEncoded |
| | | @POST("withDraw") |
| | | Observable<Results.StringApiResult> withDraw(@Field("paypass") String paypass,@Field("count") int count); |
| | | |
| | | /** |
| | | * 获取签到列表 |
| | |
| | | @POST("signIn") |
| | | Observable<Results.StringApiResult> signIn(); |
| | | |
| | | @FormUrlEncoded |
| | | @POST("updatePaypass") |
| | | Observable<Results.StringApiResult> updatePaypass(@Field("smsCode") String smsCode,@Field("paypass") String paypass); |
| | | } |
| | |
| | | import com.runt.open.mvvm.config.Configuration; |
| | | import com.runt.open.mvvm.data.HttpApiResult; |
| | | import com.runt.open.mvvm.data.Results; |
| | | |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | import io.reactivex.Observable; |
| | | import retrofit2.http.Field; |
| | | import retrofit2.http.FormUrlEncoded; |
| | | import retrofit2.http.POST; |
| | | import retrofit2.http.Url; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/11/15 0015. |
| | |
| | | @FormUrlEncoded |
| | | @POST("loginCode") |
| | | Observable<HttpApiResult<UserBean>> loginByCode(@Field(Configuration.KEY_PHONE) String phone, @Field(Configuration.KEY_CODE) String code); |
| | | |
| | | |
| | | @FormUrlEncoded |
| | | @POST |
| | | Observable<HttpApiResult<Results.SmsResult>> getVerifyCode(@Url String url, @Field(Configuration.KEY_PHONE) String phone, @Field(Configuration.KEY_CODE) String code, @Field("time") String time); |
| | | |
| | | /** |
| | | * 重置密码 |
| | |
| | | binding.txtCount.setText("+" + data.count); |
| | | Glide.with(binding.getRoot().getContext()).load(BuildConfig.HOST_IP_ADDR + (data.fromUser == null ? "" : data.fromUser.getHead())).apply(options).into(binding.imgHead); |
| | | } |
| | | binding.txtTime.setText(HandleDate.getTimeStateNew(data.cTime)); |
| | | binding.txtTime.setText(HandleDate.getTimeStateNew(HandleDate.getDateTimeToLong(data.cTime))); |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.adapter; |
| | | |
| | | import com.runt.open.mvvm.base.adapter.BaseAdapter; |
| | | import com.runt.open.mvvm.databinding.ItemNumBinding; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-30. |
| | | */ |
| | | public class NumAdapter extends BaseAdapter<String, ItemNumBinding> { |
| | | |
| | | public NumAdapter(List<String> list) { |
| | | this.dataList = list; |
| | | } |
| | | |
| | | @Override |
| | | protected void onBindView(ItemNumBinding binding, int position, String s) { |
| | | binding.text.setText(s); |
| | | binding.getRoot().setTag(s); |
| | | |
| | | } |
| | | } |
| | |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | import com.runt.open.mvvm.ui.paypass.PaypassActivity; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of 金币交易设置 |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-30. |
| | | */ |
| | | public class CoinSettingActivity extends BaseActivity<ActivitySettingCoinBinding,CoinSettingViewModel> { |
| | | public class CoinSettingActivity extends BaseActivity<ActivitySettingCoinBinding, CoinViewModel> { |
| | | |
| | | private int requestCode = 0; |
| | | |
| | |
| | | public void doSuccess(Object obj) { |
| | | mBinding.txtAlipay.setText(obj.toString()); |
| | | requestCode = REQUEST_CODE_PAYPASS_FOR_ALIPAY; |
| | | //launcher.launch(new Intent(mContext, PaypassActivity.class)); |
| | | launcher.launch(new Intent(mContext, PaypassActivity.class)); |
| | | } |
| | | }); |
| | | }); |
| | |
| | | public void doSuccess(Object obj) { |
| | | requestCode = REQUEST_CODE_PAYPASS_FOR_REALNAME; |
| | | mBinding.txtRealname.setText(obj.toString()); |
| | | //launcher.launch(new Intent(mContext, PaypassActivity.class)); |
| | | launcher.launch(new Intent(mContext, PaypassActivity.class)); |
| | | } |
| | | }); |
| | | }); |
| | | mBinding.linPass.setOnClickListener(v->{ |
| | | //startActivity(new Intent(mContext,PaypassActivity.class).putExtra("type",1)); |
| | | startActivity(new Intent(mContext,PaypassActivity.class).putExtra("type",1)); |
| | | }); |
| | | } |
| | | |
New file |
| | |
| | | package com.runt.open.mvvm.ui.coin; |
| | | |
| | | import android.content.Intent; |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | import com.runt.open.mvvm.data.HttpApiResult; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | |
| | | /** |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26. |
| | | */ |
| | | public class CoinViewModel extends BaseViewModel { |
| | | |
| | | //更新真实姓名 |
| | | public void updateName(String name,String pass, HttpObserver<String> httpObserver){ |
| | | httpObserverOnLoading(commonApi.updateRealname(name,pass),httpObserver); |
| | | } |
| | | |
| | | //更新支付宝 |
| | | public void updateAlipay(String alipay,String pass, HttpObserver<String> httpObserver){ |
| | | httpObserverOnLoading(commonApi.updateAlipay(alipay,pass),httpObserver); |
| | | } |
| | | |
| | | //提现 |
| | | public void withDraw(String pass,int count){ |
| | | httpObserverOnLoading(commonApi.withDraw(pass, count), new HttpObserver<String>(mActivity) { |
| | | @Override |
| | | protected void onSuccess(String data) { |
| | | UserBean.getUser().setCoin(UserBean.getUser().getCoin()-count); |
| | | mActivity.showToast("申请成功"); |
| | | mActivity.setResult(mActivity.RESULT_OK); |
| | | mActivity.finish(); |
| | | } |
| | | |
| | | @Override |
| | | protected void onFailed(HttpApiResult error) { |
| | | if(error.code == 40004){ |
| | | mActivity.showDialog("申请失败", "未找到对应的支付宝账户", "设置", "取消", new ResPonse() { |
| | | @Override |
| | | public void doSuccess(Object obj) { |
| | | mActivity.startActivity(new Intent(mActivity, CoinSettingActivity.class) );//去设置密码 |
| | | } |
| | | }); |
| | | }else if(error.code == 622){ |
| | | mActivity.showDialog("申请失败",error.msg,null); |
| | | }else{ |
| | | super.onFailed(error); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.coin; |
| | | |
| | | import android.content.Intent; |
| | | import android.text.Editable; |
| | | import android.text.TextWatcher; |
| | | import android.view.View; |
| | | import androidx.activity.result.ActivityResultLauncher; |
| | | import androidx.activity.result.contract.ActivityResultContracts; |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | | import com.runt.open.mvvm.databinding.ActivityWithdrawBinding; |
| | | import com.runt.open.mvvm.listener.CustomClickListener; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | import com.runt.open.mvvm.ui.paypass.PaypassActivity; |
| | | |
| | | /** |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-30. |
| | | */ |
| | | public class WithDrawActivity extends BaseActivity<ActivityWithdrawBinding, CoinViewModel> { |
| | | |
| | | ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { |
| | | if(result.getResultCode() == RESULT_OK){ |
| | | int count = Integer.parseInt(mBinding.edit.getText().toString())*1000; |
| | | mViewModel.withDraw(result.getData().getStringExtra("paypass"),count); |
| | | } |
| | | }); |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | |
| | | mBinding.txtBalance.setText(String.format("当前金币数量%s个", UserBean.getUser().getCoin())); |
| | | mBinding.edit.addTextChangedListener(new TextWatcher() { |
| | | @Override |
| | | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void afterTextChanged(Editable editable) { |
| | | mBinding.txtRmb.setText(String.format("提现¥%s元",mBinding.edit.getText())); |
| | | } |
| | | }); |
| | | mBinding.btnSubmit.setOnClickListener(new CustomClickListener() { |
| | | @Override |
| | | protected void onSingleClick(View view) { |
| | | if(isNull(mBinding.edit.getText())){ |
| | | showToast("请输入提现数量"); |
| | | }else{ |
| | | int count = Integer.parseInt(mBinding.edit.getText().toString())*1000; |
| | | if(count>UserBean.getUser().getCoin()){ |
| | | showToast("余额不足"); |
| | | }else if( isNull(UserBean.getUser().getAlipay())){ |
| | | showToast("还没有设置支付宝账号"); |
| | | }else { |
| | | launcher.launch(new Intent(mContext, PaypassActivity.class));//开启支付密码 |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public void loadData() { |
| | | |
| | | } |
| | | } |
| | |
| | | package com.runt.open.mvvm.ui.loadpage; |
| | | |
| | | import android.content.Intent; |
| | | import android.graphics.drawable.Drawable; |
| | | import android.view.View; |
| | | import com.runt.open.mvvm.R; |
| | | import com.runt.open.mvvm.base.activities.LoadPageActivity; |
| | | import com.runt.open.mvvm.data.Results; |
| | | import com.runt.open.mvvm.databinding.RefreshRecyclerBinding; |
| | | import com.runt.open.mvvm.databinding.ActivityRecyclerBinding; |
| | | import com.runt.open.mvvm.listener.CustomClickListener; |
| | | import com.runt.open.mvvm.ui.adapter.CoinTransAdapter; |
| | | import com.runt.open.mvvm.ui.coin.CoinSettingActivity; |
| | | |
| | | import java.util.Map; |
| | | |
| | |
| | | public class PageActivitys { |
| | | |
| | | //金币记录 |
| | | public class CoinRecordActivity extends LoadPageActivity<RefreshRecyclerBinding, PageViewModels.CoinRecordViewModel, CoinTransAdapter, Results.CustomCoin>{ |
| | | public static class CoinRecordActivity extends LoadPageActivity<ActivityRecyclerBinding, PageViewModels.CoinRecordViewModel, CoinTransAdapter, Results.CustomCoin>{ |
| | | @Override |
| | | protected String initTitle() { |
| | | return "金币记录"; |
| | | } |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | super.initViews(); |
| | | Drawable drawable = getResources().getDrawable(R.mipmap.icon_white_setting); |
| | | drawable.setTint(getResources().getColor(R.color.txt_color)); |
| | | setTitleRight(drawable); |
| | | titleBarView.setRightClick(new CustomClickListener() { |
| | | @Override |
| | | protected void onSingleClick(View view) { |
| | | startActivity(new Intent(mContext, CoinSettingActivity.class));//打开设置 |
| | | } |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | protected Map requestParams() { |
| | | Map map = super.requestParams(); |
| | | map.put("inOrOut",0); |
| | |
| | | package com.runt.open.mvvm.ui.login; |
| | | |
| | | import androidx.lifecycle.MutableLiveData; |
| | | import com.runt.open.mvvm.R; |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | import com.runt.open.mvvm.config.Configuration; |
| | | import com.runt.open.mvvm.data.HttpApiResult; |
| | | import com.runt.open.mvvm.data.Results; |
| | | import com.runt.open.mvvm.retrofit.api.LoginApiCenter; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | import com.runt.open.mvvm.retrofit.utils.RetrofitUtils; |
| | | import com.runt.open.mvvm.util.MyLog; |
| | | import io.reactivex.Observable; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/11/15 0015. |
| | |
| | | loginApi = RetrofitUtils.getInstance().getRetrofit(LoginApiCenter.class); |
| | | } |
| | | |
| | | MutableLiveData<UserBean> loginResult = new MutableLiveData<>(); |
| | | MutableLiveData<Integer> verifyResult = new MutableLiveData<>(); |
| | | MutableLiveData<Results.StringApiResult> resetResult = new MutableLiveData<>(); |
| | | MutableLiveData<Results.StringApiResult> registerResult = new MutableLiveData<>(); |
| | | HttpObserver<UserBean> logginObserver; |
| | |
| | | logginObserver = new HttpObserver<UserBean>(mActivity){ |
| | | @Override |
| | | protected void onSuccess(UserBean data) { |
| | | loginResult.setValue(data); |
| | | UserBean.setUser(data); |
| | | mActivity.putStringProjectPrefrence(Configuration.KEY_USERNAME, data.getUsername()); |
| | | MyLog.i("registerlogin",data.toString()); |
| | | mActivity.showToast(R.string.login_success); |
| | | mActivity.setResult(mActivity.RESULT_CODE_SUCESS); |
| | | mActivity.finish(); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public MutableLiveData<UserBean> getLoginResult() { |
| | | return loginResult; |
| | | } |
| | | |
| | | public MutableLiveData<Integer> getVerifyResult() { |
| | | return verifyResult; |
| | | } |
| | | |
| | | /** |
| | | * 密码登录 |
| | |
| | | getVerifyCode("getLoginSMS",phone); |
| | | } |
| | | |
| | | /** |
| | | * 获取验证码 |
| | | * @param url 验证码地址 |
| | | * @param phone 手机号 |
| | | */ |
| | | public void getVerifyCode(String url,String phone){ |
| | | String time = new Date().getTime()+""; |
| | | httpObserverOnLoading(loginApi.getVerifyCode(url, phone, randomString(phone, time), time), new HttpObserver<Results.SmsResult>(){ |
| | | @Override |
| | | protected void onSuccess(Results.SmsResult data) { |
| | | verifyResult.setValue(0); |
| | | } |
| | | |
| | | @Override |
| | | protected void onFailed(HttpApiResult httpResult) { |
| | | super.onFailed(httpResult); |
| | | verifyResult.setValue(-1); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 随机字符串 |
| | | * @param phone |
| | | * @param time |
| | | * @return |
| | | */ |
| | | private String randomString(String phone,String time){ |
| | | int p = (int) Math.round(phone.length()/6.0); |
| | | int t = time.length()/6; |
| | | List<String> list = new ArrayList<String>(); |
| | | for(int i = 0 ; i < 6 ; i ++){ |
| | | String str = ""; |
| | | if(i*p>phone.length()){ |
| | | str = phone.substring((i-1)*p); |
| | | }else if((i+1)*p>phone.length()){ |
| | | str = phone.substring(i*p); |
| | | }else{ |
| | | str = phone.substring(i*p,(i+1)*p); |
| | | } |
| | | String num = ((Integer.parseInt(str)*Long.parseLong(time))+"") ; |
| | | list.add(num); |
| | | } |
| | | //return sb.toString(); |
| | | return plusSingle2(list); |
| | | } |
| | | |
| | | private String plusSingle2(List<String> list){ |
| | | StringBuilder sb = new StringBuilder(); |
| | | for(int i = 0 ; i < list.size() ; i ++){ |
| | | sb.append(list.get(i).substring(list.get(i).length()-2<0?0:list.get(i).length()-2)); |
| | | } |
| | | return sb.toString(); |
| | | |
| | | } |
| | | } |
| | |
| | | import android.content.Intent; |
| | | import android.view.View; |
| | | import android.widget.EditText; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.runt.open.mvvm.R; |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | | import com.runt.open.mvvm.config.Configuration; |
| | |
| | | import com.runt.open.mvvm.listener.CustomClickListener; |
| | | import com.runt.open.mvvm.ui.web.WebViewActivity; |
| | | import com.runt.open.mvvm.util.AlgorithmUtils; |
| | | import com.runt.open.mvvm.util.MyLog; |
| | | import com.runt.open.mvvm.util.PhoneUtil; |
| | | |
| | | import java.util.Date; |
| | |
| | | }else{ |
| | | |
| | | } |
| | | }); |
| | | mViewModel.getLoginResult().observe(this, loggedInUser -> { |
| | | putStringProjectPrefrence(Configuration.KEY_USERNAME, mBinding.editPhone.getText().toString()); |
| | | UserBean.setUser(loggedInUser); |
| | | putStringProjectPrefrence(Configuration.KEY_USERINFO, new Gson().toJson(loggedInUser)); |
| | | MyLog.i("registerlogin",loggedInUser.toString()); |
| | | showToast(R.string.login_success); |
| | | setResult(RESULT_CODE_SUCESS); |
| | | finish(); |
| | | }); |
| | | } |
| | | |
| | |
| | | * Created by Administrator on 2021/11/15 0015. |
| | | */ |
| | | |
| | | import androidx.lifecycle.MutableLiveData; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | private static UserBean user; |
| | | public static MutableLiveData<UserBean> onUpdate = new MutableLiveData<>(); |
| | | |
| | | public static UserBean getUser() { |
| | | return user; |
| | |
| | | |
| | | public static void setUser(UserBean user) { |
| | | UserBean.user = user; |
| | | onUpdate.postValue(user); |
| | | } |
| | | |
| | | /** 主键 **/ |
| | |
| | | import androidx.activity.result.contract.ActivityResultContracts; |
| | | import com.bumptech.glide.Glide; |
| | | import com.bumptech.glide.request.RequestOptions; |
| | | import com.google.gson.Gson; |
| | | import com.luck.picture.lib.PictureSelector; |
| | | import com.luck.picture.lib.config.PictureConfig; |
| | | import com.luck.picture.lib.config.PictureMimeType; |
| | |
| | | import com.runt.open.mvvm.BuildConfig; |
| | | import com.runt.open.mvvm.R; |
| | | import com.runt.open.mvvm.base.fragments.BaseFragment; |
| | | import com.runt.open.mvvm.config.Configuration; |
| | | import com.runt.open.mvvm.databinding.FragmentMineBinding; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | import com.runt.open.mvvm.ui.coin.WithDrawActivity; |
| | | import com.runt.open.mvvm.ui.coin.CoinSettingActivity; |
| | | import com.runt.open.mvvm.ui.loadpage.PageActivitys; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | |
| | | public class MineFragment extends BaseFragment<FragmentMineBinding,MineViewModel> implements View.OnClickListener { |
| | | |
| | | private final String TAG = "MineFragment"; |
| | | ActivityResultLauncher<Intent> signLaunch = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { |
| | | |
| | | ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { |
| | | refreshUi(); |
| | | }); |
| | | @Override |
| | | public void initViews() { |
| | | mViewModel.getUserBean(); |
| | | UserBean.onUpdate.observe(this, userBean -> { |
| | | mActivity.putStringProjectPrefrence(Configuration.KEY_USERINFO, new Gson().toJson(userBean)); |
| | | refreshUi(); |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public void loadData() { |
| | | setOnClickListener(this,R.id.lin_sign,R.id.lin_coin,R.id.img,R.id.txt_name); |
| | | refreshUi(); |
| | | } |
| | | |
| | | public void refreshUi(){ |
| | | if(UserBean.getUser() != null){ |
| | | RequestOptions options = new RequestOptions() |
| | | .placeholder(R.mipmap.default_head)//图片加载出来前,显示的图片 |
| | |
| | | mBinding.txtCoin.setText(UserBean.getUser().getCoin()+""); |
| | | mBinding.txtSigns.setText(UserBean.getUser().getSign()+""); |
| | | mBinding.linGroup.setVisibility(View.VISIBLE); |
| | | |
| | | }else{ |
| | | Glide.with(getContext()).load(R.mipmap.default_head).into(mBinding.img); |
| | | mBinding.txtName.setText("未登录"); |
| | | mBinding.linGroup.setVisibility(View.GONE); |
| | | } |
| | | setOnClickListener(this,R.id.lin_sign,R.id.lin_coin,R.id.img,R.id.txt_name); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void onClick(View view) { |
| | |
| | | } |
| | | }); |
| | | }else{ |
| | | //startActivityForResult(new Intent(mActivity, WithDrawActivity.class),REQUEST_CODE_WITHDRAW ); |
| | | launcher.launch(new Intent(mActivity, WithDrawActivity.class) ); |
| | | } |
| | | } |
| | | } |
| | |
| | | .show(); |
| | | break; |
| | | case R.id.lin_sign://签到 |
| | | signLaunch.launch(new Intent(getContext(), SignInActivity.class)); |
| | | launcher.launch(new Intent(getContext(), SignInActivity.class)); |
| | | break; |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.paypass; |
| | | |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | |
| | | /** |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-30. |
| | | */ |
| | | public class PayPassViewModel extends BaseViewModel { |
| | | |
| | | public void updatePass(String pass,String code){ |
| | | httpObserverOnLoading(commonApi.updatePaypass(code, pass), new HttpObserver(mActivity) { |
| | | @Override |
| | | protected void onSuccess(Object data) { |
| | | mActivity.finish(); |
| | | mActivity.showToast("支付密码修改成功"); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.paypass; |
| | | |
| | | import android.app.Instrumentation; |
| | | import android.content.Intent; |
| | | import android.text.Editable; |
| | | import android.text.TextWatcher; |
| | | import android.view.KeyEvent; |
| | | import androidx.recyclerview.widget.GridLayoutManager; |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | | import com.runt.open.mvvm.databinding.ActivityPaypassBinding; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.ui.adapter.NumAdapter; |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | import com.runt.open.mvvm.widgets.PasswordInputView; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-30. |
| | | */ |
| | | public class PaypassActivity extends BaseActivity<ActivityPaypassBinding, PayPassViewModel> { |
| | | |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | int type = getIntent().getIntExtra("type",0);// 0 验证 , 1 修改 |
| | | if(type == 0) { |
| | | setTitle("验证支付密码"); |
| | | }else{ |
| | | setTitle("修改支付密码"); |
| | | } |
| | | PasswordInputView password = mBinding.paypassInclude.password; |
| | | mBinding.paypassInclude.view.setOnClickListener(v->{}); |
| | | mBinding.paypassInclude.recyclerNum.setLayoutManager(new GridLayoutManager(this,3)); |
| | | mBinding.paypassInclude.password.addTextChangedListener(new TextWatcher() { |
| | | @Override |
| | | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void afterTextChanged(Editable editable) { |
| | | if(editable.length() ==6){ |
| | | |
| | | if(type == 0 ){ |
| | | setResult(RESULT_OK,new Intent().putExtra("paypass",editable.toString())); |
| | | finish(); |
| | | }else if(type == 1){ |
| | | if(password.getTag() == null){ |
| | | password.setText(""); |
| | | password.setTag(editable.toString()); |
| | | mBinding.paypassInclude.txtTip.setText("请再次输入支付密码"); |
| | | } else if(password.getTag().toString().equals(editable.toString())) { |
| | | mViewModel.getVerifyCode("getPayPassSMS", UserBean.getUser().getPhone()); |
| | | } else if(!password.getTag().toString().equals(editable.toString())) { |
| | | password.setText(""); |
| | | password.setTag(null); |
| | | showToast("两次输入不一致"); |
| | | mBinding.paypassInclude.txtTip.setText("两次输入不一致"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | mViewModel.getVerifyResult().observe(this, integer -> { |
| | | if(integer == 0){ |
| | | showInputDialog("输入验证码", "", "请输入发送到" + UserBean.getUser().getPhone().substring(8)+"的验证码", new ResPonse() { |
| | | @Override |
| | | public void doSuccess(Object obj) { |
| | | mViewModel.updatePass(password.getText().toString(),obj.toString()); |
| | | } |
| | | }); |
| | | } |
| | | password.setText(""); |
| | | password.setTag(null); |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public void loadData() { |
| | | List<String> list = new ArrayList<>(); |
| | | for(int i = 1 ; i < 10; i ++) { |
| | | list.add(i+""); |
| | | } |
| | | list.add("×"); |
| | | list.add("0"); |
| | | list.add("←"); |
| | | NumAdapter numAdapter = new NumAdapter(list); |
| | | numAdapter.setOnItemClickListener((position, s) -> { |
| | | |
| | | if(s.equals("←")){ |
| | | new Thread(() -> { |
| | | Instrumentation inst = new Instrumentation(); |
| | | inst.sendKeyDownUpSync( KeyEvent.KEYCODE_DEL ); |
| | | }).start(); |
| | | }else if(s.equals("×")){ |
| | | showDialog("取消操作", "确定取消当前操作?", new ResPonse() { |
| | | @Override |
| | | public void doSuccess(Object obj) { |
| | | finish(); |
| | | } |
| | | }); |
| | | } else { |
| | | new Thread(() -> { |
| | | Instrumentation inst = new Instrumentation(); |
| | | inst.sendKeyDownUpSync( Integer.parseInt(s)+7 ); |
| | | }).start(); |
| | | } |
| | | }); |
| | | mBinding.paypassInclude.recyclerNum.setAdapter(numAdapter); |
| | | } |
| | | } |
| | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * dp获取dip |
| | | * @param dp |
| | | * @return |
| | | */ |
| | | public static int convertDpToPixel(float dp, Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | return (int) (dp * displayMetrics.density); |
| | | } |
| | | |
| | | /*** |
| | | * px获取dip |
| | | * @param pixel |
| | | * @return |
| | | */ |
| | | public static int convertPixelToDp(int pixel, Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | return (int) (pixel / displayMetrics.density); |
| | | } |
| | | |
| | | public static String getSerialNumber(Context context) { |
| | | String serial = ""; |
| | |
| | | * @param dp |
| | | * @return |
| | | */ |
| | | public int convertDpToPixel(float dp,Context context) { |
| | | public static float convertDpToPixel(float dp, Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | return (int) (dp * displayMetrics.density); |
| | | return (dp * displayMetrics.density); |
| | | } |
| | | |
| | | /*** |
| | |
| | | * @param pixel |
| | | * @return |
| | | */ |
| | | public int convertPixelToDp(int pixel,Context context) { |
| | | public static float convertPixelToDp(int pixel,Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | return (int) (pixel / displayMetrics.density); |
| | | return (pixel / displayMetrics.density); |
| | | } |
| | | /** |
| | | * 把pix值转换为sp |
| | |
| | | * (DisplayMetrics类中属性scaledDensity) |
| | | * @return |
| | | */ |
| | | public static int convertSpToPixel(Context context, float spValue) { |
| | | public static float convertSpToPixel(Context context, float spValue) { |
| | | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; |
| | | return (int) (spValue * fontScale + 0.5f); |
| | | return (spValue * fontScale + 0.5f); |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.widgets; |
| | | |
| | | import android.content.Context; |
| | | import android.content.res.Resources; |
| | | import android.content.res.TypedArray; |
| | | import android.graphics.Canvas; |
| | | import android.graphics.Paint; |
| | | import android.graphics.RectF; |
| | | import android.util.AttributeSet; |
| | | import com.runt.open.mvvm.R; |
| | | import com.runt.open.mvvm.util.DimensionUtils; |
| | | |
| | | /** |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2019-3-26. |
| | | */ |
| | | public class PasswordInputView extends androidx.appcompat.widget.AppCompatEditText { |
| | | private int textLength; |
| | | |
| | | private int borderColor; |
| | | |
| | | private float borderWidth; |
| | | |
| | | private float borderRadius; |
| | | |
| | | private int passwordLength; |
| | | |
| | | private int passwordColor; |
| | | |
| | | private float passwordWidth; |
| | | |
| | | private float passwordRadius; |
| | | |
| | | private Paint passwordPaint = new Paint(Paint.ANTI_ALIAS_FLAG); |
| | | |
| | | private Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); |
| | | |
| | | private final int defaultSplitLineWidth = 1; |
| | | |
| | | public PasswordInputView(Context context, AttributeSet attrs) { |
| | | |
| | | super(context, attrs); |
| | | |
| | | final Resources res = getResources(); |
| | | |
| | | final int defaultBorderColor = res.getColor(R.color.cut_off_line); |
| | | |
| | | final float defaultBorderWidth = res.getDimension(R.dimen.dimen_1px); |
| | | |
| | | final float defaultBorderRadius = res.getDimension(R.dimen.radios); |
| | | |
| | | final int defaultPasswordLength = 6; |
| | | |
| | | final int defaultPasswordColor = res.getColor(R.color.txt_normal); |
| | | |
| | | final float defaultPasswordWidth = res.getDimension(R.dimen.dimen_6); |
| | | |
| | | final float defaultPasswordRadius = res.getDimension(R.dimen.dimen_6); |
| | | |
| | | TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PasswordInputView, 0, 0); |
| | | |
| | | try { |
| | | |
| | | borderColor = a.getColor(R.styleable.PasswordInputView_borderColor, defaultBorderColor); |
| | | |
| | | borderWidth = a.getDimension(R.styleable.PasswordInputView_borderWidth, defaultBorderWidth); |
| | | |
| | | borderRadius = a.getDimension(R.styleable.PasswordInputView_borderRadius, defaultBorderRadius); |
| | | |
| | | passwordLength = a.getInt(R.styleable.PasswordInputView_passwordLength, defaultPasswordLength); |
| | | |
| | | passwordColor = a.getColor(R.styleable.PasswordInputView_passwordColor, defaultPasswordColor); |
| | | |
| | | passwordWidth = a.getDimension(R.styleable.PasswordInputView_passwordWidth, defaultPasswordWidth); |
| | | |
| | | passwordRadius = a.getDimension(R.styleable.PasswordInputView_passwordRadius, defaultPasswordRadius); |
| | | |
| | | } finally { |
| | | |
| | | a.recycle(); |
| | | |
| | | } |
| | | |
| | | borderPaint.setStrokeWidth(borderWidth); |
| | | borderPaint.setStyle(Paint.Style.STROKE); //空心的 |
| | | borderPaint.setStrokeWidth(DimensionUtils.convertDpToPixel(1,getContext()));//线宽 |
| | | borderPaint.setColor(borderColor); |
| | | |
| | | passwordPaint.setStrokeWidth(passwordWidth); |
| | | passwordPaint.setStyle(Paint.Style.FILL); |
| | | |
| | | passwordPaint.setColor(passwordColor); |
| | | setBackground(null); |
| | | setSingleLine(true); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | |
| | | protected void onDraw(Canvas canvas) { |
| | | |
| | | int width = getWidth(); |
| | | |
| | | int border = (int) DimensionUtils.convertDpToPixel(1,getContext()); |
| | | |
| | | |
| | | final float cha = (borderWidth - passwordWidth)/2; |
| | | final float xCha = (width/passwordLength-borderWidth)/2; |
| | | |
| | | for (int i = 0; i < passwordLength; i++) { |
| | | float x = width * i / passwordLength + xCha; |
| | | canvas.drawRoundRect(new RectF(x, border, x+borderWidth, border+borderWidth), 10, 10, borderPaint); |
| | | |
| | | } |
| | | |
| | | // 密码 |
| | | |
| | | float cx, cy = cha+passwordWidth/2 + border; |
| | | |
| | | for(int i = 0; i < textLength; i++) { |
| | | |
| | | cx = width * i / passwordLength + cha+passwordWidth/2 + xCha; |
| | | |
| | | canvas.drawCircle(cx, cy, passwordWidth, passwordPaint); |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | @Override |
| | | protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { |
| | | |
| | | super.onTextChanged(text, start, lengthBefore, lengthAfter); |
| | | |
| | | this.textLength = text.toString().length(); |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public int getBorderColor() { |
| | | |
| | | return borderColor; |
| | | |
| | | } |
| | | |
| | | public void setBorderColor(int borderColor) { |
| | | |
| | | this.borderColor = borderColor; |
| | | |
| | | borderPaint.setColor(borderColor); |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public float getBorderWidth() { |
| | | |
| | | return borderWidth; |
| | | |
| | | } |
| | | |
| | | public void setBorderWidth(float borderWidth) { |
| | | |
| | | this.borderWidth = borderWidth; |
| | | |
| | | borderPaint.setStrokeWidth(borderWidth); |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public float getBorderRadius() { |
| | | |
| | | return borderRadius; |
| | | |
| | | } |
| | | |
| | | public void setBorderRadius(float borderRadius) { |
| | | |
| | | this.borderRadius = borderRadius; |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public int getPasswordLength() { |
| | | |
| | | return passwordLength; |
| | | |
| | | } |
| | | |
| | | public void setPasswordLength(int passwordLength) { |
| | | |
| | | this.passwordLength = passwordLength; |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public int getPasswordColor() { |
| | | |
| | | return passwordColor; |
| | | |
| | | } |
| | | |
| | | public void setPasswordColor(int passwordColor) { |
| | | |
| | | this.passwordColor = passwordColor; |
| | | |
| | | passwordPaint.setColor(passwordColor); |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public float getPasswordWidth() { |
| | | |
| | | return passwordWidth; |
| | | |
| | | } |
| | | |
| | | public void setPasswordWidth(float passwordWidth) { |
| | | |
| | | this.passwordWidth = passwordWidth; |
| | | |
| | | passwordPaint.setStrokeWidth(passwordWidth); |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | |
| | | public float getPasswordRadius() { |
| | | |
| | | return passwordRadius; |
| | | |
| | | } |
| | | |
| | | public void setPasswordRadius(float passwordRadius) { |
| | | |
| | | this.passwordRadius = passwordRadius; |
| | | |
| | | invalidate(); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | xmlns:tools="http://schemas.android.com/tools" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" > |
| | | |
| | | <com.runt.open.mvvm.widgets.TitleBarView |
| | | android:id="@+id/title_bar" |
| | | style="@style/titlebar" |
| | | android:background="@color/transparent" |
| | | app:leftDrawable="@mipmap/icon_white_back" |
| | | app:leftTint="@color/black" |
| | | app:titleText="支付密码" |
| | | tools:ignore="MissingConstraints"/> |
| | | |
| | | <include |
| | | android:id="@+id/paypass_include" |
| | | layout="@layout/dialog_paypass" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | app:layout_constraintBottom_toBottomOf="parent" /> |
| | | |
| | | <View |
| | | app:layout_constraintTop_toBottomOf="@id/title_bar" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="0.5dp" |
| | | android:background="@color/gray_normal" /> |
| | | |
| | | |
| | | |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <androidx.constraintlayout.widget.ConstraintLayout |
| | | xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> |
| | | |
| | | <com.runt.open.mvvm.widgets.TitleBarView |
| | | android:id="@+id/title_bar" |
| | | style="@style/titlebar" |
| | | app:layout_constraintTop_toTopOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | app:leftDrawable="@mipmap/icon_white_back" |
| | | app:leftTint="@color/txt_normal" |
| | | app:titleTextColor="@color/txt_normal"/> |
| | | |
| | | <include |
| | | android:layout_width="match_parent" |
| | | android:layout_height="0dp" |
| | | layout="@layout/refresh_recycler" |
| | | app:layout_constraintBottom_toBottomOf="parent" |
| | | app:layout_constraintTop_toBottomOf="@id/title_bar" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" /> |
| | | <View |
| | | app:layout_constraintTop_toBottomOf="@id/title_bar" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/cut_off_line"/> |
| | | |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | xmlns:tools="http://schemas.android.com/tools" |
| | | android:background="@color/white" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:orientation="vertical"> |
| | | |
| | | <com.runt.open.mvvm.widgets.TitleBarView |
| | | android:id="@+id/title_bar" |
| | | style="@style/titlebar" |
| | | android:background="@color/transparent" |
| | | app:leftDrawable="@mipmap/icon_white_back" |
| | | app:leftTint="@color/black" |
| | | app:titleText="提现" |
| | | /> |
| | | <View |
| | | android:layout_width="match_parent" |
| | | android:layout_height="0.5dp" |
| | | android:background="@color/color_gray8" /> |
| | | |
| | | |
| | | <LinearLayout |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginTop="@dimen/default_margin_lr" |
| | | android:layout_marginLeft="@dimen/default_margin_lr" |
| | | android:layout_marginRight="@dimen/default_margin_lr" |
| | | android:orientation="vertical"> |
| | | |
| | | <TextView |
| | | android:id="@+id/txt_balance" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:text="当前金币数量1000个" /> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginTop="@dimen/default_margin_td" |
| | | android:gravity="center_vertical" |
| | | android:orientation="horizontal"> |
| | | |
| | | <EditText |
| | | android:id="@+id/edit" |
| | | android:layout_width="match_parent" |
| | | android:layout_weight="1" |
| | | android:layout_height="40dp" |
| | | android:background="@null" |
| | | android:inputType="number" |
| | | android:textSize="23sp" |
| | | android:gravity="right|center_vertical" |
| | | android:textColor="@color/txt_normal" |
| | | android:hint="输入提现数量" /> |
| | | <TextView |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="40dp" |
| | | android:textSize="23sp" |
| | | android:layout_marginLeft="5dp" |
| | | android:gravity="center_vertical" |
| | | android:text=",000 个" /> |
| | | </LinearLayout> |
| | | <TextView |
| | | android:id="@+id/txt_rmb" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginTop="@dimen/default_margin_td" |
| | | android:layout_gravity="right" |
| | | android:textSize="16sp" |
| | | android:text="提现¥0元" /> |
| | | |
| | | <TextView |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textSize="12sp" |
| | | android:textColor="@color/txt_enable" |
| | | android:layout_marginTop="@dimen/default_margin_td" |
| | | android:text="输入金币数量必须为1000的倍数,1000兑换为1元人民币。提现申请提交后,系统会在一个工作日内将金额汇入您所设置的支付宝账户中,请留意查收" |
| | | /> |
| | | |
| | | </LinearLayout> |
| | | |
| | | <LinearLayout |
| | | android:id="@+id/lin_ad" |
| | | android:layout_margin="15dp" |
| | | android:orientation="vertical" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" ></LinearLayout> |
| | | <Button |
| | | android:id="@+id/btn_submit" |
| | | style="@style/btn_normal" |
| | | android:layout_marginTop="20dp" |
| | | android:layout_marginBottom="50dp" |
| | | android:layout_marginLeft="@dimen/default_margin_lr" |
| | | android:layout_marginRight="@dimen/default_margin_lr" |
| | | android:text="提交申请"/> |
| | | |
| | | </LinearLayout> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <androidx.constraintlayout.widget.ConstraintLayout |
| | | xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | xmlns:tools="http://schemas.android.com/tools"> |
| | | |
| | | <TextView |
| | | android:id="@+id/txt_tip" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:text="" |
| | | android:gravity="center" |
| | | android:textSize="14sp" |
| | | android:layout_margin="@dimen/default_margin_lr" |
| | | app:layout_constraintTop_toTopOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" /> |
| | | |
| | | <com.runt.open.mvvm.widgets.PasswordInputView |
| | | android:id="@+id/password" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="50dp" |
| | | android:inputType="number" |
| | | android:background="@null" |
| | | android:layout_marginTop="36dp" |
| | | android:layout_marginLeft="21dp" |
| | | android:layout_marginRight="20dp" |
| | | android:focusable="true" |
| | | android:focusableInTouchMode="true" |
| | | android:maxLength="6" |
| | | app:passwordColor="@color/black" |
| | | app:passwordWidth="10dp" |
| | | app:passwordLength="6" |
| | | app:borderColor="@color/gray" |
| | | app:borderWidth="47dp" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | app:layout_constraintTop_toBottomOf="@id/txt_tip" /> |
| | | |
| | | <View |
| | | android:id="@+id/view" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | app:layout_constraintLeft_toLeftOf="@id/password" |
| | | app:layout_constraintRight_toRightOf="@id/password" |
| | | app:layout_constraintTop_toTopOf="@id/password" |
| | | app:layout_constraintBottom_toBottomOf="@id/password" /> |
| | | |
| | | <androidx.recyclerview.widget.RecyclerView |
| | | android:id="@+id/recycler_num" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginTop="16dp" |
| | | android:overScrollMode="never" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | app:layout_constraintTop_toBottomOf="@id/password" |
| | | app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" |
| | | app:spanCount="3" |
| | | tools:listitem="@layout/item_num" |
| | | tools:itemCount="12" /> |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <com.runt.open.mvvm.widgets.QuadrateLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| | | xmlns:tools="http://schemas.android.com/tools" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:gravity="center" |
| | | android:orientation="vertical" > |
| | | <TextView |
| | | android:id="@+id/text" |
| | | android:text="←" |
| | | style="@style/item_num" /> |
| | | |
| | | </com.runt.open.mvvm.widgets.QuadrateLinearLayout > |
| | |
| | | <dimen name="default_margin_lr">27dp</dimen> |
| | | <dimen name="default_margin_td">12dp</dimen> |
| | | |
| | | <dimen name="dimen_1px">1px</dimen> |
| | | <dimen name="dimen_6">6dp</dimen> |
| | | </resources> |
| | |
| | | <item name="android:paddingLeft">@dimen/default_margin_lr</item> |
| | | <item name="android:paddingRight">@dimen/default_margin_lr</item> |
| | | </style> |
| | | |
| | | <declare-styleable name="PasswordInputView"> |
| | | <attr name="borderColor" format="color" /> |
| | | <attr name="borderWidth" format="dimension" /> |
| | | <attr name="borderRadius" format="dimension" /> |
| | | <attr name="passwordLength" format="integer" /> |
| | | <attr name="passwordColor" format="color" /> |
| | | <attr name="passwordWidth" format="dimension" /> |
| | | <attr name="passwordRadius" format="dimension" /> |
| | | </declare-styleable> |
| | | |
| | | |
| | | <style name="item_num"> |
| | | <item name="android:layout_width">match_parent</item> |
| | | <item name="android:layout_height">match_parent</item> |
| | | <item name="android:gravity">center</item> |
| | | <item name="android:background">@drawable/bg_num</item> |
| | | <item name="android:textColor">@color/black</item> |
| | | <item name="android:textSize">44sp</item> |
| | | </style> |
| | | |
| | | </resources> |