12 files added
12 files modified
2 files deleted
| | |
| | | <action android:name="com.zfwl.merchant.activities.MainActivity" /> |
| | | </intent-filter> |
| | | </activity> |
| | | <activity android:name=".ui.login.RegisterLoginActivity" /> |
| | | <activity android:name=".ui.web.WebViewActivity" /> |
| | | </application> |
| | | |
| | | </manifest> |
| | |
| | | package com.runt.open.mvvm; |
| | | |
| | | import android.Manifest; |
| | | import android.content.Intent; |
| | | |
| | | import androidx.activity.result.ActivityResult; |
| | | import androidx.activity.result.ActivityResultCallback; |
| | | import androidx.activity.result.ActivityResultLauncher; |
| | | import androidx.activity.result.contract.ActivityResultContracts; |
| | | import androidx.navigation.NavController; |
| | | import androidx.navigation.Navigation; |
| | | import androidx.navigation.ui.NavigationUI; |
| | |
| | | import com.runt.open.mvvm.data.PhoneDevice; |
| | | import com.runt.open.mvvm.databinding.ActivityMainBinding; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.ui.login.RegisterLoginActivity; |
| | | import com.runt.open.mvvm.ui.main.MainViewModel; |
| | | |
| | | public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> { |
| | |
| | | NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main); |
| | | NavigationUI.setupWithNavController(binding.navView, navController); |
| | | checkPermission(); |
| | | ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { |
| | | @Override |
| | | public void onActivityResult(ActivityResult result) { |
| | | if(result.getResultCode() == RESULT_CODE_SUCESS){ |
| | | showToast("登录成功"); |
| | | } |
| | | } |
| | | }); |
| | | Intent intent = new Intent(mContext, RegisterLoginActivity.class); |
| | | launcher.launch(intent); |
| | | } |
| | | |
| | | private void showPermissionDialog(){ |
| | |
| | | import com.bytedance.sdk.openadsdk.TTAdConfig; |
| | | import com.bytedance.sdk.openadsdk.TTAdConstant; |
| | | import com.bytedance.sdk.openadsdk.TTAdSdk; |
| | | import com.runt.open.mvvm.listener.CrashHandler; |
| | | import com.runt.open.mvvm.util.MyLog; |
| | | import com.scwang.smart.refresh.footer.ClassicsFooter; |
| | | import com.scwang.smart.refresh.header.ClassicsHeader; |
| | |
| | | MyLog.e(TAG,"TTAdSdk fail"); |
| | | } |
| | | }); |
| | | CrashHandler crashHandler = CrashHandler.getInstance(); |
| | | crashHandler.init(getApplicationContext(), new CrashHandler.CrashListener() { |
| | | @Override |
| | | public void onCrash() { |
| | | for(Activity activity : activities){ |
| | | activity.finish(); |
| | | } |
| | | System.exit(0); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | import com.runt.open.mvvm.base.model.ViewModelFactory; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.util.PreferencesUtils; |
| | | |
| | | import java.io.File; |
| | | import java.lang.reflect.Method; |
| | | import java.lang.reflect.ParameterizedType; |
| | | import java.util.Set; |
| | | |
| | | import dmax.dialog.SpotsDialog; |
| | | |
| | |
| | | public final String[] LOCATION_PERMISSIONS = new String []{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}; |
| | | public final String[] CAMERA_PERMISSIONS = new String[]{ FILE_PERMISSIONS[0],FILE_PERMISSIONS[1], Manifest.permission.CAMERA}; |
| | | public final String[] CAMERA_RECORD_PERMISSIONS = new String[]{ FILE_PERMISSIONS[0],FILE_PERMISSIONS[1], Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO}; |
| | | |
| | | public static final String PARAMS_TITLE = "title"; |
| | | public static final String PARAMS_URL = "url"; |
| | | |
| | | public static final int RESULT_LOGIN = 100,RESULT_LOGIN_RECREATE = 103,RESULT_BIND = 101,RESULT_SENDEDFILES = 105,RESULT_DISSCONNECT = 104, |
| | | RESULT_UPDATEUSER = 115,RESULT_LOGOUT = 113, REQUEST_CODE_ACTIVITY = 333; |
| | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | public boolean getBooleanUserPrefrence(String key){ |
| | | return PreferencesUtils.getBoolean(this,key,false,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public boolean getBooleanProjectPrefrence(String key){ |
| | | return PreferencesUtils.getBoolean(this,key,false,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public String getStringUserPrefrence(String key){ |
| | | return PreferencesUtils.getString(this,key,"",PreferencesUtils.USER); |
| | | } |
| | | |
| | | public String getStringProjectPrefrence(String key){ |
| | | return PreferencesUtils.getString(this,key,"",PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public Integer getIntProjectPrefrence(String key){ |
| | | return PreferencesUtils.getInt(this,key,0,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public Long getLongProjectPrefrence(String key){ |
| | | return PreferencesUtils.getLong(this,key,0,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public float getFloatProjectPrefrence(String key){ |
| | | return PreferencesUtils.getFloat(this,key,0,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public Set getStringSetProjectPrefrence(String key){ |
| | | return PreferencesUtils.getStringSet(this,key,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public Integer getIntUserPrefrence(String key){ |
| | | return PreferencesUtils.getInt(this,key,0,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public Long getLongUserPrefrence(String key){ |
| | | return PreferencesUtils.getLong(this,key,0,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public float getFloatUserPrefrence(String key){ |
| | | return PreferencesUtils.getFloat(this,key,0,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public Set getStringSetUserPrefrence(String key){ |
| | | return PreferencesUtils.getStringSet(this,key,PreferencesUtils.USER); |
| | | } |
| | | |
| | | |
| | | public void putBooleanUserPrefrence(String key ,Boolean value){ |
| | | PreferencesUtils.putBoolean(this,key,value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void putBooleanProjectPrefrence(String key,Boolean value){ |
| | | PreferencesUtils.putBoolean(this,key,value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void putStringUserPrefrence(String key,String value){ |
| | | PreferencesUtils.putString(this,key,value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void putStringProjectPrefrence(String key,String value){ |
| | | PreferencesUtils.putString(this,key,value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void putIntProjectPrefrence(String key,int value){ |
| | | PreferencesUtils.putInt(this,key,value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void putLongProjectPrefrence(String key,long value){ |
| | | PreferencesUtils.putLong(this,key,value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void putFloatProjectPrefrence(String key,float value){ |
| | | PreferencesUtils.putFloat(this,key,value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void putStringSetProjectPrefrence(String key, Set value){ |
| | | PreferencesUtils.putStringSet(this,key,value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void putIntUserPrefrence(String key,int value){ |
| | | PreferencesUtils.putInt(this,key,value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void putLongUserPrefrence(String key,long value){ |
| | | PreferencesUtils.putLong(this,key,value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void putFloatUserPrefrence(String key,float value){ |
| | | PreferencesUtils.putFloat(this,key,value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void putStringSetUserPrefrence(String key, Set value){ |
| | | PreferencesUtils.putStringSet(this,key,value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | |
| | | public void removeUserKey(String key){ |
| | | PreferencesUtils.removeKey(this,key,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void removeProjectKey(String key){ |
| | | PreferencesUtils.removeKey(this,key,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | public void removeUserValue(String Value){ |
| | | PreferencesUtils.removeValue(this,Value,PreferencesUtils.USER); |
| | | } |
| | | |
| | | public void removeProjectValue(String Value){ |
| | | PreferencesUtils.removeValue(this,Value,PreferencesUtils.PROJECT); |
| | | } |
| | | |
| | | |
| | | public void clearProjectData(){ |
| | | PreferencesUtils.clearData(this,PreferencesUtils.PROJECT); |
| | | } |
| | | public void clearUserData(){ |
| | | PreferencesUtils.clearData(this,PreferencesUtils.USER); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.config; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/1/29. |
| | | */ |
| | | public class Configuration { |
| | | |
| | | public final static String KEY_CODE= "code"; |
| | | public static final String KEY_TOKEN = "token"; |
| | | public static final String KEY_USERNAME = "username"; |
| | | public static final String KEY_PHONE = "phone"; |
| | | public static final String KEY_USERPASS = "userpass"; |
| | | public final static String IS_LOGIN= "is_login"; |
| | | } |
| | |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class BaseApiResult<D extends Object> implements Serializable { |
| | | |
| | | public String msg; |
| | | public int code = 200; |
| | | public D data; |
New file |
| | |
| | | package com.runt.open.mvvm.data; |
| | | |
| | | import com.runt.open.mvvm.ui.login.UserBean; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/1/29. |
| | | */ |
| | | public class Results { |
| | | |
| | | public static class LoggedInUser extends BaseApiResult<UserBean> { } |
| | | |
| | | public static class StringApiResult extends BaseApiResult<String>{ } |
| | | |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.listener; |
| | | |
| | | import android.content.Context; |
| | | import android.content.pm.PackageInfo; |
| | | 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.lang.reflect.Field; |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of 崩溃监听 |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2021-4-13. |
| | | */ |
| | | |
| | | public class CrashHandler implements Thread.UncaughtExceptionHandler { |
| | | |
| | | public static final String TAG = "CrashHandler"; |
| | | |
| | | //系统默认的UncaughtException处理类 |
| | | private Thread.UncaughtExceptionHandler mDefaultHandler; |
| | | |
| | | CrashListener crashListener; |
| | | |
| | | //CrashHandler实例 |
| | | private static CrashHandler instance; |
| | | //程序的Context对象 |
| | | private Context mContext; |
| | | //用来存储设备信息和异常信息 |
| | | private Map<String, String> infos = new HashMap<String, String>(); |
| | | |
| | | //用于格式化日期,作为日志文件名的一部分 |
| | | private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | /** 保证只有一个CrashHandler实例 */ |
| | | private CrashHandler() {} |
| | | |
| | | /** 获取CrashHandler实例 ,单例模式 */ |
| | | public static CrashHandler getInstance() { |
| | | Log.i(TAG, "getInstance"); |
| | | if(instance == null) |
| | | instance = new CrashHandler(); |
| | | return instance; |
| | | } |
| | | |
| | | /** |
| | | * 初始化 |
| | | */ |
| | | public void init(Context context) { |
| | | Log.i(TAG, "init context:"+context); |
| | | mContext = context; |
| | | //获取系统默认的UncaughtException处理器 |
| | | mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); |
| | | //设置该CrashHandler为程序的默认处理器 |
| | | Thread.setDefaultUncaughtExceptionHandler(this); |
| | | } |
| | | |
| | | /** |
| | | * 初始化 |
| | | */ |
| | | public void init(Context context,CrashListener crashListener) { |
| | | Log.i(TAG, "init context:"+context); |
| | | mContext = context; |
| | | this.crashListener = crashListener; |
| | | //设置该CrashHandler为程序的默认处理器 |
| | | Thread.setDefaultUncaughtExceptionHandler(this); |
| | | } |
| | | |
| | | /** |
| | | * 当UncaughtException发生时会转入该函数来处理 |
| | | */ |
| | | @Override |
| | | public void uncaughtException(Thread thread, Throwable ex) { |
| | | Log.i(TAG, "uncaughtException Throwable:"+ex); |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. |
| | | * |
| | | * @param ex |
| | | * @return true:如果处理了该异常信息;否则返回false. |
| | | */ |
| | | private boolean handleException(Throwable ex) { |
| | | Log.i(TAG, "handleException Throwable:"+ex); |
| | | if (ex == null) { |
| | | return false; |
| | | } |
| | | //收集设备参数信息 |
| | | collectDeviceInfo(mContext); |
| | | |
| | | //使用Toast来显示异常信息 |
| | | new Thread() { |
| | | @Override |
| | | public void run() { |
| | | Looper.prepare(); |
| | | Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show(); |
| | | Looper.loop(); |
| | | } |
| | | }.start(); |
| | | //保存日志文件 |
| | | saveCatchInfo2File(ex); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 收集设备参数信息 |
| | | * @param ctx |
| | | */ |
| | | public void collectDeviceInfo(Context ctx) { |
| | | Log.i(TAG, "collectDeviceInfo Context:"+ctx); |
| | | try { |
| | | PackageManager pm = ctx.getPackageManager(); |
| | | PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); |
| | | if (pi != null) { |
| | | String versionName = pi.versionName == null ? "null" : pi.versionName; |
| | | String versionCode = pi.versionCode + ""; |
| | | infos.put("versionName", versionName); |
| | | infos.put("versionCode", versionCode); |
| | | } |
| | | } catch (PackageManager.NameNotFoundException e) { |
| | | Log.e(TAG, "an error occured when collect package info", e); |
| | | } |
| | | Field[] fields = Build.class.getDeclaredFields(); |
| | | for (Field field : fields) { |
| | | try { |
| | | field.setAccessible(true); |
| | | infos.put(field.getName(), field.get(null).toString()); |
| | | Log.d(TAG, field.getName() + " : " + field.get(null)); |
| | | } catch (Exception e) { |
| | | Log.e(TAG, "an error occured when collect crash info", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 保存错误信息到文件中 |
| | | * |
| | | * @param ex |
| | | * @return 返回文件名称,便于将文件传送到服务器 |
| | | */ |
| | | private String saveCatchInfo2File(Throwable ex) { |
| | | ex.printStackTrace(); |
| | | Log.i(TAG, "saveCatchInfo2File Throwable:"+ex); |
| | | |
| | | StringBuffer sb = new StringBuffer(); |
| | | for (Map.Entry<String, String> entry : infos.entrySet()) { |
| | | String key = entry.getKey(); |
| | | String value = entry.getValue(); |
| | | sb.append(key + "=" + value + "\n"); |
| | | } |
| | | |
| | | Writer writer = new StringWriter(); |
| | | PrintWriter printWriter = new PrintWriter(writer); |
| | | ex.printStackTrace(printWriter); |
| | | Throwable cause = ex.getCause(); |
| | | while (cause != null) { |
| | | cause.printStackTrace(printWriter); |
| | | cause = cause.getCause(); |
| | | } |
| | | printWriter.close(); |
| | | String result = writer.toString(); |
| | | sb.append(result); |
| | | try { |
| | | long timestamp = System.currentTimeMillis(); |
| | | String time = formatter.format(new Date()); |
| | | String fileName = "crash-" + time + "-" + timestamp + ".log"; |
| | | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { |
| | | String path = "/mnt/sdcard/crash/"; |
| | | File dir = new File(path); |
| | | if (!dir.exists()) { |
| | | dir.mkdirs(); |
| | | } |
| | | FileOutputStream fos = new FileOutputStream(path + fileName); |
| | | fos.write(sb.toString().getBytes()); |
| | | //发送给开发人员 |
| | | sendCrashLog2PM(path+fileName); |
| | | fos.close(); |
| | | } |
| | | return fileName; |
| | | } catch (Exception e) { |
| | | Log.e(TAG, "an error occured while writing file...", e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 将捕获的导致崩溃的错误信息发送给开发人员 |
| | | * |
| | | * 目前只将log日志保存在sdcard 和输出到LogCat中,并未发送给后台。 |
| | | */ |
| | | private void sendCrashLog2PM(String fileName){ |
| | | Log.i(TAG, "asendCrashLog2PM fileName:"+fileName); |
| | | if(!new File(fileName).exists()){ |
| | | Toast.makeText(mContext, "日志文件不存在!", Toast.LENGTH_SHORT).show(); |
| | | return; |
| | | } |
| | | FileInputStream fis = null; |
| | | BufferedReader reader = null; |
| | | String s = null; |
| | | try { |
| | | fis = new FileInputStream(fileName); |
| | | reader = new BufferedReader(new InputStreamReader(fis, "GBK")); |
| | | while(true){ |
| | | s = reader.readLine(); |
| | | if(s == null) break; |
| | | //由于目前尚未确定以何种方式发送,所以先打出log日志。 |
| | | //Log.i("info", s.toString()); |
| | | } |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | }finally{ // 关闭流 |
| | | try { |
| | | reader.close(); |
| | | fis.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static interface CrashListener{ |
| | | void onCrash(); |
| | | } |
| | | } |
| | |
| | | int position = logArrays.size() +2; |
| | | Response response; |
| | | try { |
| | | //request = encryptRequest(request);//加密 |
| | | request = encryptRequest(request);//加密 |
| | | response = chain.proceed(request); |
| | | logArrays.addAll(getResponseLog(response)); |
| | | Log.d(TAG,"hashcode:"+hashCode); |
| | |
| | | package com.runt.open.mvvm.retrofit.api; |
| | | |
| | | import com.runt.open.mvvm.ui.login.LoggedInUser; |
| | | import com.runt.open.mvvm.config.Configuration; |
| | | import com.runt.open.mvvm.data.Results; |
| | | |
| | | 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. |
| | | */ |
| | | public interface LoginApiCenter { |
| | | /** |
| | | * 密码登录 |
| | | * @param phone |
| | | * @param pass |
| | | * @return |
| | | */ |
| | | @FormUrlEncoded |
| | | @POST("login") |
| | | Observable<LoggedInUser> login(@Field("phone") String phone,@Field("pass") String pass); |
| | | Observable<Results.LoggedInUser> login(@Field(Configuration.KEY_PHONE) String phone, @Field("pass") String pass); |
| | | |
| | | /** |
| | | * 验证码登录 |
| | | * @param phone |
| | | * @param code |
| | | * @return |
| | | */ |
| | | @FormUrlEncoded |
| | | @POST("loginCode") |
| | | Observable<Results.LoggedInUser> loginByCode(@Field(Configuration.KEY_PHONE) String phone, @Field(Configuration.KEY_CODE) String code); |
| | | |
| | | |
| | | @FormUrlEncoded |
| | | @POST("login") |
| | | Observable<LoggedInUser> loginByCode(@Field("phone") String phone,@Field("code") String code); |
| | | @POST |
| | | Observable<Results.StringApiResult> getVerifyCode(@Url String url, @Field(Configuration.KEY_PHONE) String phone, @Field(Configuration.KEY_CODE) String code, @Field("time") String time); |
| | | |
| | | /** |
| | | * 重置密码 |
| | | * @param phone |
| | | * @param sms |
| | | * @param newPass |
| | | * @return |
| | | */ |
| | | @FormUrlEncoded |
| | | @POST("verifySMSReSetLoginPwd") |
| | | Observable<Results.StringApiResult> resetLoginPwd(@Field(Configuration.KEY_PHONE) String phone,@Field("sms") String sms, @Field("pass") String newPass); |
| | | |
| | | |
| | | /** |
| | | * 注册 |
| | | * @param phone |
| | | * @param sms |
| | | * @param pass |
| | | * @return |
| | | */ |
| | | @FormUrlEncoded |
| | | @POST("registerCustomer") |
| | | Observable<Results.StringApiResult> register(@Field(Configuration.KEY_USERNAME) String phone,@Field("sms") String sms, @Field("pass") String pass); |
| | | |
| | | |
| | | } |
| | |
| | | package com.runt.open.mvvm.retrofit.observable; |
| | | |
| | | import android.accounts.NetworkErrorException; |
| | | import android.util.Log; |
| | | |
| | | import androidx.annotation.NonNull; |
| | |
| | | Log.i("subscribe","onError"); |
| | | |
| | | try { |
| | | Log.e(TAG,this.getClass().getSimpleName()+" "+throwable.getMessage()); |
| | | Log.e(TAG,this.getClass().getSimpleName()+" mes:"+throwable.getMessage()); |
| | | Class<M> entityClass = (Class<M>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; |
| | | M t = entityClass.newInstance();//实例化一个泛型 |
| | | t.code = 410; |
| | | if( throwable instanceof SocketTimeoutException){ |
| | | t.msg = "服务请求超时,请稍候再试";//设置错误信息 |
| | | }else{ |
| | | }else if( throwable instanceof NetworkErrorException){ |
| | | t.msg = "网络连接不畅,请检查您的网络设置";//设置错误信息 |
| | | }else{ |
| | | t.msg = throwable.getMessage();//设置错误信息 |
| | | } |
| | | resultLive.setValue(t); |
| | | } catch (ClassCastException e) { |
New file |
| | |
| | | package com.runt.open.mvvm.ui.login; |
| | | |
| | | import android.os.CountDownTimer; |
| | | import android.widget.TextView; |
| | | |
| | | import com.runt.open.mvvm.R; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-2-23. |
| | | */ |
| | | public class CodeTimer extends CountDownTimer { |
| | | |
| | | TextView txtGetCode; |
| | | |
| | | public CodeTimer(long millisInFuture, long countDownInterval, TextView txtGetCode) { |
| | | super(millisInFuture, countDownInterval); |
| | | this.txtGetCode = txtGetCode; |
| | | } |
| | | |
| | | public void startUp(){ |
| | | txtGetCode.setEnabled(false); |
| | | txtGetCode.setTextColor(txtGetCode.getContext().getResources().getColor(R.color.txt_enable)); |
| | | start(); |
| | | } |
| | | |
| | | @Override |
| | | public void onTick(long l) { |
| | | txtGetCode.setText(String.format("(%s)", l/1000)); |
| | | } |
| | | |
| | | @Override |
| | | public void onFinish() { |
| | | txtGetCode.setEnabled(true); |
| | | txtGetCode.setTextColor(txtGetCode.getContext().getResources().getColor(R.color.link)); |
| | | txtGetCode.setText(txtGetCode.getContext().getResources().getString(R.string.get_verify_code)); |
| | | } |
| | | |
| | | } |
| | |
| | | import androidx.lifecycle.MutableLiveData; |
| | | |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | 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 java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | import io.reactivex.Observable; |
| | | |
| | |
| | | */ |
| | | public class LoginViewModel extends BaseViewModel { |
| | | |
| | | MutableLiveData<LoggedInUser> loginResult = new MutableLiveData<>(); |
| | | LoginApiCenter loginApi; |
| | | |
| | | public MutableLiveData<LoggedInUser> getLoginResult() { |
| | | public LoginViewModel() { |
| | | loginApi = RetrofitUtils.getInstance().getRetrofit(LoginApiCenter.class); |
| | | } |
| | | |
| | | MutableLiveData<Results.LoggedInUser> loginResult = new MutableLiveData<>(); |
| | | MutableLiveData<Results.StringApiResult> verifyResult = new MutableLiveData<>(); |
| | | MutableLiveData<Results.StringApiResult> resetResult = new MutableLiveData<>(); |
| | | MutableLiveData<Results.StringApiResult> registerResult = new MutableLiveData<>(); |
| | | |
| | | public MutableLiveData<Results.LoggedInUser> getLoginResult() { |
| | | return loginResult; |
| | | } |
| | | |
| | | public void login(String username, String password) { |
| | | // can be launched in a separate asynchronous job |
| | | final Observable<LoggedInUser> userObservable = RetrofitUtils.getInstance().getRetrofit(LoginApiCenter.class).login(username, password); |
| | | httpObserverOn(userObservable,new HttpObserver<LoggedInUser>(loginResult){}); |
| | | public MutableLiveData<Results.StringApiResult> getVerifyResult() { |
| | | return verifyResult; |
| | | } |
| | | |
| | | /** |
| | | * 密码登录 |
| | | * @param username |
| | | * @param password |
| | | */ |
| | | public void login(String username, String password) { |
| | | // can be launched in a separate asynchronous job |
| | | final Observable<Results.LoggedInUser> userObservable = loginApi.login(username, password); |
| | | httpObserverOnLoading(userObservable,new HttpObserver<Results.LoggedInUser>(loginResult){}); |
| | | } |
| | | |
| | | /** |
| | | * 验证码登录 |
| | | * @param phone |
| | | * @param code |
| | | */ |
| | | public void loginByCode(String phone,String code){ |
| | | httpObserverOnLoading(loginApi.loginByCode(phone,code), |
| | | new HttpObserver<Results.LoggedInUser>(loginResult){}); |
| | | } |
| | | |
| | | /** |
| | | * 重置密码 |
| | | * @param phone |
| | | * @param sms |
| | | * @param pass |
| | | */ |
| | | public void resetPwd(String phone,String sms,String pass){ |
| | | httpObserverOnLoading(loginApi.resetLoginPwd(phone, sms, pass), new HttpObserver<Results.StringApiResult>(resetResult) {}); |
| | | } |
| | | |
| | | /** |
| | | * 注册 |
| | | * @param phone |
| | | * @param sms |
| | | * @param pass |
| | | */ |
| | | public void register(String phone,String sms,String pass){ |
| | | httpObserverOnLoading(loginApi.register(phone, sms, pass), new HttpObserver<Results.StringApiResult>(resetResult) {}); |
| | | } |
| | | |
| | | /** |
| | | * 注册密码 |
| | | * @param phone |
| | | */ |
| | | public void getRegisterSMS(String phone){ |
| | | getVerifyCode("getRegisterSMS",phone); |
| | | } |
| | | |
| | | /** |
| | | * 忘记密码 |
| | | * @param phone |
| | | */ |
| | | public void getForgetSMS(String phone){ |
| | | getVerifyCode("getForgetSMS",phone); |
| | | } |
| | | |
| | | /** |
| | | * 登录验证码 |
| | | * @param phone |
| | | */ |
| | | public void getLoginSMS(String phone){ |
| | | 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.StringApiResult>(verifyResult){}); |
| | | } |
| | | |
| | | /** |
| | | * 随机字符串 |
| | | * @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(); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.login; |
| | | |
| | | 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.databinding.ActivityLoginBinding; |
| | | 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; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/1/29. |
| | | */ |
| | | public class RegisterLoginActivity extends BaseActivity<ActivityLoginBinding,LoginViewModel> { |
| | | final String VERIFY_CODE = "verify_code"; |
| | | final String TAG = "RegisterLoginActivity"; |
| | | int type = 0;//0 登录,1忘记密码,2注册,-1短信登录 |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | binding.txtGetVerify.setOnClickListener(onclick); |
| | | binding.txtForgot.setOnClickListener(onclick); |
| | | binding.txtLogin.setOnClickListener(onclick); |
| | | binding.txtRegister.setOnClickListener(onclick); |
| | | binding.txtPrivacy.setOnClickListener(onclick); |
| | | long getTime = getLongProjectPrefrence(VERIFY_CODE); |
| | | long cha = new Date().getTime() - getTime; |
| | | if(cha <1000*60){ |
| | | CodeTimer codeTimer = new CodeTimer(cha, 1000, binding.txtGetVerify); |
| | | codeTimer.startUp(); |
| | | } |
| | | changeView(); |
| | | binding.editPhone.setText(getStringProjectPrefrence(Configuration.KEY_USERNAME)); |
| | | viewModel.getVerifyResult().observe(this, stringApiResult -> { |
| | | if(stringApiResult.code == 200){ |
| | | |
| | | }else{ |
| | | showToast(stringApiResult.msg); |
| | | } |
| | | }); |
| | | viewModel.getLoginResult().observe(this,loggedInUser -> { |
| | | if(loggedInUser.code == 200){ |
| | | putBooleanProjectPrefrence(Configuration.IS_LOGIN,true); |
| | | putStringProjectPrefrence(Configuration.KEY_USERNAME,binding.editPhone.getText().toString()); |
| | | |
| | | UserBean user = new Gson().fromJson(new Gson().toJson(loggedInUser.data) ,UserBean.class); |
| | | UserBean.setUser(user); |
| | | putStringProjectPrefrence(Configuration.KEY_TOKEN, user.getToken()); |
| | | MyLog.i("registerlogin",user.toString()); |
| | | showToast(R.string.login_success); |
| | | setResult(RESULT_CODE_SUCESS); |
| | | finish(); |
| | | }else{ |
| | | showToast(loggedInUser.msg); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | CustomClickListener onclick = new CustomClickListener() { |
| | | @Override |
| | | protected void onSingleClick(View view) { |
| | | switch (view.getId()){ |
| | | case R.id.button: |
| | | submit(); |
| | | break; |
| | | case R.id.txt_get_verify: |
| | | |
| | | String phone = binding.editPhone.getText().toString(); |
| | | if(!verifyPhone(phone)){//验证手机 |
| | | return; |
| | | } |
| | | if(type==2){//获取注册验证码 |
| | | viewModel.getRegisterSMS(phone); |
| | | }else if(type ==1){ |
| | | viewModel.getForgetSMS( phone); |
| | | }else if(type == -1){ |
| | | viewModel.getLoginSMS( phone); |
| | | } |
| | | break; |
| | | case R.id.txt_privacy: |
| | | startActivity(new Intent(mContext, WebViewActivity.class).putExtra(PARAMS_URL,"http://www.hefan.space/privacyPolicy.html").putExtra(PARAMS_TITLE,"隐私政策")); |
| | | break; |
| | | case R.id.txt_register: |
| | | type = 2; |
| | | changeView(); |
| | | break; |
| | | case R.id.txt_forgot: |
| | | type = 1; |
| | | changeView(); |
| | | break; |
| | | case R.id.txt_login: |
| | | if(type != 0 ){ |
| | | type = 0; |
| | | }else { |
| | | type = -1; |
| | | } |
| | | changeView(); |
| | | break; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | |
| | | /** |
| | | * 修改页面布局 |
| | | */ |
| | | private void changeView(){ |
| | | binding.button.setEnabled(true); |
| | | binding.txtRegister.setVisibility(View.VISIBLE); |
| | | binding.checkbox.setVisibility(View.GONE); |
| | | binding.txtPrivacy.setVisibility(View.GONE); |
| | | switch (type){ |
| | | case -1://短信登录 |
| | | binding.editVerifyCode.setVisibility(View.VISIBLE); |
| | | binding.txtGetVerify.setVisibility(View.VISIBLE); |
| | | binding.editPass.setVisibility(View.GONE); |
| | | binding.editPassRepeat.setVisibility(View.GONE); |
| | | binding.txtForgot.setVisibility(View.VISIBLE); |
| | | binding.txtLogin.setText(getResources().getString(R.string.login)); |
| | | binding.button.setText(getResources().getString(R.string.login)); |
| | | binding.checkbox.setVisibility(View.VISIBLE); |
| | | binding.txtPrivacy.setVisibility(View.VISIBLE); |
| | | break; |
| | | case 0://登录 |
| | | binding.editVerifyCode.setVisibility(View.GONE); |
| | | binding.txtGetVerify.setVisibility(View.GONE); |
| | | binding.editPass.setVisibility(View.VISIBLE); |
| | | binding.editPassRepeat.setVisibility(View.GONE); |
| | | binding.txtForgot.setVisibility(View.VISIBLE); |
| | | binding.txtLogin.setText(getResources().getString(R.string.msg_login)); |
| | | binding.button.setText(getResources().getString(R.string.login)); |
| | | break; |
| | | case 1://忘记密码 |
| | | binding.txtForgot.setVisibility(View.INVISIBLE); |
| | | binding.editVerifyCode.setVisibility(View.VISIBLE); |
| | | binding.txtGetVerify.setVisibility(View.VISIBLE); |
| | | binding.editPass.setVisibility(View.VISIBLE); |
| | | binding.editPassRepeat.setVisibility(View.VISIBLE); |
| | | binding.txtLogin.setText(getResources().getString(R.string.login)); |
| | | binding.button.setText(getResources().getString(R.string.str_confirm)); |
| | | break; |
| | | case 2://注册 |
| | | binding.checkbox.setVisibility(View.VISIBLE); |
| | | binding.txtPrivacy.setVisibility(View.VISIBLE); |
| | | binding.txtRegister.setVisibility(View.INVISIBLE); |
| | | binding.editVerifyCode.setVisibility(View.VISIBLE); |
| | | binding.txtGetVerify.setVisibility(View.VISIBLE); |
| | | binding.editPass.setVisibility(View.VISIBLE); |
| | | binding.editPassRepeat.setVisibility(View.VISIBLE); |
| | | binding.txtLogin.setText(getResources().getString(R.string.login)); |
| | | binding.button.setText(getResources().getString(R.string.register)); |
| | | break; |
| | | } |
| | | clearText(binding.editPassRepeat,binding.editPass,binding.editPhone,binding.editVerifyCode); |
| | | } |
| | | |
| | | private void clearText(EditText... editTextes){ |
| | | for(EditText editText :editTextes) { |
| | | editText.setText(""); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 提交数据 |
| | | */ |
| | | public void submit(){ |
| | | String phone = binding.editPhone.getText().toString(); |
| | | String pass = binding.editPass .getText().toString(); |
| | | String veriCode = binding.editVerifyCode.getText().toString(); |
| | | String invite = binding.editPassRepeat.getText().toString(); |
| | | if(!verifyPhone(phone)){//验证手机 |
| | | return; |
| | | } |
| | | switch (type){ |
| | | case -1://短信登录 |
| | | if(veriCode.length() == 0){//验证码 |
| | | showToast(R.string.input_verify_code); |
| | | return; |
| | | } |
| | | if(!binding.checkbox.isChecked()){ |
| | | showToast("请阅读并勾选《隐私条款》"); |
| | | return; |
| | | } |
| | | viewModel.loginByCode(phone,veriCode); |
| | | break; |
| | | case 0: |
| | | if(!verifyPassWord(pass)){//验证密码 |
| | | return; |
| | | } |
| | | viewModel.login(phone,pass); |
| | | break; |
| | | case 1: |
| | | if(!verifyPassWord(pass)){//验证密码 |
| | | return; |
| | | } |
| | | if(veriCode.length() == 0){//验证码 |
| | | showToast(R.string.input_verify_code); |
| | | return; |
| | | } |
| | | |
| | | //新密码 |
| | | if(invite.length() == 0){ |
| | | showToast(R.string.input_pass); |
| | | return; |
| | | } else if(!invite.equals(pass)){ |
| | | showToast(R.string.str_new_verify_failed); |
| | | return; |
| | | } |
| | | viewModel.resetPwd(phone,veriCode,pass); |
| | | break; |
| | | case 2://注册 |
| | | if(!verifyPassWord(pass)){//验证密码 |
| | | return; |
| | | } |
| | | if(veriCode.length() == 0){//验证码 |
| | | showToast(R.string.input_verify_code); |
| | | return; |
| | | } |
| | | if(!binding.checkbox.isChecked()){ |
| | | showToast("请阅读并勾选《隐私条款》"); |
| | | return; |
| | | } |
| | | viewModel.register(phone,veriCode,pass); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 验证密码 |
| | | * @param pass |
| | | * @return |
| | | */ |
| | | public boolean verifyPassWord(String pass){ |
| | | |
| | | if(pass.length() == 0){ |
| | | showToast(R.string.input_pass); |
| | | return false; |
| | | } else if(!verifyPass(pass)){ |
| | | showToast(R.string.str_pass_format_failed); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 验证手机号 |
| | | * @param phone |
| | | * @return |
| | | */ |
| | | public boolean verifyPhone(String phone ){ |
| | | |
| | | if(phone.length() == 0){ |
| | | showToast(R.string.input_phone); |
| | | return false; |
| | | }else if(phone.length()<5 || !PhoneUtil.isMobileNO(phone)){ |
| | | showToast(R.string.str_phone_format_failed); |
| | | return false; |
| | | } |
| | | return true; |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 验证密码 |
| | | * @param pass |
| | | * @return |
| | | */ |
| | | public boolean verifyPass(String pass){ |
| | | return AlgorithmUtils.pwdLevel(pass)>1 && pass.length()>=6 && pass.length() <=12; |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.web; |
| | | |
| | | import android.os.Handler; |
| | | import android.view.View; |
| | | import android.view.ViewTreeObserver; |
| | | import android.view.animation.LayoutAnimationController; |
| | | import android.webkit.WebChromeClient; |
| | | import android.webkit.WebSettings; |
| | | import android.webkit.WebView; |
| | | import android.webkit.WebViewClient; |
| | | import android.widget.Toast; |
| | | |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | import com.runt.open.mvvm.databinding.ActivityWebBinding; |
| | | import com.runt.open.mvvm.util.MyAnimations; |
| | | import com.runt.open.mvvm.util.MyLog; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-9-16. |
| | | */ |
| | | public class WebViewActivity extends BaseActivity<ActivityWebBinding, BaseViewModel> { |
| | | |
| | | private String url; |
| | | private int linProgressWidth; |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | url = getIntent().getSerializableExtra(PARAMS_URL)+""; |
| | | setTitle(getIntent().getSerializableExtra(PARAMS_TITLE)+""); |
| | | initCompent(); |
| | | } |
| | | |
| | | |
| | | int count = 100; |
| | | int index = 100; |
| | | private void initCompent(){ |
| | | binding.browser.getSettings().setJavaScriptEnabled(true); |
| | | binding.browser.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); |
| | | //跳转至拼接好的地址 |
| | | //mBaseHandler.sendMessage(msg);//http://192.168.5.156:8080/MyFinance/gd16/1.html |
| | | binding.browser.loadUrl(url); |
| | | binding.browser.setWebViewClient(new myWebViewClient()); |
| | | binding.browser.setWebChromeClient(new WebChromeClient(){ |
| | | |
| | | @Override |
| | | public void onProgressChanged(WebView view,final int newProgress) { |
| | | MyLog.i("onProgressChanged","--newProgress:--"+newProgress); |
| | | MyLog.i("onProgressChanged","--binding.viewProgressbar:--"+binding.viewProgressbar.getWidth()); |
| | | final LayoutAnimationController.AnimationParameters animation= new LayoutAnimationController.AnimationParameters(); //得到一个LayoutAnimationController对象; |
| | | animation.index =index++ ; |
| | | animation.count = count++ ; |
| | | if (newProgress == 100) { |
| | | MyAnimations.hideAnimaInSitu(binding.linProgressbar); |
| | | MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),0,0,0,binding.viewProgressbar); |
| | | new Handler().postDelayed(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | binding.linProgressbar.setVisibility(View.GONE); |
| | | } |
| | | },MyAnimations.ANIMA_TIME); |
| | | } else { |
| | | |
| | | if (View.VISIBLE != binding.linProgressbar.getVisibility()) { |
| | | MyAnimations.showAnimaInSitu(binding.linProgressbar); |
| | | if(linProgressWidth==0){ |
| | | final ViewTreeObserver vto = binding.linProgressbar.getViewTreeObserver(); |
| | | vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { |
| | | public boolean onPreDraw() { |
| | | linProgressWidth = binding.linProgressbar.getMeasuredWidth(); |
| | | binding.viewProgressbar.setTranslationX(0-linProgressWidth); |
| | | binding.linProgressbar.getViewTreeObserver().removeOnPreDrawListener(this); |
| | | return true; |
| | | } |
| | | }); |
| | | }else{ |
| | | binding.viewProgressbar.setTranslationX(0-linProgressWidth); |
| | | } |
| | | |
| | | } |
| | | if(linProgressWidth!=0){ |
| | | MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),0-linProgressWidth+linProgressWidth/100*newProgress,0,0,binding.viewProgressbar,MyAnimations.ANIMA_TIME*3); |
| | | new Handler().postDelayed(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),binding.viewProgressbar.getTranslationX()+300,0,0,binding.viewProgressbar,MyAnimations.ANIMA_TIME*10); |
| | | } |
| | | },MyAnimations.ANIMA_TIME*3); |
| | | } |
| | | |
| | | } |
| | | super.onProgressChanged(view, newProgress); |
| | | } |
| | | |
| | | }); |
| | | |
| | | binding.browser.getSettings().setSavePassword(false); |
| | | //Toast.makeText(mContext,"进入浏览器",Toast.LENGTH_SHORT).show(); |
| | | String Scale = String.valueOf(binding.browser.getScale()); |
| | | MyLog.i("Runt","--Scale:--"+Scale); |
| | | int screenDensity=getResources().getDisplayMetrics().densityDpi; |
| | | MyLog.i("Runt", "--screenDensity:--"+String.valueOf(screenDensity)); //60-160-240 |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private class myWebViewClient extends WebViewClient { |
| | | |
| | | /** |
| | | * 每加载一张图片资源执行一次 |
| | | */ |
| | | @Override |
| | | public void onLoadResource(WebView view, String url) { |
| | | // TODO Auto-generated method stub |
| | | super.onLoadResource(view, url); |
| | | //MyLog.i("WebView", "onLoadResource "+url); |
| | | } |
| | | |
| | | @Override |
| | | public void onPageFinished(WebView view, String url) { |
| | | hideProgressBar(); |
| | | //MyLog.i("WebView", "onPageFinished "+url); |
| | | } |
| | | |
| | | /** |
| | | * 获取页面跳转的链接 |
| | | */ |
| | | @Override |
| | | public boolean shouldOverrideUrlLoading(WebView view, String url) { |
| | | // TODO Auto-generated method stub |
| | | //MyLog.i("UrlLoading", "UrlLoading 正在跳转页面"+url); |
| | | view.loadUrl(url); |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public void onReceivedError(WebView view, int errorCode, |
| | | String description, String failingUrl) { |
| | | // TODO Auto-generated method stub |
| | | super.onReceivedError(view, errorCode, description, failingUrl); |
| | | Toast.makeText(mContext, "加载失败,请稍候再试", Toast.LENGTH_SHORT).show(); |
| | | hideProgressBar(); |
| | | } |
| | | } |
| | | |
| | | private void hideProgressBar(){ |
| | | MyAnimations.hideAnimaInSitu(binding.linProgressbar); |
| | | MyAnimations.makeViewMove(binding.viewProgressbar.getTranslationX(),0,0,0,binding.viewProgressbar); |
| | | new Handler().postDelayed(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | binding.linProgressbar.setVisibility(View.GONE); |
| | | } |
| | | },MyAnimations.ANIMA_TIME*2); |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.util; |
| | | |
| | | import android.animation.Animator; |
| | | import android.animation.AnimatorInflater; |
| | | import android.animation.ObjectAnimator; |
| | | import android.annotation.SuppressLint; |
| | | import android.content.Context; |
| | | import android.os.Handler; |
| | | import android.os.Message; |
| | | import android.util.Log; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.view.animation.Animation; |
| | | import android.view.animation.TranslateAnimation; |
| | | import android.widget.RelativeLayout; |
| | | |
| | | import com.facebook.rebound.SimpleSpringListener; |
| | | import com.facebook.rebound.Spring; |
| | | import com.facebook.rebound.SpringConfig; |
| | | import com.facebook.rebound.SpringSystem; |
| | | import com.runt.open.mvvm.R; |
| | | |
| | | /** |
| | | * Created by Administrator on 2017/11/30. |
| | | */ |
| | | public class MyAnimations { |
| | | |
| | | public static final int ANIMA_TIME = 300; |
| | | public static final float MOVE_SPACE = 1; |
| | | public static final float SITU = 0; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 移动控件 |
| | | * @param x x初始位置 |
| | | * @param distanceX x移动的距离 |
| | | * @param y y初始位置 |
| | | * @param distanceY y移动的距离 |
| | | * @param view |
| | | */ |
| | | public static void makeViewMove(float x ,float distanceX , float y ,float distanceY, View view){ |
| | | setAnimator("translationY", y, distanceY,view,ANIMA_TIME); |
| | | setAnimator("translationX", x, distanceX,view,ANIMA_TIME); |
| | | } |
| | | /** |
| | | * 移动控件 |
| | | * @param x x初始位置 |
| | | * @param distanceX x移动的距离 |
| | | * @param y y初始位置 |
| | | * @param distanceY y移动的距离 |
| | | * @param view |
| | | */ |
| | | public static void makeViewMove(float x , float distanceX , float y , float distanceY, View view, int animTime){ |
| | | setAnimator("translationY", y, distanceY,view,animTime); |
| | | setAnimator("translationX", x, distanceX,view,animTime); |
| | | } |
| | | |
| | | private static void setAnimator(String attribute, float from, float to, View view, int animTime){ |
| | | ObjectAnimator.ofFloat(view, attribute, from, to).setDuration(animTime).start(); |
| | | } |
| | | public static void setLayoutMargin(View view, int left, int top, int right, int bottom) |
| | | { |
| | | //克隆view的width、height、margin的值生成margin对象 |
| | | ViewGroup.MarginLayoutParams margin=new ViewGroup.MarginLayoutParams(view.getLayoutParams()); |
| | | //设置新的边距 |
| | | margin.setMargins(left, top, right, bottom); |
| | | //把新的边距生成layoutParams对象 |
| | | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(margin); |
| | | //设制view的新的位置 |
| | | view.setLayoutParams(layoutParams); |
| | | } |
| | | /** |
| | | * 原地不动 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeInSitu(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 从顶部显示 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeInFromTop(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,0-MOVE_SPACE,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | /** |
| | | * 从底部显示 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeInFromBottom(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,MOVE_SPACE,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | /** |
| | | * 从左侧显示 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeInFromLeft(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0-MOVE_SPACE,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | /** |
| | | * 从右侧显示 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeInFromRight(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,MOVE_SPACE,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 向上隐藏 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeOutToTop(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,0-MOVE_SPACE);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | /** |
| | | * 向左隐藏 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeOutToLeft(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,0-MOVE_SPACE,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | /** |
| | | * 向右隐藏 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeOutToRight(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,MOVE_SPACE,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,SITU);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | /** |
| | | * 向下隐藏 |
| | | * @return |
| | | */ |
| | | private static TranslateAnimation makeOutToButtom(){ |
| | | TranslateAnimation mAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,SITU,//大于0 则从右向当前位置移动,反之则从左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从当前位置向右移动,反之则向左 |
| | | Animation.RELATIVE_TO_SELF,SITU,//大于0 则从下方向当前位置,反之则从上方 |
| | | Animation.RELATIVE_TO_SELF,MOVE_SPACE);//大于0从当前位置向下移动,反之则向上方 |
| | | mAction.setDuration(ANIMA_TIME); |
| | | return mAction; |
| | | } |
| | | |
| | | |
| | | |
| | | /*** |
| | | * 动画显示 从右向左左显示 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void showAnimaRightToLeft(View view) { |
| | | view.setVisibility(View.VISIBLE); |
| | | Animation mAni; |
| | | mAni = makeInFromRight(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | |
| | | /*** |
| | | * 动画显示 从右向左左显示 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void showAnimaLeftToRight(View view) { |
| | | view.setVisibility(View.VISIBLE); |
| | | Animation mAni; |
| | | mAni = makeInFromLeft(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | /** |
| | | * 动画隐藏 从下往上 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void hideAnimaBottomToTop(View view) { |
| | | view.setVisibility(View.INVISIBLE); |
| | | Animation mAni; |
| | | mAni = makeOutToTop(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | /** |
| | | * 动画隐藏 从左往右 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void hideAnimaLeftToRight(View view) { |
| | | view.setVisibility(View.INVISIBLE); |
| | | Animation mAni; |
| | | mAni = makeOutToRight(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | /** |
| | | * 动画隐藏 从右往左 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void hideAnimaRightToLeft(View view) { |
| | | view.setVisibility(View.INVISIBLE); |
| | | Animation mAni; |
| | | mAni = makeOutToLeft(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 动画隐藏 原地 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void hideAnimaInSitu(View view) { |
| | | view.setVisibility(View.INVISIBLE); |
| | | Animation mAni; |
| | | mAni = makeInSitu(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 动画显示 原地 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void showAnimaInSitu(View view) { |
| | | view.setVisibility(View.VISIBLE); |
| | | Animation mAni; |
| | | mAni = makeInSitu(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 动画显示 从上往下走 |
| | | * |
| | | * @param view |
| | | */ |
| | | public static void showAnimaTopToBottom(View view) { |
| | | view.setVisibility(View.VISIBLE); |
| | | Animation mAni; |
| | | mAni = makeInFromTop(); |
| | | mAni.setDuration(ANIMA_TIME); |
| | | view.setAnimation(mAni); |
| | | } |
| | | |
| | | /** |
| | | * 冒泡式显示控件 |
| | | * @param view |
| | | */ |
| | | public static void showReBound(final View view){ |
| | | Log.i("","showReBound view:"+view); |
| | | view.setVisibility(View.GONE); |
| | | showAnimaInSitu(view); |
| | | SpringSystem springSystem = SpringSystem.create(); |
| | | final Spring spring = springSystem.createSpring(); |
| | | spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(100,7));//qcTension拉力和qcFriction摩擦力参数 |
| | | spring.addListener(new SimpleSpringListener() { |
| | | @Override |
| | | public void onSpringUpdate(Spring spring) { |
| | | float value = (float) spring.getCurrentValue(); |
| | | float scale = value; |
| | | view.setScaleX(scale); |
| | | view.setScaleY(scale); |
| | | } |
| | | }); |
| | | spring.setEndValue(1);//控件拉伸收缩的倍率 |
| | | } |
| | | |
| | | /** |
| | | * 冒泡式放大控件 |
| | | * @param view |
| | | */ |
| | | public static void showReBoundBig(final View view){ |
| | | Log.i("","showReBound view:"+view); |
| | | view.setVisibility(View.GONE); |
| | | showAnimaInSitu(view); |
| | | SpringSystem springSystem = SpringSystem.create(); |
| | | final Spring spring = springSystem.createSpring(); |
| | | spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(100,7));//qcTension拉力和qcFriction摩擦力参数 |
| | | spring.addListener(new SimpleSpringListener() { |
| | | @Override |
| | | public void onSpringUpdate(Spring spring) { |
| | | float value = (float) spring.getCurrentValue(); |
| | | float scale = value; |
| | | view.setScaleX(scale); |
| | | view.setScaleY(scale); |
| | | } |
| | | }); |
| | | spring.setEndValue(3);//控件拉伸收缩的倍率 |
| | | } |
| | | |
| | | /** |
| | | * 收缩式 隐藏 |
| | | * @param view |
| | | * @param context |
| | | */ |
| | | public static void hideReBound(final View view, final Context context){ |
| | | /*showReBound(view); |
| | | @SuppressLint("ResourceType") Animator animator = AnimatorInflater.loadAnimator(context, R.anim.anima_make_none); |
| | | animator.setTarget(view); |
| | | animator.start();*/ |
| | | |
| | | final Handler handler = new Handler() { |
| | | |
| | | @Override |
| | | public void handleMessage(Message msg) { |
| | | super.handleMessage(msg); |
| | | float value = (float) msg.obj; |
| | | if(value>2){ |
| | | @SuppressLint("ResourceType") Animator animator = AnimatorInflater.loadAnimator(context, R.anim.anima_make_none); |
| | | animator.setTarget(view); |
| | | animator.start(); |
| | | animator.addListener(new Animator.AnimatorListener() { |
| | | @Override |
| | | public void onAnimationEnd(Animator animation, boolean isReverse) { |
| | | MyLog.i("hideReBound","onAnimationEnd "+animation+" "+isReverse); |
| | | view.setVisibility(View.GONE); |
| | | } |
| | | @Override |
| | | public void onAnimationStart(Animator animation, boolean isReverse) {} |
| | | @Override |
| | | public void onAnimationStart(Animator animator) { |
| | | } |
| | | @Override |
| | | public void onAnimationEnd(Animator animator) { |
| | | MyLog.i("hideReBound","onAnimationEnd "+animator); |
| | | view.setVisibility(View.GONE); |
| | | } |
| | | @Override |
| | | public void onAnimationCancel(Animator animator) {} |
| | | @Override |
| | | public void onAnimationRepeat(Animator animator) { } |
| | | }); |
| | | hideAnimaInSitu(view); |
| | | }else { |
| | | value = 1f + (value); |
| | | view.setScaleX(value); |
| | | view.setScaleY(value); |
| | | } |
| | | } |
| | | }; |
| | | new Thread(){ |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | int sleep = 10; |
| | | for(int i =0 ; i < 100 ; i+=sleep){ |
| | | sleep(sleep); |
| | | Message msg = new Message(); |
| | | msg.obj = (float)i/100/3; |
| | | handler.sendMessage(msg); |
| | | } |
| | | |
| | | Message msg = new Message(); |
| | | msg.obj = 3f; |
| | | handler.sendMessage(msg); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }.start(); |
| | | } |
| | | |
| | | static int time = 0; |
| | | public static void animaScale(final Context context, final View view, final float x, final float y){ |
| | | |
| | | final Handler handler = new Handler() { |
| | | |
| | | @Override |
| | | public void handleMessage(Message msg) { |
| | | super.handleMessage(msg); |
| | | float value = (float) msg.obj; |
| | | value = 1f + (value); |
| | | view.setScaleX(value); |
| | | view.setScaleY(value); |
| | | } |
| | | }; |
| | | new Thread(){ |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | int sleep = 10; |
| | | for(int i =0 ; i < 100 ; i+=sleep){ |
| | | sleep(sleep); |
| | | Message msg = new Message(); |
| | | msg.obj = (float)i/100/3; |
| | | handler.sendMessage(msg); |
| | | } |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }.start(); |
| | | } |
| | | |
| | | /** |
| | | * 冒泡式拉伸控件 |
| | | * @param view |
| | | */ |
| | | public static void scaleReBoundX(final View view, final int size){ |
| | | Log.i("","scaleReBound view:"+view); |
| | | SpringSystem springSystem = SpringSystem.create(); |
| | | final Spring spring = springSystem.createSpring(); |
| | | spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(100,7));//qcTension拉力和qcFriction摩擦力参数 |
| | | spring.addListener(new SimpleSpringListener() { |
| | | @Override |
| | | public void onSpringUpdate(Spring spring) { |
| | | float value = (float) spring.getCurrentValue(); |
| | | float scale = value; |
| | | view.setScaleX(scale); |
| | | view.setScaleY(scale); |
| | | } |
| | | }); |
| | | spring.setEndValue(size);//控件拉伸收缩的倍率 |
| | | } |
| | | |
| | | public static void scalXAnima(final View view, float from, float to){ |
| | | setAnimator("scaleX",from,to,view,ANIMA_TIME); |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.util; |
| | | |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-4-14. |
| | | */ |
| | | public class PhoneUtil { |
| | | /** |
| | | * 验证中国大陆手机号是否合法 |
| | | * @return |
| | | */ |
| | | public static boolean isCNMobileNO(String mobile){ |
| | | if (mobile.length() != 11) |
| | | { |
| | | return false; |
| | | }else{ |
| | | /** |
| | | * 移动号段正则表达式 |
| | | */ |
| | | String pat1 = "^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$"; |
| | | /** |
| | | * 联通号段正则表达式 |
| | | */ |
| | | String pat2 = "^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$"; |
| | | /** |
| | | * 电信号段正则表达式 |
| | | */ |
| | | String pat3 = "^((133)|(153)|(177)|(18[0,1,9])|(149))\\d{8}$"; |
| | | /** |
| | | * 虚拟运营商正则表达式 |
| | | */ |
| | | String pat4 = "^((170))\\d{8}|(1718)|(1719)\\d{7}$"; |
| | | |
| | | Pattern pattern1 = Pattern.compile(pat1); |
| | | Matcher match1 = pattern1.matcher(mobile); |
| | | boolean isMatch1 = match1.matches(); |
| | | if(isMatch1){ |
| | | return true; |
| | | } |
| | | Pattern pattern2 = Pattern.compile(pat2); |
| | | Matcher match2 = pattern2.matcher(mobile); |
| | | boolean isMatch2 = match2.matches(); |
| | | if(isMatch2){ |
| | | return true; |
| | | } |
| | | Pattern pattern3 = Pattern.compile(pat3); |
| | | Matcher match3 = pattern3.matcher(mobile); |
| | | boolean isMatch3 = match3.matches(); |
| | | if(isMatch3){ |
| | | return true; |
| | | } |
| | | Pattern pattern4 = Pattern.compile(pat4); |
| | | Matcher match4 = pattern4.matcher(mobile); |
| | | boolean isMatch4 = match4.matches(); |
| | | if(isMatch4){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public static boolean isMobileNO( String phone) { |
| | | //china phone |
| | | String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$"; |
| | | if (phone.length() != 11) { |
| | | return false; |
| | | } else { |
| | | Pattern p = Pattern.compile(regex); |
| | | Matcher m = p.matcher(phone); |
| | | return m.matches(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.util; |
| | | |
| | | import android.content.Context; |
| | | import android.content.SharedPreferences; |
| | | |
| | | import androidx.collection.ArraySet; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * PreferencesUtils, easy to get or put data |
| | | * <ul> |
| | | * <strong>Preference Name</strong> |
| | | * <li>you can change preference name by {@link #PREFERENCE_NAME}</li> |
| | | * </ul> |
| | | * <ul> |
| | | * <strong>Put Value</strong> |
| | | * </ul> |
| | | * |
| | | * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-3-6 |
| | | */ |
| | | public class PreferencesUtils { |
| | | |
| | | public static final String PREFERENCE_NAME="zipper"; |
| | | public static final String PROJECT = "project"; |
| | | public static final String USER = "user"; |
| | | public static final String VISITOR = "visitor"; |
| | | |
| | | private PreferencesUtils() { |
| | | throw new AssertionError(); |
| | | } |
| | | |
| | | public static boolean clearData(Context context, String keyShared){ |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | return settings.edit().clear().commit(); |
| | | } |
| | | |
| | | |
| | | public static boolean clearData(Context context, String key, String keyShared){ |
| | | putString(context,key,null,keyShared); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * remove key preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static void removeKey(Context context, String key, String keyShared){ |
| | | |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.remove(key); |
| | | } |
| | | |
| | | /** |
| | | * remove value preferences |
| | | * |
| | | * @param context |
| | | * @param value The name of the preference to modify |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static void removeValue(Context context, String value, String keyShared){ |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.remove(value); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * put string preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static boolean putString(Context context, String key, String value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putString(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get string preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or null. Throws ClassCastException if there is a preference with this |
| | | * name that is not a string |
| | | * @see #getString(Context, String, String) |
| | | */ |
| | | public static String getString(Context context, String key, String keyShared) { |
| | | return getString(context, key, null,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get string preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a string |
| | | */ |
| | | public static String getString(Context context, String key, String defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | return settings.getString(key, defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * put int preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static boolean putInt(Context context, String key, int value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putInt(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get int preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this |
| | | * name that is not a int |
| | | */ |
| | | public static int getInt(Context context, String key, String keyShared) { |
| | | return getInt(context, key, -1,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get int preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a int |
| | | */ |
| | | public static int getInt(Context context, String key, int defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getInt(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Integer.parseInt(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put long preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static boolean putLong(Context context, String key, long value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putLong(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get long preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this |
| | | * name that is not a long |
| | | */ |
| | | public static long getLong(Context context, String key, String keyShared) { |
| | | return getLong(context, key, -1,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get long preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a long |
| | | */ |
| | | public static long getLong(Context context, String key, long defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getLong(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Long.parseLong(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put float preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static boolean putFloat(Context context, String key, float value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putFloat(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get float preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this |
| | | * name that is not a float |
| | | */ |
| | | public static float getFloat(Context context, String key, String keyShared) { |
| | | return getFloat(context, key, -1,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get float preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a float |
| | | */ |
| | | public static float getFloat(Context context, String key, float defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getFloat(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Float.parseFloat(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static boolean putBoolean(Context context, String key, boolean value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putBoolean(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences, default is false |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or false. Throws ClassCastException if there is a preference with this |
| | | * name that is not a boolean |
| | | */ |
| | | public static boolean getBoolean(Context context, String key, String keyShared) { |
| | | return getBoolean(context, key, false,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a boolean |
| | | */ |
| | | public static boolean getBoolean(Context context, String key, boolean defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getBoolean(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Boolean.parseBoolean(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference , the value of set ,canot be the other class out of java collection |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public static boolean putStringSet(Context context, String key, Set value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putStringSet(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences, default is false |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or false. Throws ClassCastException if there is a preference with this |
| | | * name that is not a boolean 获取出来的值最终被转换为hashset类型 |
| | | */ |
| | | public static Set getStringSet(Context context, String key, String keyShared) { |
| | | return getStringSet(context, key,new ArraySet(),keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a boolean 获取出来的值最终被转换为hashset类型 |
| | | */ |
| | | public static Set getStringSet(Context context, String key, Set defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | return settings.getStringSet(key, defaultValue); |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <selector xmlns:tools="http://schemas.android.com/tools" |
| | | xmlns:android="http://schemas.android.com/apk/res/android" |
| | | tools:ignore="MissingDefaultResource"> |
| | | <item android:state_enabled="false" android:color="@color/txt_enable"/> <!-- pressed --> |
| | | <item android:state_pressed="true" android:color="@color/txt_cusor_color"/> <!-- pressed --> |
| | | <item android:state_focused="true" android:color="@color/txt_hint"/> <!-- focused --> |
| | | <item android:color="@color/white"/> <!-- default --> |
| | | </selector> |
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" |
| | | app:leftDrawable="@mipmap/ic_arrow_back_black_24dp" |
| | | app:titleText="登录" |
| | | tools:ignore="MissingConstraints" /> |
| | | |
| | | |
| | | <ImageView |
| | | android:id="@+id/img_icon" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:layout_gravity="center_horizontal" |
| | | android:layout_marginTop="50dp" |
| | | android:src="@mipmap/app_icon" |
| | | android:adjustViewBounds="true" |
| | | app:layout_constraintTop_toBottomOf="@id/title_bar" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | /> |
| | | |
| | | <com.runt.open.mvvm.widgets.ClearEditText |
| | | android:id="@+id/edit_phone" |
| | | style="@style/login_edit" |
| | | android:hint="@string/input_phone" |
| | | android:inputType="phone" |
| | | app:layout_constraintTop_toBottomOf="@id/img_icon" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | /> |
| | | |
| | | |
| | | <com.runt.open.mvvm.widgets.ClearEditText |
| | | android:id="@+id/edit_verify_code" |
| | | style="@style/login_edit" |
| | | android:hint="@string/input_verify_code" |
| | | android:inputType="number" |
| | | app:layout_constraintTop_toBottomOf="@id/edit_phone" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent"/> |
| | | |
| | | |
| | | <TextView |
| | | android:id="@+id/txt_get_verify" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:textColor="@color/link" |
| | | android:layout_marginRight="@dimen/default_margin_lr" |
| | | android:text="@string/get_verify_code" |
| | | android:gravity="center" |
| | | app:layout_constraintTop_toTopOf="@id/edit_verify_code" |
| | | app:layout_constraintRight_toRightOf="@id/edit_verify_code" |
| | | app:layout_constraintBottom_toBottomOf="@id/edit_verify_code"/> |
| | | |
| | | |
| | | <com.runt.open.mvvm.widgets.ClearEditText |
| | | android:id="@+id/edit_pass" |
| | | style="@style/login_edit" |
| | | android:inputType="textPassword" |
| | | android:hint="@string/input_pass" |
| | | app:layout_constraintTop_toBottomOf="@id/edit_verify_code" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" /> |
| | | |
| | | |
| | | <com.runt.open.mvvm.widgets.ClearEditText |
| | | android:id="@+id/edit_pass_repeat" |
| | | style="@style/login_edit" |
| | | android:hint="@string/str_input_repeat" |
| | | android:inputType="textPassword" |
| | | app:layout_constraintTop_toBottomOf="@id/edit_pass" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent"/> |
| | | |
| | | |
| | | <TextView |
| | | android:id="@+id/txt_forgot" |
| | | style="@style/login_link" |
| | | android:text="@string/forgot_pass" |
| | | app:layout_constraintTop_toBottomOf="@id/edit_pass_repeat" |
| | | app:layout_constraintLeft_toLeftOf="parent" /> |
| | | <TextView |
| | | android:id="@+id/txt_register" |
| | | style="@style/login_link" |
| | | android:text="@string/register" |
| | | app:layout_constraintTop_toBottomOf="@id/edit_pass_repeat" |
| | | app:layout_constraintLeft_toRightOf="@id/txt_forgot" |
| | | app:layout_constraintRight_toLeftOf="@id/txt_login" /> |
| | | <TextView |
| | | android:id="@+id/txt_login" |
| | | style="@style/login_link" |
| | | android:text="@string/login" |
| | | app:layout_constraintTop_toBottomOf="@id/edit_pass_repeat" |
| | | app:layout_constraintRight_toRightOf="parent" /> |
| | | |
| | | <androidx.appcompat.widget.AppCompatCheckBox |
| | | android:id="@+id/checkbox" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginLeft="@dimen/default_margin_lr" |
| | | android:layout_marginBottom="@dimen/default_margin_lr" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintBottom_toTopOf="@id/button"/> |
| | | <TextView |
| | | android:id="@+id/txt_privacy" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:paddingTop="@dimen/default_margin_td" |
| | | android:paddingBottom="@dimen/default_margin_td" |
| | | android:paddingRight="@dimen/default_margin_lr" |
| | | android:background="@color/white" |
| | | android:textColor="@color/link" |
| | | android:text=" 我已阅读并同意《隐私条款》" |
| | | app:layout_constraintLeft_toRightOf="@id/checkbox" |
| | | app:layout_constraintTop_toTopOf="@id/checkbox" |
| | | app:layout_constraintBottom_toBottomOf="@id/checkbox"/> |
| | | <Button |
| | | android:id="@+id/button" |
| | | style="@style/btn_normal" |
| | | android:layout_marginBottom="@dimen/default_margin_lr" |
| | | android:text="@string/login" |
| | | android:layout_marginLeft="@dimen/default_margin_lr" |
| | | android:layout_marginRight="@dimen/default_margin_lr" |
| | | app:layout_constraintBottom_toBottomOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent"/> |
| | | </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" |
| | | app:layout_constraintTop_toTopOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | style="@style/titlebar" /> |
| | | |
| | | <LinearLayout |
| | | android:id="@+id/lin_progressbar" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="2dp" |
| | | android:background="@drawable/bg_gradient_gray" |
| | | app:layout_constraintTop_toBottomOf="@id/title_bar" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | android:visibility="gone"> |
| | | <View |
| | | android:id="@+id/view_progressbar" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:animateLayoutChanges="true" |
| | | android:background="@drawable/bg_gradient_blue"/> |
| | | </LinearLayout> |
| | | |
| | | <WebView |
| | | android:id="@+id/browser" |
| | | app:layout_constraintTop_toBottomOf="@id/title_bar" |
| | | app:layout_constraintBottom_toBottomOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="0dp" /> |
| | | |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
| | |
| | | <string name="title_home">Home</string> |
| | | <string name="title_dashboard">Dashboard</string> |
| | | <string name="title_notifications">Notifications</string> |
| | | <string name="get_verify_code">获取验证码</string> |
| | | <string name="select_region">选择国家/地区</string> |
| | | <string name="input_phone">请输入手机号</string> |
| | | <string name="input_pass">请输入密码</string> |
| | | <string name="input_verify_code">请输入验证码</string> |
| | | <string name="input_invite_code">请输入邀请码</string> |
| | | <string name="forgot_pass">忘记密码?</string> |
| | | <string name="register">注册</string> |
| | | <string name="login">登录</string> |
| | | <string name="msg_login">短信登录</string> |
| | | <string name="str_input_old">请输入旧密码</string> |
| | | <string name="str_input_new">请输入新密码</string> |
| | | <string name="str_input_repeat">请再次输入新密码</string> |
| | | <string name="str_pass_format_failed">密码要求6-12位数(数字/英文大小写/符号混合)格式</string> |
| | | <string name="str_cannot_eques_old">新密码不能与旧密码相同</string> |
| | | <string name="str_new_verify_failed">新密码两次输入不相同</string> |
| | | <string name="str_edit_pass">修改密码</string> |
| | | <string name="str_confirm">确认</string> |
| | | <string name="str_invite">推荐码</string> |
| | | <string name="str_mine">个人中心</string> |
| | | <string name="str_setting">设置</string> |
| | | <string name="str_msg">消息中心</string> |
| | | <string name="str_version">版本号</string> |
| | | <string name="str_msg_detail">资讯详情</string> |
| | | <string name="str_copied">复制成功</string> |
| | | <string name="str_get_data_failed">获取数据失败</string> |
| | | <string name="str_phone_format_failed">输入手机格式不正确</string> |
| | | <string name="login_pass_failed">账号或者密码错误,请重新输入</string> |
| | | <string name="login_code_failed">验证码有误,请重新输入</string> |
| | | <string name="comming_soon">敬请期待</string> |
| | | <string name="notice">通知</string> |
| | | <string name="save_img">保存图片</string> |
| | | <string name="copy_url">复制链接</string> |
| | | <string name="toast_login">请先登录后再操作</string> |
| | | <string name="registed">账号已经注册了</string> |
| | | <string name="failed">操作失败</string> |
| | | <string name="none_account">账号不存在</string> |
| | | <string name="loading">加载中</string> |
| | | <string name="register_success">账号注册成功请登录</string> |
| | | <string name="verify_failed">验证码失效</string> |
| | | <string name="invite_error">错误的邀请码</string> |
| | | <string name="update_pass_sucess">密码修改成功</string> |
| | | <string name="update_pass_failed_old">旧密码错误</string> |
| | | <string name="update_pass_failed">密码修改失败</string> |
| | | <string name="login_success">登录成功</string> |
| | | <string name="login_failed">登录失败</string> |
| | | <string name="login_failed_pass">密码错误</string> |
| | | <string name="new_version">新版本更新</string> |
| | | <string name="str_cancel">取消</string> |
| | | <string name="logouted">登录失效,请重新登录</string> |
| | | |
| | | <string name="forgot_update_pwd">点击忘记密码去修改</string> |
| | | <string name="download">下载</string> |
| | | <string name="created_at">更新</string> |
| | | <string name="msg_deleted">消息已被删除</string> |
| | | <string name="logout">退出登录</string> |
| | | <string name="internet_failed">网络连接失败</string> |
| | | <string name="str_miner_running">正在挖矿</string> |
| | | <string name="str_apply">申请</string> |
| | | <string name="str_permission">需要获取文件存储权限才能查看</string> |
| | | <string name="str_wait">敬请期待</string> |
| | | <string name="str_node_l">您当前为三级节点</string> |
| | | <string name="str_email">官方邮箱:</string> |
| | | <string name="str_website">官方网站:</string> |
| | | <string name="str_restart">重启APP</string> |
| | | <string name="str_success">成功</string> |
| | | <string name="str_no_up">暂无更新</string> |
| | | </resources> |
| | |
| | | <style name="TransparentDialog" parent="Theme.AppCompat.Dialog"> |
| | | <item name="android:windowBackground">@color/transparent</item> |
| | | </style> |
| | | |
| | | <style name="titlebar"> |
| | | <item name="android:layout_width">match_parent</item> |
| | | <item name="android:layout_height">?attr/actionBarSize</item> |
| | | <item name="android:background">@color/white</item> |
| | | <item name="titleTextColor">@color/txt_normal</item> |
| | | <item name="layout_constraintTop_toTopOf">parent</item> |
| | | <item name="layout_constraintLeft_toLeftOf">parent</item> |
| | | <item name="layout_constraintRight_toRightOf">parent</item> |
| | | <item name="android:paddingLeft">@dimen/default_margin_lr</item> |
| | | <item name="android:paddingRight">@dimen/default_margin_lr</item> |
| | | </style> |
| | | |
| | | |
| | | <style name="btn_normal"> |
| | | <item name="android:layout_width">match_parent</item> |
| | | <item name="android:layout_height">wrap_content</item> |
| | | <item name="android:background">@drawable/btn_circle_blue</item> |
| | | <item name="android:textColor">@color/btn_txt_normal</item> |
| | | <item name="android:textSize">@dimen/title_size</item> |
| | | </style> |
| | | |
| | | <style name="login_edit"> |
| | | <item name="android:layout_width">match_parent</item> |
| | | <item name="android:layout_height">@dimen/title_height</item> |
| | | <item name="android:background">@drawable/bg_circle_default</item> |
| | | <item name="android:layout_marginTop">@dimen/default_margin_td</item> |
| | | <item name="android:paddingRight">@dimen/default_margin_lr</item> |
| | | <item name="android:paddingLeft">@dimen/default_margin_lr</item> |
| | | <item name="android:singleLine">true</item> |
| | | <item name="android:gravity">center_vertical</item> |
| | | <item name="android:layout_marginLeft">@dimen/default_margin_lr</item> |
| | | <item name="android:layout_marginRight">@dimen/default_margin_lr</item> |
| | | </style> |
| | | |
| | | <style name="login_link"> |
| | | <item name="android:layout_width">wrap_content</item> |
| | | <item name="android:layout_height">wrap_content</item> |
| | | <item name="android:paddingTop">@dimen/default_margin_td</item> |
| | | <item name="android:paddingBottom">@dimen/default_margin_td</item> |
| | | <item name="android:paddingRight">30dp</item> |
| | | <item name="android:paddingLeft">30dp</item> |
| | | <item name="android:textColor">@color/link</item> |
| | | </style> |
| | | </resources> |
| | |
| | | <style name="Theme.OpemMvvm" parent="Theme.MaterialComponents.Light.NoActionBar"> |
| | | <!-- Primary brand color. --> |
| | | <item name="colorPrimary">@color/sky</item> |
| | | <item name="colorPrimaryVariant">@color/red</item> |
| | | <item name="colorPrimaryVariant">@color/blue_sky</item> |
| | | <item name="colorOnPrimary">@color/black</item> |
| | | <!-- Secondary brand color. --> |
| | | <item name="colorSecondary">@color/black_4</item> |
| | |
| | | <!-- Status bar color. --> |
| | | <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> |
| | | <!-- Customize your theme here. --> |
| | | <!--全局设置文本颜色和大小--> |
| | | <item name="android:textColor">@color/txt_normal</item> |
| | | <item name="android:textSize">@dimen/txt_size</item> |
| | | </style> |
| | | |
| | | |