android.text.TextWatcher

本文详细介绍了TextWatcher接口的功能与使用方法,包括beforeTextChanged、onTextChanged及afterTextChanged三个关键方法的作用与参数解释,帮助开发者更好地理解和应用此接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



/**
 * When an object of a type is attached to an Editable, its methods will
 * be called when the text is changed.
 */
public interface TextWatcher extends NoCopySpan {
    /**
     * This method is called to notify you that, within <code>s</code>,
     * the <code>count</code> characters beginning at <code>start</code>
     * are about to be replaced by new text with length <code>after</code>.
     * It is an error to attempt to make changes to <code>s</code> from
     * this callback.
     */
    public void beforeTextChanged(CharSequence s, int start,
                                  int count, int after);
    /**
     * This method is called to notify you that, within <code>s</code>,
     * the <code>count</code> characters beginning at <code>start</code>
     * have just replaced old text that had length <code>before</code>.
     * It is an error to attempt to make changes to <code>s</code> from
     * this callback.
     */
    public void onTextChanged(CharSequence s, int start, int before, int count);

    /**
     * This method is called to notify you that, somewhere within
     * <code>s</code>, the text has been changed.
     * It is legitimate to make further changes to <code>s</code> from
     * this callback, but be careful not to get yourself into an infinite
     * loop, because any changes you make will cause this method to be
     * called again recursively.
     * (You are not told where the change took place because other
     * afterTextChanged() methods may already have made other changes
     * and invalidated the offsets.  But if you need to know here,
     * you can use {@link Spannable#setSpan} in {@link #onTextChanged}
     * to mark your place and then look up from here where the span
     * ended up.
     */
    public void afterTextChanged(Editable s);
}
说明:

public void beforeTextChanged(CharSequence s, int start, int count, int after)

s改变前的text字符,start当前起始位置,count被替换字符的长度(删除时为0),after新替代字符的长度


public void onTextChanged(CharSequence s, int start, int before, int count)

s改变后的text字符,start替换前的起始位置(同beforeTextChanged),before被替换字符的长度,count新替代字符的长度


public void afterTextChanged(Editable s)

s改变后的text字符



package com.example.kucun2.ui.bancai; import android.app.AlertDialog; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.example.kucun2.DataPreserver.Data; import com.example.kucun2.R; import com.example.kucun2.Retrofit.RetrofitClient; import com.example.kucun2.Retrofit.RetrofitService; import com.example.kucun2.entity.*; import com.example.kucun2.ui.bancai.Adapter.InventoryAdapter; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.ArrayList; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class InventoryFragment extends Fragment implements Data.OnDataChangeListener { private EditText searchEditText; private RecyclerView recyclerView; private InventoryAdapter adapter; private List<Kucun> inventoryList = new ArrayList<>(); private FloatingActionButton fabAdd; @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_kucun_inventory, container, false); // 初始化UI组件 searchEditText = view.findViewById(R.id.search_edittext); recyclerView = view.findViewById(R.id.recycler_view); fabAdd = view.findViewById(R.id.fab_add); // 设置RecyclerView recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); adapter = new InventoryAdapter(inventoryList); recyclerView.setAdapter(adapter); // 设置搜索功能 searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { filterInventory(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); // 添加按钮点击事件 fabAdd.setOnClickListener(v -> showAddDialog()); // 加载数据 loadData(); return view; } private void fetchInventoryData(String searchTerm) { RetrofitService service = RetrofitClient.getRetrofitInstance().create(RetrofitService.class); service.getInventory(searchTerm).enqueue(new Callback<List<Kucun>>() { @Override public void onResponse(Call<List<Kucun>> call, Response<List<Kucun>> response) { if (response.isSuccessful() && response.body() != null) { updateInventoryList(response.body()); } } @Override public void onFailure(Call<List<Kucun>> call, Throwable t) { Toast.makeText(getContext(), "加载失败: " + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); } private void filterInventory(String query) { List<Kucun> filtered = new ArrayList<>(); String lowerQuery = query.toLowerCase(); for (Kucun kucun : Data.kucuns().getViewList()) { Bancai bancai = kucun.getBancai(); if (bancai == null) continue; boolean matches = false; // 检查材质名称 if (bancai.getCaizhi() != null && bancai.getCaizhi().getName() != null) { matches |= bancai.getCaizhi().getName().toLowerCase().contains(lowerQuery); } // 检查木皮1名称 if (bancai.getMupi1() != null && bancai.getMupi1().getName() != null) { matches |= bancai.getMupi1().getName().toLowerCase().contains(lowerQuery); } // 检查木皮2名称 if (bancai.getMupi2() != null && bancai.getMupi2().getName() != null) { matches |= bancai.getMupi2().getName().toLowerCase().contains(lowerQuery); } // 检查厚度 if (String.valueOf(bancai.getHoudu()).contains(query)) { matches = true; } if (matches) filtered.add(kucun); } inventoryList.clear(); inventoryList.addAll(filtered); adapter.notifyDataSetChanged(); } private void showAddDialog() { MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext()); builder.setTitle("添加类型") .setItems(new String[]{"板材", "木皮1", "木皮2", "材质"}, (dialog, which) -> { switch (which) { case 0: showAddBancaiDialog(); break; case 1: showAddMupiDialog(); break; case 2: showAddCaizhiDialog(); break; } }); builder.show(); } private void showAddBancaiDialog() { } private void showAddMupiDialog() { // 类似上面的实现 } private void showAddCaizhiDialog() { // 类似上面的实现 } private void addNewBancai(Bancai bancai) { // 添加新板材 Data.add(bancai); // 创建关联的库存记录 Kucun newKucun = new Kucun(); newKucun.setBancai(bancai); newKucun.setShuliang(0); // 初始库存为0 Data.add(newKucun); Toast.makeText(getContext(), "板材添加成功", Toast.LENGTH_SHORT).show(); } @Override public void onResume() { super.onResume(); Data.addDataChangeListener(this); // 注册数据监听 } @Override public void onPause() { super.onPause(); Data.removeDataChangeListener(this); // 移除数据监听 } @Override public void onDataChanged() { // 数据变化时自动刷新 loadData(); } private void loadData() { // 从全局数据获取库存 List<Kucun> fullList = Data.kucuns().getViewList(); updateInventoryList(fullList); } private void updateInventoryList(List<Kucun> fullList) { inventoryList.clear(); inventoryList.addAll(fullList); adapter.notifyDataSetChanged(); } }
最新发布
06-27
package com.example.kucun2.data; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; import androidx.room.migration.Migration; import androidx.sqlite.db.SupportSQLiteDatabase; import com.example.kucun2.entity.User; import java.io.File; @Database(entities = {User.class}, version = 2, exportSchema = false ) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); private static volatile AppDatabase INSTANCE; public static AppDatabase getDatabase(Context context) { return Room.databaseBuilder(context, AppDatabase.class, "users.db") .addMigrations(MIGRATION_1_2) .addCallback(new RoomDatabase.Callback() { @Override public void onOpen(@NonNull SupportSQLiteDatabase db) { // 确保视图存在 db.execSQL("CREATE VIEW IF NOT EXISTS user_summary AS SELECT id, name FROM users"); } }) .fallbackToDestructiveMigrationOnDowngrade() .build(); } private static void migrateFromLegacy(Context context) { // 旧数据库迁移逻辑 SQLiteDatabase legacyDb = SQLiteDatabase.openDatabase( context.getDatabasePath("users.db").getPath(), null, SQLiteDatabase.OPEN_READONLY); Cursor cursor = legacyDb.rawQuery("SELECT * FROM users", null); // 数据迁移到Room数据库 UserDao dao = INSTANCE.userDao(); // 使用事务保证迁移完整性 INSTANCE.runInTransaction(() -> { while (cursor.moveToNext()) { User user = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getInt(4) ); dao.insert(user); } cursor.close(); legacyDb.close(); }); } private static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(@NonNull SupportSQLiteDatabase db) { // 示例:添加新字段 // 示例:创建视图(不修改表结构) db.execSQL("CREATE TABLE users_temp (id INTEGER PRIMARY KEY, " + "name TEXT, " + "andy TEXT, " + "pass TEXT, " + "role INTEGER)" + ""); // 3. 迁移数据 db.execSQL("INSERT INTO users_temp (id, name, andy, pass, role) " + "SELECT id, name, andy, pass, role FROM users"); // 4. 删除旧表并重命名 db.execSQL("DROP TABLE users"); db.execSQL("ALTER TABLE users_temp RENAME TO users"); // 5. 维护视图 db.execSQL("DROP VIEW IF EXISTS user_summary"); db.execSQL("CREATE VIEW user_summary AS SELECT id, name FROM users"); } }; public static void deleteDatabase(Context context) { // 1. 关闭现有连接 if (INSTANCE != null) { INSTANCE.close(); INSTANCE = null; } // 2. 删除物理文件 context.deleteDatabase("users.db"); // 3. 清理残留文件(WAL/SHM) File databaseDir = context.getDatabasePath("users.db").getParentFile(); if (databaseDir != null) { for (File file : databaseDir.listFiles()) { if (file.getName().startsWith("users.db")) { file.delete(); } } } } }package com.example.kucun2.ui.moban; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.graphics.Rect; import android.os.Bundle; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.DecelerateInterpolator; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import com.example.kucun2.Http.HttpApi; import com.example.kucun2.Http.ReturnMethod; import com.example.kucun2.R; import com.example.kucun2.data.AppDatabase; import com.example.kucun2.entity.User; import com.example.kucun2.manager.AuthManager; import java.io.File; public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, ViewTreeObserver.OnGlobalLayoutListener, TextWatcher { private String TAG = "ifu25"; private ImageButton mIbNavigationBack; private LinearLayout mLlLoginPull; private View mLlLoginLayer; private LinearLayout mLlLoginOptions; private EditText mEtLoginUsername; private EditText mEtLoginPwd; private LinearLayout mLlLoginUsername; private ImageView mIvLoginUsernameDel; private Button mBtLoginSubmit; private LinearLayout mLlLoginPwd; private ImageView mIvLoginPwdDel; private ImageView mIvLoginLogo; private LinearLayout mLayBackBar; private TextView mTvLoginForgetPwd; private Button mBtLoginRegister; private CheckBox cbAgree; //全局Toast private Toast mToast; private int mLogoHeight; private int mLogoWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); initView(); } //初始化视图 private void initView() { //登录层、下拉层、其它登录方式层 mLlLoginPull = findViewById(R.id.ll_login_pull); mLlLoginOptions = findViewById(R.id.ll_login_options); //导航栏+返回按钮 mLayBackBar = findViewById(R.id.ly_retrieve_bar); mIbNavigationBack = findViewById(R.id.ib_navigation_back); //logo mIvLoginLogo = findViewById(R.id.iv_login_logo); //username mLlLoginUsername = findViewById(R.id.ll_login_username); mEtLoginUsername = findViewById(R.id.et_login_username); mIvLoginUsernameDel = findViewById(R.id.iv_login_username_del); //passwd mLlLoginPwd = findViewById(R.id.ll_login_pwd); mEtLoginPwd = findViewById(R.id.et_login_pwd); mIvLoginPwdDel = findViewById(R.id.iv_login_pwd_del); //提交、注册 mBtLoginSubmit = findViewById(R.id.bt_login_submit); //忘记密码 mTvLoginForgetPwd = findViewById(R.id.tv_login_forget_pwd); mTvLoginForgetPwd.setOnClickListener(this); //注册点击事件 mLlLoginPull.setOnClickListener(this); mIbNavigationBack.setOnClickListener(this); mEtLoginUsername.setOnClickListener(this); mIvLoginUsernameDel.setOnClickListener(this); mBtLoginSubmit.setOnClickListener(this); mEtLoginPwd.setOnClickListener(this); mIvLoginPwdDel.setOnClickListener(this); findViewById(R.id.ib_login_weibo).setOnClickListener(this); findViewById(R.id.ib_login_qq).setOnClickListener(this); findViewById(R.id.ib_login_wx).setOnClickListener(this); //注册其它事件 mLayBackBar.getViewTreeObserver().addOnGlobalLayoutListener(this); mEtLoginUsername.setOnFocusChangeListener(this); mEtLoginUsername.addTextChangedListener(this); mEtLoginPwd.setOnFocusChangeListener(this); mEtLoginPwd.addTextChangedListener(this); cbAgree = findViewById(R.id.cb_remember_login); cbAgree.setOnCheckedChangeListener((buttonView, isChecked) -> { if (isChecked) { Toast.makeText(this, "已同意协议", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "请阅读并同意协议", Toast.LENGTH_SHORT).show(); } }); } @SuppressLint("NonConstantResourceId") @Override public void onClick(View view) { switch (view.getId()) { case R.id.ib_navigation_back: //返回 finish(); break; case R.id.et_login_username: mEtLoginPwd.clearFocus(); mEtLoginUsername.setFocusableInTouchMode(true); mEtLoginUsername.requestFocus(); break; case R.id.et_login_pwd: mEtLoginUsername.clearFocus(); mEtLoginPwd.setFocusableInTouchMode(true); mEtLoginPwd.requestFocus(); break; case R.id.iv_login_username_del: //清空用户名 mEtLoginUsername.setText(null); break; case R.id.iv_login_pwd_del: //清空密码 mEtLoginPwd.setText(null); break; case R.id.bt_login_submit: //登录 loginRequest(); break; case R.id.tv_login_forget_pwd: //忘记密码 startActivity(new Intent(MainActivity.this, ForgetPwdActivity.class)); break; case R.id.ll_login_pull: mLlLoginPull.animate().cancel(); mLlLoginLayer.animate().cancel(); int height = mLlLoginOptions.getHeight(); float progress = (mLlLoginLayer.getTag() != null && mLlLoginLayer.getTag() instanceof Float) ? (float) mLlLoginLayer.getTag() : 1; int time = (int) (360 * progress); if (mLlLoginPull.getTag() != null) { mLlLoginPull.setTag(null); glide(height, progress, time); } else { mLlLoginPull.setTag(true); upGlide(height, progress, time); } break; case R.id.ib_login_weibo: weiboLogin(); break; case R.id.ib_login_qq: qqLogin(); break; case R.id.ib_login_wx: weixinLogin(); break; default: break; } } //用户名密码焦点改变 @Override public void onFocusChange(View v, boolean hasFocus) { int id = v.getId(); if (id == R.id.et_login_username) { if (hasFocus) { mLlLoginUsername.setActivated(true); mLlLoginPwd.setActivated(false); } } else { if (hasFocus) { mLlLoginPwd.setActivated(true); mLlLoginUsername.setActivated(false); } } } /** * menu glide * * @param height height * @param progress progress * @param time time */ private void glide(int height, float progress, int time) { mLlLoginPull.animate() .translationYBy(height - height * progress) .translationY(height) .setDuration(time) .start(); mLlLoginLayer.animate() .alphaBy(1 * progress) .alpha(0) .setDuration(time) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationCancel(Animator animation) { if (animation instanceof ValueAnimator) { mLlLoginLayer.setTag(((ValueAnimator) animation).getAnimatedValue()); } } @Override public void onAnimationEnd(Animator animation) { if (animation instanceof ValueAnimator) { mLlLoginLayer.setTag(((ValueAnimator) animation).getAnimatedValue()); } mLlLoginLayer.setVisibility(View.GONE); } }) .start(); } /** * menu up glide * * @param height height * @param progress progress * @param time time */ private void upGlide(int height, float progress, int time) { mLlLoginPull.animate() .translationYBy(height * progress) .translationY(0) .setDuration(time) .start(); mLlLoginLayer.animate() .alphaBy(1 - progress) .alpha(1) .setDuration(time) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { mLlLoginLayer.setVisibility(View.VISIBLE); } @Override public void onAnimationCancel(Animator animation) { if (animation instanceof ValueAnimator) { mLlLoginLayer.setTag(((ValueAnimator) animation).getAnimatedValue()); } } @Override public void onAnimationEnd(Animator animation) { if (animation instanceof ValueAnimator) { mLlLoginLayer.setTag(((ValueAnimator) animation).getAnimatedValue()); } } }) .start(); } //显示或隐藏logo @Override public void onGlobalLayout() { final ImageView ivLogo = this.mIvLoginLogo; Rect KeypadRect = new Rect(); mLayBackBar.getWindowVisibleDisplayFrame(KeypadRect); int screenHeight = mLayBackBar.getRootView().getHeight(); int keypadHeight = screenHeight - KeypadRect.bottom; //隐藏logo if (keypadHeight > 300 && ivLogo.getTag() == null) { final int height = ivLogo.getHeight(); final int width = ivLogo.getWidth(); this.mLogoHeight = height; this.mLogoWidth = width; ivLogo.setTag(true); ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 0); valueAnimator.setDuration(400).setInterpolator(new DecelerateInterpolator()); valueAnimator.addUpdateListener(animation -> { float animatedValue = (float) animation.getAnimatedValue(); ViewGroup.LayoutParams layoutParams = ivLogo.getLayoutParams(); layoutParams.height = (int) (height * animatedValue); layoutParams.width = (int) (width * animatedValue); ivLogo.requestLayout(); ivLogo.setAlpha(animatedValue); }); if (valueAnimator.isRunning()) { valueAnimator.cancel(); } valueAnimator.start(); } //显示logo else if (keypadHeight < 300 && ivLogo.getTag() != null) { final int height = mLogoHeight; final int width = mLogoWidth; ivLogo.setTag(null); ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); valueAnimator.setDuration(400).setInterpolator(new DecelerateInterpolator()); valueAnimator.addUpdateListener(animation -> { float animatedValue = (float) animation.getAnimatedValue(); ViewGroup.LayoutParams layoutParams = ivLogo.getLayoutParams(); layoutParams.height = (int) (height * animatedValue); layoutParams.width = (int) (width * animatedValue); ivLogo.requestLayout(); ivLogo.setAlpha(animatedValue); }); if (valueAnimator.isRunning()) { valueAnimator.cancel(); } valueAnimator.start(); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } //用户名密码输入事件 @Override public void afterTextChanged(Editable s) { String username = mEtLoginUsername.getText().toString().trim(); String pwd = mEtLoginPwd.getText().toString().trim(); //是否显示清除按钮 if (username.length() > 0) { mIvLoginUsernameDel.setVisibility(View.VISIBLE); } else { mIvLoginUsernameDel.setVisibility(View.INVISIBLE); } if (pwd.length() > 0) { mIvLoginPwdDel.setVisibility(View.VISIBLE); } else { mIvLoginPwdDel.setVisibility(View.INVISIBLE); } //登录按钮是否可用 if (!TextUtils.isEmpty(pwd) && !TextUtils.isEmpty(username)) { mBtLoginSubmit.setBackgroundResource(R.drawable.bg_login_submit); mBtLoginSubmit.setTextColor(ContextCompat.getColor(this,R.color.white)); } else { mBtLoginSubmit.setBackgroundResource(R.drawable.bg_login_submit_lock); mBtLoginSubmit.setTextColor(ContextCompat.getColor(this,R.color.account_lock_font_color)); } } //登录 private void loginRequest() { AppDatabase.deleteDatabase(this); // 验证是否删除成功 File dbFile = this.getDatabasePath("users.db"); if (!dbFile.exists()) { Log.d("Database", "数据库已彻底删除"); } String andy=mEtLoginUsername.getText().toString(); String pass=mEtLoginPwd.getText().toString(); Context context=this; try { HttpApi.HttpPost(getString(R.string.url_baidu), new User(0, null, andy, pass, 0), new ReturnMethod() { @Override public void Success(String data) { Log.d("success",data); // Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show(); User user =new User(0,"12323123","3211231","12312",0); AuthManager Auth=new AuthManager(context); Auth.register(user) ; Log.d("sql",""+ user.toString()); Log.d("sql",""+ Auth.login(user.getAndy(),user.getPass()) ); } @Override public void failed(String data) { } @Override public void error(Exception e) { // Toast.makeText(MainActivity.this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); Log.d("error",e.getLocalizedMessage()); } }); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } //微博登录 private void weiboLogin() { } //QQ登录 private void qqLogin() { } //微信登录 private void weixinLogin() { } /** * 显示Toast * * @param msg 提示信息内容 */ private void showToast(int msg) { if (null != mToast) { mToast.setText(msg); } else { mToast = Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT); } mToast.show(); } } package com.example.kucun2.entity; import androidx.room.Entity; import androidx.room.Ignore; import androidx.room.PrimaryKey; @Entity(tableName = "users") public class User { @PrimaryKey(autoGenerate = true) private Integer id; private String name; private String andy; private String pass; private Integer role; public int getId() { return id; } public String getName() { return name; } public String getAndy() { return andy; } public String getPass() { return pass; } public int getRole() { return role; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAndy(String andy) { this.andy = andy; } public void setPass(String pass) { this.pass = pass; } public void setRole(int role) { this.role = role; } @Ignore public User(int id, String name, String andy, String pass, int role) { this.id = id; this.name = name; this.andy = andy; this.pass = pass; this.role = role; } public User() { } @Override public String toString() { StringBuilder sb = new StringBuilder("{"); // 处理属性名 sb.append("\"id\": "); // 处理不同数据类型 // 其他对象类型 sb.append((id != null) ? id : "null"); sb.append(","); // 处理属性名 sb.append("\"name\": "); // 处理不同数据类型 // 字符串类型处理(含转义) sb.append("\"") .append(name .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\b", "\\b") .replace("\f", "\\f") .replace("\n", "\\n") .replace("\r", "\\r") .replace("\t", "\\t")) .append("\""); sb.append(","); // 处理属性名 sb.append("\"andy\": "); // 处理不同数据类型 // 字符串类型处理(含转义) sb.append("\"") .append(andy .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\b", "\\b") .replace("\f", "\\f") .replace("\n", "\\n") .replace("\r", "\\r") .replace("\t", "\\t")) .append("\""); sb.append(","); // 处理属性名 sb.append("\"pass\": "); // 处理不同数据类型 // 字符串类型处理(含转义) sb.append("\"") .append(pass .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\b", "\\b") .replace("\f", "\\f") .replace("\n", "\\n") .replace("\r", "\\r") .replace("\t", "\\t")) .append("\""); sb.append(","); // 处理属性名 sb.append("\"role\": "); // 处理不同数据类型 // 其他对象类型 sb.append((role != null) ? role : "null"); sb.append("}"); return sb.toString(); } } package com.example.kucun2.manager; import android.content.Context; import androidx.room.Room; import com.example.kucun2.data.AppDatabase; import com.example.kucun2.data.UserDao; import com.example.kucun2.entity.User; import at.favre.lib.crypto.bcrypt.BCrypt; public class AuthManager { private final BCrypt.Hasher hasher = BCrypt.with(BCrypt.Version.VERSION_2Y); private final UserDao userDao; public AuthManager(Context context) { AppDatabase db = Room.databaseBuilder( context, AppDatabase.class, "app-db" ).build(); userDao = db.userDao(); } public boolean register(User user) { // 密码强度校验 if (!validatePassword(user.getPass())) return false; // 生成BCrypt哈希(自动处理盐值) String hash = hasher.hashToString(12, user.getPass().toCharArray()); // 异步插入数据库 new Thread(() -> { User us = new User(0,"000000",user.getAndy(),hash,0); userDao.insertUser(us); }).start(); return true; } private boolean validatePassword(String password) { return password.length() >= 8 && password.matches(".*[A-Z].*") && password.matches(".*\\d.*"); } public boolean login(String username, String password) { User user = userDao.findUserByUsername(username); if (user == null) return false; BCrypt.Result result = BCrypt.verifyer().verify( password.toCharArray(), user.getPass() ); return result.verified; } }
05-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值