### Open Image Preview with Gestures and Animations Source: https://context7.com/luweiapp/lwbaselib/llms.txt Launch the image previewer with support for gesture scaling, drag-to-dismiss, transition animations, and indicator styles. This example shows how to set data, current index, and animation properties. ```java // 打开图片预览(点击第 2 张图片,共 5 张) GPreviewBuilder.from(this) .setData(images) .setCurrentIndex(1) // 从第 2 张开始 .setType(GPreviewBuilder.IndicatorType.Dot) // 点型指示器 .setDrag(true, 0.3f) // 开启拖拽关闭,灵敏度 0.3 .setFullscreen(false) // 非全屏 .setDuration(300) // 过渡动画时长 300ms .start(); ``` -------------------------------- ### Start Activity with Result Callback Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md Launch an activity for a result using SimpleForResult. Provide a callback to handle the result, checking for RESULT_OK. ```java /** * 微信号未绑定手机号情况下跳转手机绑定 * 绑定完后授权登录微信 */ public void goToBindPhone(String jsonKey) { Intent intent = new Intent(LoginActivity.this, BindPhoneActivity.class); intent.putExtra("jsonKey", jsonKey); new SimpleForResult(this).startForResult(intent, (requestCode, resultCode, data) -> { if (resultCode == RESULT_OK) { onAuthorizeSuccess();//授权登录成功 } }); } ``` -------------------------------- ### Configure and Use TimerButton Source: https://context7.com/luweiapp/lwbaselib/llms.txt Configure TimerButton via XML attributes for countdown duration, text formats, and colors. Use the start() method to begin the countdown and the stop()/resetStatus() methods for manual control. Implement the Callback interface to handle finish and tick events. ```xml ``` -------------------------------- ### Initialize and Load Banner Data Source: https://context7.com/luweiapp/lwbaselib/llms.txt Initialize the Banner component in your Java code, set an image loader (e.g., bridging Glide), load image URLs, and start the auto-play functionality. Also, set up a click listener for banner items. ```java Banner banner = findViewById(R.id.banner); // 设置图片加载器(桥接 Glide) banner.setImageLoader(new BannerLoader() { @Override public void loadBanner(Context context, Object path, ImageView imageView) { ImageLoaderUtils.getInstance().loadImage(context, imageView, path); } }); // 加载数据并启动 List imageUrls = Arrays.asList( "https://example.com/banner1.jpg", "https://example.com/banner2.jpg", "https://example.com/banner3.jpg" ); banner.setImages(imageUrls).start(); // 设置点击监听 banner.setOnBannerClickListener((position) -> { BannerDetailActivity.start(this, bannerList.get(position).getLink()); }); ``` -------------------------------- ### Control TimerButton Logic Source: https://context7.com/luweiapp/lwbaselib/llms.txt Start the countdown timer using the start() method after initiating an action like sending a verification code. The isStated() method checks if the timer is currently active. Use stop() and resetStatus() for manual resets, for example, on network request failure. ```java TimerButton btnSendCode = findViewById(R.id.btn_send_code); btnSendCode.setOnClickListener(v -> { if (!btnSendCode.isStated()) { String phone = etPhone.getText().toString().trim(); if (TextUtils.isEmpty(phone)) { ToastUtils.showShort("请输入手机号"); return; } // 发送验证码请求 getP().sendVerifyCode(phone); btnSendCode.start(); // 启动倒计时 } }); btnSendCode.setCallback(new TimerButton.Callback() { @Override public void onFinish(TimerButton button) { button.setEnabled(true); // 倒计时结束,恢复按钮可点击 } @Override public void onTick(TimerButton button, long millisUntilFinished) { // 每秒回调,millisUntilFinished 为剩余毫秒 } }); // 手动重置(如网络请求失败时回滚) btnSendCode.stop(); btnSendCode.resetStatus(); ``` -------------------------------- ### Control Banner Auto-Play Lifecycle Source: https://context7.com/luweiapp/lwbaselib/llms.txt Manage the Banner's auto-play behavior by stopping it in onPause and starting it again in onResume to ensure proper lifecycle integration and prevent issues when the activity is not in the foreground. ```java // 在 onPause/onResume 中控制轮播 @Override protected void onPause() { super.onPause(); banner.stopAutoPlay(); } @Override protected void onResume() { super.onResume(); banner.startAutoPlay(); } ``` -------------------------------- ### Encapsulate ConfirmPopup Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md Provides an example of encapsulating a reusable confirmation dialog popup by extending `BasePopup`. This custom popup includes title, description, confirm, and cancel buttons with customizable text and listeners. ```java public class ConfirmPopup extends BasePopup { private Context mContext; private Callback mCallback; private View.OnClickListener mOnCancelListener; private View.OnClickListener mOnConfirmListener; private CharSequence mTitleText; private CharSequence mDescribeText; private CharSequence mCancelText; private CharSequence mConfirmText; private int mCancelColor; private int mConfirmColor; private ConfirmPopup(Context context) { this.mContext = context; setContext(mContext); } public static ConfirmPopup newInstance(Context context) { return new ConfirmPopup(context); } @Override protected void initAttributes() { setContentView(R.layout.base_popup_confirm);//设置布局xml文件 setBackgroundDimEnable(true)//设定打开弹窗时背景变暗 setFocusAndOutsideEnable(true)//点击Popup之外的地方可关掉Popup setWidth(ScreenUtils.getScreenWidth() / 3 * 2)//设定宽度 } @Override protected void initViews(View view, ConfirmPopup popup) { TextView tvTitle = view.findViewById(R.id.tv_title); TextView tvDescribe = view.findViewById(R.id.tv_describe); TextView tvConfirm = view.findViewById(R.id.tv_confirm); TextView tvCancel = view.findViewById(R.id.tv_cancel); if (mCallback != null) { tvConfirm.setOnClickListener(v -> mCallback.onClick(this)); } else if (mOnConfirmListener != null) { tvConfirm.setOnClickListener(mOnConfirmListener); } if (mOnCancelListener != null) { tvCancel.setOnClickListener(mOnCancelListener); } else { tvCancel.setOnClickListener(v -> popup.dismiss());//添加默认取消按钮监听 } if (mTitleText != null) { tvTitle.setText(mTitleText); } if (mDescribeText != null) { tvDescribe.setText(mDescribeText); } if (mConfirmText != null) { tvConfirm.setText(mConfirmText); } if (mCancelText != null) { tvCancel.setText(mCancelText); } if (mCancelColor != 0) { tvConfirm.setTextColor(mCancelColor); } if (mConfirmColor != 0) { tvConfirm.setTextColor(mConfirmColor); } } //设置取消按钮监听 public ConfirmPopup setOnCancelClickListener(View.OnClickListener onCancelListener) { mOnCancelListener = onCancelListener; return this; } //设置确认按钮监听 public ConfirmPopup setOnConfirmClickListener(View.OnClickListener onConfirmListener) { mOnConfirmListener = onConfirmListener; return this; } //设置标题文字 public ConfirmPopup setTitleText(CharSequence titleText) { mTitleText = titleText; return this; } //设置描述文字 public ConfirmPopup setDescribeText(CharSequence describeText) { mDescribeText = describeText; return this; } //设置取消按钮文字 public ConfirmPopup setCancelText(CharSequence cancelText) { mCancelText = cancelText; return this; } //设置确认按钮文字 ``` -------------------------------- ### Network Status Detection Source: https://context7.com/luweiapp/lwbaselib/llms.txt Get the current network type (e.g., 'wifi', '3g', 'disconnect') using Kits.NetWork.getNetworkTypeName. ```java String netType = Kits.NetWork.getNetworkTypeName(context); // "wifi" / "3g" / "disconnect" ``` -------------------------------- ### Prepare Image Data for Preview Source: https://context7.com/luweiapp/lwbaselib/llms.txt Prepare a list of ImageViewInfo objects, each containing an image URL and the Rect bounds of its corresponding thumbnail view on the screen. This is crucial for the transition animation. ```java // 准备数据 List images = new ArrayList<>(); for (String url : imageUrls) { Rect rect = new Rect(); // 从 ImageView 获取实际位置 targetImageView.getGlobalVisibleRect(rect); images.add(new ImageViewInfo(url, rect)); } ``` -------------------------------- ### Create and Show CustomPopup Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md Demonstrates how to create and display a general-purpose custom popup using `CustomPopup`. It shows setting the content view, dimensions, background dimming, focus, and click-outside-to-dismiss behavior, along with a listener for view interactions. ```java CustomPopup.newInstance(this)//创建实例,传入Context .setContentView(R.layout.market_popup_invite_guild)//设置弹窗布局xml文件 .setWidth(ScreenUtils.getScreenWidth() / 3 * 2)//设定宽度 .setBackgroundDimEnable(true)//设定打开弹窗时背景变暗 .setFocusAndOutsideEnable(true)//点击Popup之外的地方可关掉Popup .setOnViewListener((view, popup) -> { EditText etApplyText = view.findViewById(R.id.et_invite_text); //... 此处省略 对View中的控件进行处理 popup.dismiss();//关闭弹窗 }); }) .showAtLocation(getView(), Gravity.CENTER);//居中显示Popup ``` -------------------------------- ### Implement MVP Architecture with LwBaseLib Source: https://context7.com/luweiapp/lwbaselib/llms.txt Demonstrates the implementation of MVP architecture using LwBaseActivity, LwBaseFragment, and LwBasePresent. Ensure RxJava subscriptions are managed with CompositeDisposable to prevent memory leaks. ```java public interface IUserView extends IView { void showUserName(String name); } ``` ```java public class UserPresenter extends LwBasePresent { public void loadUser() { // 使用 put() 管理 RxJava 订阅生命周期 put(UserApi.getUser() .compose(XApi.getScheduler()) .subscribeWith(new ApiSubscriber() { @Override public void onNext(UserBean bean) { if (getV() != null) getV().showUserName(bean.getName()); } @Override protected void onFail(NetError error) { // 错误处理 } })); } } ``` ```java public class UserActivity extends LwBaseActivity implements IUserView { @BindView(R.id.tv_name) TextView tvName; @Override public int getLayoutId() { return R.layout.activity_user; } @Override public UserPresenter newP() { return new UserPresenter(); } @Override public void initView(Bundle savedInstanceState) { /* 初始化 View */ } @Override public void initData() { getP().loadUser(); } @Override public void initEvent() { /* 设置点击事件 */ } @Override public void showUserName(String name) { tvName.setText(name); } // 可选:开启沉浸式状态栏 @Override public boolean isSetStatus() { return true; } // 可选:屏幕适配(以 375dp 宽度为基准) @Override protected int getAdaptSizeVertical() { return 375; } } ``` -------------------------------- ### Show Loading Dialog with Configuration Source: https://context7.com/luweiapp/lwbaselib/llms.txt Display a loading dialog using showDialog, preventing duplicates and Activity destruction crashes. Configure cancellation, gravity, and width percentage. ```java LoadingDialog.newInstance("数据加载中...") .setCanCancel(false) // 不可点击外部取消 .setGravity(Gravity.CENTER) .setDialogWidthPercent(0.7f) // 宽度为屏幕的 70% .showDialog(this); // this = AppCompatActivity ``` -------------------------------- ### 打开摄像头拍摄照片 Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md 使用SimpleForResult启动相机拍摄照片,并将结果文件保存在临时文件中。拍摄成功后,会调用startPictureZoom进行裁剪。 ```java private void openCamera() { try { mTmpFile = FileUtils.createTmpFile(this); } catch (IOException e) { e.printStackTrace(); } simpleForResult.startForResult(PictureIntentHelper.getOpenCameraIntent(this, mTmpFile)) .subscribe((resultInfo -> { if (resultInfo.getResultCode() == RESULT_OK) { mHeadUrl = mTmpFile.getAbsolutePath(); ImageLoaderUtils.getInstance().loadCircleImage(this, ivHeader, mHeadUrl); // 裁剪(如果没有要求可裁剪,也可以不要) startPictureZoom(mTmpFile); } })); } public void startPictureZoom(File srcFile) { try { mZoomOutFile = FileUtils.createTmpFile(this); } catch (IOException e) { e.printStackTrace(); } } ``` -------------------------------- ### Show Confirm Dialog with Callbacks and Animation Source: https://context7.com/luweiapp/lwbaselib/llms.txt Instantiate and display a custom ConfirmDialog. Set confirmation and cancellation callbacks, and specify an animation style. ```java new ConfirmDialog() .setConfirmLitener(() -> { /* 确认逻辑 */ }) .setCancelListener(() -> { /* 取消逻辑 */ }) .setAnimationsStyleId(R.style.BottomActionSheetDialogAnimation) .showDialog(this); ``` -------------------------------- ### Package Management Utilities Source: https://context7.com/luweiapp/lwbaselib/llms.txt Retrieve application version name, version code, and metadata like API keys using Kits.Package. ```java String versionName = Kits.Package.getVersionName(context); // "1.2.3" int versionCode = Kits.Package.getVersionCode(context); // 12 String apiKey = Kits.Package.getAppMetaData(context, "API_KEY"); ``` -------------------------------- ### LoadingDialog Usage Source: https://context7.com/luweiapp/lwbaselib/llms.txt Demonstrates creating and showing a custom loading dialog using BaseDialog, with options to set the loading message and dialog properties. ```APIDOC ## LoadingDialog Usage ### Description Create a custom loading dialog by extending `BaseDialog`. This example shows how to set a custom message and configure dialog properties like cancellation and width. ### Class Definition ```java public class LoadingDialog extends BaseDialog { private String mMsg = "加载中..."; public static LoadingDialog newInstance(String msg) { LoadingDialog dialog = new LoadingDialog(); dialog.mMsg = msg; return dialog; } @Override protected int getLayoutId() { return R.layout.dialog_loading; } @Override public void onCreateView(DialogViewHolder holder, BaseDialog dialog) { holder.getView(R.id.tv_loading, TextView.class).setText(mMsg); } } ``` ### Usage Example ```java LoadingDialog.newInstance("数据加载中...") .setCanCancel(false) .setGravity(Gravity.CENTER) .setDialogWidthPercent(0.7f) .showDialog(this); ``` ``` -------------------------------- ### Open Single Image Preview Source: https://context7.com/luweiapp/lwbaselib/llms.txt This snippet shows how to preview a single image without any indicators. It supports exiting by tapping the black area and can be configured for single-fling behavior. ```java // 单图预览(无指示器) GPreviewBuilder.from(this) .setSingleData(images.get(0)) .setSingleShowType(false) // 单图不显示指示器 .setSingleFling(true) // 点击黑色区域退出 .start(); ``` -------------------------------- ### Create a Custom Loading Dialog Source: https://context7.com/luweiapp/lwbaselib/llms.txt Define a custom loading dialog by extending BaseDialog and implementing getLayoutId and onCreateView. Pass a message to be displayed. ```java public class LoadingDialog extends BaseDialog { private String mMsg = "加载中..."; public static LoadingDialog newInstance(String msg) { LoadingDialog dialog = new LoadingDialog(); dialog.mMsg = msg; return dialog; } @Override protected int getLayoutId() { return R.layout.dialog_loading; } @Override public void onCreateView(DialogViewHolder holder, BaseDialog dialog) { holder.getView(R.id.tv_loading, TextView.class).setText(mMsg); } } ``` -------------------------------- ### Handle Activity Results with SimpleForResult (RxJava) Source: https://context7.com/luweiapp/lwbaselib/llms.txt Simplify startActivityForResult using RxJava Observables. Initialize SimpleForResult with the Activity or Fragment context. Subscribe to the Observable to receive results, handling the resultCode and data. ```java // 初始化(在 Activity 或 Fragment 中) SimpleForResult simpleForResult = new SimpleForResult(this); // 方式一:RxJava Observable 风格 simpleForResult.startForResult(new Intent(this, EditProfileActivity.class)) .subscribe(result -> { if (result.getResultCode() == RESULT_OK) { String newName = result.getData().getStringExtra("name"); tvName.setText(newName); } }); ``` -------------------------------- ### CustomPopup Usage Source: https://context7.com/luweiapp/lwbaselib/llms.txt Demonstrates how to use CustomPopup for creating one-time popups with various configurations like content view, size, background dimming, focus, animation, and event listeners. ```APIDOC ## CustomPopup Usage ### Description Use `CustomPopup` for quick, one-time popup creation. It allows chaining methods to configure size, background dimming, focus, animations, and event listeners. ### Method `CustomPopup.newInstance(Context).setContentView(layoutResId).setWidth(width).setBackgroundDimEnable(boolean).setDimValue(float).setFocusAndOutsideEnable(boolean).setAnimationStyle(animResId).setOnViewListener((view, popup) -> { ... }).setOnDismissListener(() -> { ... }).showAtLocation(parentView, gravity, xOffset, yOffset)` ### Example ```java CustomPopup.newInstance(this) .setContentView(R.layout.popup_custom) .setWidth(ScreenUtils.getScreenWidth() * 2 / 3) .setBackgroundDimEnable(true) .setDimValue(0.6f) .setFocusAndOutsideEnable(true) .setAnimationStyle(R.style.popup_anim) .setOnViewListener((view, popup) -> { Button btnConfirm = view.findViewById(R.id.btn_confirm); btnConfirm.setOnClickListener(v -> { popup.dismiss(); }); }) .setOnDismissListener(() -> Log.d("Popup", "已关闭")) .showAtLocation(getWindow().getDecorView(), Gravity.CENTER); ``` ``` -------------------------------- ### Register Global NetProvider for XApi Source: https://context7.com/luweiapp/lwbaselib/llms.txt Configure global network settings like interceptors, timeouts, HTTPS, and error handling in your Application class. ```java public class MyApplication extends LwBaseApplication { @Override public void onCreate() { super.onCreate(); XApi.registerProvider(new NetProvider() { @Override public Interceptor[] configInterceptors() { return null; } @Override public void configHttps(OkHttpClient.Builder builder) { /* 配置 SSL */ } @Override public CookieJar configCookie() { return null; } @Override public RequestHandler configHandler() { return (request, builder) -> { // 统一添加请求头,如 token builder.header("Authorization", "Bearer " + UserManager.getToken()); return builder.build(); }; } @Override public long configConnectTimeoutMills() { return 15_000L; } @Override public long configReadTimeoutMills() { return 15_000L; } @Override public boolean configLogEnable() { return BuildConfig.DEBUG; } @Override public boolean handleError(NetError error) { if (error.getCode() == NetError.AuthError) { // 全局处理 401,跳转登录 LoginActivity.startLogin(); return true; // 返回 true 表示已处理,不再回调 onFail } return false; } @Override public Converter.Factory configConverterFactory() { return JsonConverterFactory.create(); // 使用库内自定义 JSON 转换器 } }); } } ``` -------------------------------- ### ConfirmDialog Usage Source: https://context7.com/luweiapp/lwbaselib/llms.txt Illustrates how to implement a reusable confirmation dialog with confirm and cancel actions using BaseDialog. ```APIDOC ## ConfirmDialog Usage ### Description Implement a custom confirmation dialog by extending `BaseDialog`. This example provides listeners for confirm and cancel actions and allows setting custom animation styles. ### Class Definition ```java public class ConfirmDialog extends BaseDialog { @Override protected int getLayoutId() { return R.layout.dialog_confirm; } @Override public void onCreateView(DialogViewHolder holder, BaseDialog dialog) { holder.getView(R.id.btn_confirm, Button.class).setOnClickListener(v -> { if (mConfirmLitener != null) mConfirmLitener.onConfirm(); dismiss(); }); holder.getView(R.id.btn_cancel, Button.class).setOnClickListener(v -> { if (mCancelListener != null) mCancelListener.onCancel(); dismiss(); }); } } ``` ### Usage Example ```java new ConfirmDialog() .setConfirmLitener(() -> { /* 确认逻辑 */ }) .setCancelListener(() -> { /* 取消逻辑 */ }) .setAnimationsStyleId(R.style.BottomActionSheetDialogAnimation) .showDialog(this); ``` ``` -------------------------------- ### Multi-Type RecyclerView Adapter with LwAdapter Source: https://context7.com/luweiapp/lwbaselib/llms.txt Implement a multi-type RecyclerView adapter by defining data classes, implementing LwItemBinder, and registering them with LwAdapter. Supports header, footer, and empty view extensions. Item and child view click listeners can be configured. ```java public class ArticleBean { public String title; public String imageUrl; } public class AdBannerBean { public String bannerUrl; } ``` ```java public class ArticleBinder extends LwItemBinder { @Override protected View getView(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) { return inflater.inflate(R.layout.item_article, parent, false); } @Override protected void onBind(@NonNull LwViewHolder holder, @NonNull ArticleBean item) { holder.getView(R.id.tv_title, TextView.class).setText(item.title); ImageLoaderUtils.getInstance().loadImage( holder.itemView.getContext(), holder.getView(R.id.iv_cover, ImageView.class), item.imageUrl ); } } ``` ```java RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); ArticleBinder articleBinder = new ArticleBinder(); articleBinder.setOnItemClickListener((holder, item) -> { // 点击整个 Item ArticleDetailActivity.start(this, item); }); articleBinder.setOnChildClickListener(R.id.iv_cover, (holder, child, item) -> { // 点击封面图片 ImagePreviewActivity.start(this, item.imageUrl); }); LwAdapter adapter = new LwAdapter(new Items()); adapter.register(ArticleBean.class, articleBinder); adapter.register(AdBannerBean.class, new AdBannerBinder()); // 全局配置空数据视图 LwAdapter.getConfig().setGlobalEmptyView(R.layout.view_empty); recyclerView.setAdapter(adapter); // 加载数据 Items items = new Items(); items.add(new AdBannerBean("https://img.example.com/banner.jpg")); for (Article a : articles) items.add(new ArticleBean(a)); adapter.addAll(items); adapter.notifyDataSetChanged(); // 动态添加 Header / Footer adapter.addHeader(new HeaderBean("推荐内容")); adapter.addFooter(new FooterBean("—— 没有更多了 ——")); ``` -------------------------------- ### Create a One-Time Popup with CustomPopup Source: https://context7.com/luweiapp/lwbaselib/llms.txt Use CustomPopup for quick, one-time popups. Configure properties like content view, size, background dimming, focus, animation, and event listeners. ```java CustomPopup.newInstance(this) .setContentView(R.layout.popup_custom) .setWidth(ScreenUtils.getScreenWidth() * 2 / 3) .setBackgroundDimEnable(true) // 背景变暗 .setDimValue(0.6f) // 变暗透明度 .setFocusAndOutsideEnable(true) // 点击外部关闭 .setAnimationStyle(R.style.popup_anim) .setOnViewListener((view, popup) -> { Button btnConfirm = view.findViewById(R.id.btn_confirm); btnConfirm.setOnClickListener(v -> { // 处理确认逻辑 popup.dismiss(); }); }) .setOnDismissListener(() -> Log.d("Popup", "已关闭")) .showAtLocation(getWindow().getDecorView(), Gravity.CENTER); ``` -------------------------------- ### Show Reusable ConfirmPopup with Anchor Source: https://context7.com/luweiapp/lwbaselib/llms.txt Instantiate and configure the reusable ConfirmPopup, setting title, description, and callback. Use showAtAnchorView for positioning relative to another view. ```java ConfirmPopup.newInstance(this) .setTitle("确认删除?") .setDesc("此操作不可撤销") .setCallback(popup -> { deleteItem(); popup.dismiss(); }) .showAtAnchorView(btnDelete, YGravity.ABOVE, XGravity.CENTER); ``` -------------------------------- ### Make Network Request with XApi Source: https://context7.com/luweiapp/lwbaselib/llms.txt Initiate network requests in your Presenter, applying transformers for error handling and thread switching. ```java public class UserPresenter extends LwBasePresent { private static final String BASE_URL = "https://api.example.com/"; public void loadUser(String userId) { UserService service = XApi.get(BASE_URL, UserService.class); put(service.getUserInfo(userId) .compose(XApi.getApiTransformer()) // 统一处理业务错误 .compose(XApi.getScheduler()) // IO -> Main 线程切换 .subscribeWith(new ApiSubscriber() { @Override public void onNext(UserBean bean) { if (getV() != null) getV().showUser(bean); } @Override protected void onFail(NetError error) { // NetError.NoConnectError / ParseError / BusinessError / AuthError ToastUtils.showShort(error.getMessage()); } })); } } ``` -------------------------------- ### File Operations Source: https://context7.com/luweiapp/lwbaselib/llms.txt Perform common file operations like writing, reading, copying, checking size, existence, and deleting files or directories recursively using Kits.File. ```java Kits.File.writeFile("/sdcard/log.txt", "日志内容", true); // 追加写入 StringBuilder content = Kits.File.readFile("/sdcard/log.txt", "UTF-8"); Kits.File.copyFile("/sdcard/src.jpg", "/sdcard/dst.jpg"); long size = Kits.File.getFileSize("/sdcard/video.mp4"); // 返回字节数 boolean exists = Kits.File.isFileExist("/sdcard/photo.jpg"); Kits.File.deleteFile("/sdcard/tmp/"); // 支持递归删除目录 ``` -------------------------------- ### 设置倒计时按钮回调 Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md 设置TimerButton的回调,用于监听倒计时结束和进行中的事件。在倒计时结束时,按钮会被启用。 ```java mTimerbutton.setCallback(new TimerButton.Callback() { @Override public void onFinish(TimerButton button) { button.setEnabled(true); } @Override public void onTick(TimerButton button, long millisUntilFinished) { } }); ``` -------------------------------- ### Configure ImageLoaderUtils Source: https://context7.com/luweiapp/lwbaselib/llms.txt Customize ImageLoaderUtils with a specific configuration including disk and memory cache sizes, and default error/placeholder drawables. Use setLoaderConfig() to apply these settings before loading images. ```java // 自定义配置(50MB 磁盘缓存,10MB 内存缓存) ImageLoaderConfig config = new ImageLoaderConfig.Builder() .setMaxDishCache(1024 * 1024 * 50) .setMaxMemoryCache(1024 * 1024 * 10) .setErrorPicRes(R.mipmap.ic_error) .setPlacePicRes(R.mipmap.ic_placeholder) .create(); loader.setLoaderConfig(config); // 清理内存缓存 loader.clearMemory(context); ``` -------------------------------- ### 打开图片选择器(SimpleForResult) Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md 使用SimpleForResult启动图片选择器,无需在onActivityResult中处理结果。此方法用于选择单个图片。 ```java public void openImageSelect2() { // todo:打开摄像头、读写权限 // todo:在 AndroidManifest.xml 中添加 simpleForResult.startForResult(PictureIntentHelper.getSelectSingleImageIntent(this, false)) .subscribe(resultInfo -> { if (resultInfo.getResultCode() == RESULT_OK) { List urls = resultInfo.getData().getStringArrayListExtra(MultiImageSelectorActivity.EXTRA_RESULT); if (urls != null && urls.size() > 0) { mHeadUrl = urls.get(0); ImageLoaderUtils.getInstance().loadCircleImage(this, ivHeader, mHeadUrl); } } }); } ``` -------------------------------- ### ConfirmPopup (Custom BasePopup) Source: https://context7.com/luweiapp/lwbaselib/llms.txt Shows how to extend BasePopup to create a reusable ConfirmPopup with custom title, description, and callback functionality. ```APIDOC ## ConfirmPopup (Custom BasePopup) ### Description Encapsulate business logic by extending `BasePopup`. This example creates a reusable `ConfirmPopup` with title, description, and confirmation/cancel callbacks. ### Class Definition ```java public class ConfirmPopup extends BasePopup { private Callback mCallback; private CharSequence mTitle, mDesc; private ConfirmPopup(Context ctx) { setContext(ctx); } public static ConfirmPopup newInstance(Context ctx) { return new ConfirmPopup(ctx); } @Override protected void initAttributes() { setContentView(R.layout.base_popup_confirm); setBackgroundDimEnable(true); setFocusAndOutsideEnable(true); setWidth(ScreenUtils.getScreenWidth() * 2 / 3); } @Override protected void initViews(View view, ConfirmPopup popup) { ((TextView) view.findViewById(R.id.tv_title)).setText(mTitle); ((TextView) view.findViewById(R.id.tv_desc)).setText(mDesc); view.findViewById(R.id.btn_confirm).setOnClickListener(v -> { if (mCallback != null) mCallback.onConfirm(popup); }); view.findViewById(R.id.btn_cancel).setOnClickListener(v -> popup.dismiss()); } public ConfirmPopup setTitle(CharSequence title) { mTitle = title; return this; } public ConfirmPopup setDesc(CharSequence desc) { mDesc = desc; return this; } public ConfirmPopup setCallback(Callback cb) { mCallback = cb; return this; } public interface Callback { void onConfirm(ConfirmPopup popup); } } ``` ### Usage Example ```java ConfirmPopup.newInstance(this) .setTitle("确认删除?") .setDesc("此操作不可撤销") .setCallback(popup -> { deleteItem(); popup.dismiss(); }) .showAtAnchorView(btnDelete, YGravity.ABOVE, XGravity.CENTER); ``` ``` -------------------------------- ### ImageLoaderUtils Source: https://context7.com/luweiapp/lwbaselib/llms.txt An image loading utility singleton based on the strategy pattern, defaulting to Glide. It provides methods for various image loading types including normal, circular, rounded, blurred, GIF, local, and Drawable loading. The underlying implementation can be switched using `setStrategy()`. ```APIDOC ## ImageLoaderUtils ### Description An image loading utility singleton based on the strategy pattern, defaulting to Glide. It provides methods for ordinary loading, circular, rounded, Gaussian blur, GIF, local, and Drawable loading. The underlying implementation can be switched via `setStrategy()`. ### Usage Examples ```java ImageLoaderUtils loader = ImageLoaderUtils.getInstance(); // 普通图片加载(带默认占位和错误图) loader.loadImage(context, imageView, "https://example.com/avatar.jpg"); // 圆形头像 loader.loadCircleImage(context, ivAvatar, user.getAvatarUrl()); // 圆角图片(半径 10dp) loader.loadRoundedImage(context, ivCover, article.getCoverUrl(), 10); // 高斯模糊背景(自定义模糊度) loader.loadBlurImage(context, ivBackground, imageUrl, 25); // 加载 GIF loader.loadGifImage(context, ivGif, "https://example.com/loading.gif"); // 从本地路径加载 loader.loadImageFromLocal(context, ivPreview, "/sdcard/DCIM/photo.jpg"); // 从 Drawable 资源加载 loader.loadImageFromDrawable(context, ivIcon, R.drawable.ic_placeholder); // 自定义配置(50MB 磁盘缓存,10MB 内存缓存) ImageLoaderConfig config = new ImageLoaderConfig.Builder() .setMaxDishCache(1024 * 1024 * 50) .setMaxMemoryCache(1024 * 1024 * 10) .setErrorPicRes(R.mipmap.ic_error) .setPlacePicRes(R.mipmap.ic_placeholder) .create(); loader.setLoaderConfig(config); // 清理内存缓存 loader.clearMemory(context); ``` ``` -------------------------------- ### Handle Activity Results with SimpleForResult (Callback) Source: https://context7.com/luweiapp/lwbaselib/llms.txt Use SimpleForResult with a callback style for handling activity results. This approach avoids manual requestCode management. Pass an Intent and a lambda function to startForResult to process the results. ```java // 方式二:Callback 风格 Intent intent = new Intent(this, BindPhoneActivity.class); intent.putExtra("source", "login"); simpleForResult.startForResult(intent, (requestCode, resultCode, data) -> { if (resultCode == RESULT_OK) { onBindSuccess(); } }); // 直接传入 Class(无需手动创建 Intent) simpleForResult.startForResult(CameraActivity.class, (req, res, data) -> { if (res == RESULT_OK) { String photoPath = data.getStringExtra("photo_path"); ImageLoaderUtils.getInstance().loadCircleImage(this, ivAvatar, photoPath); } }); ``` -------------------------------- ### 打开图片选择器(onActivityResult) Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md 使用MultiImageSelector打开图库进行图片选择,结果在onActivityResult中处理。需要在AndroidManifest.xml中注册MultiImageSelectorActivity。 ```java public void openImageSelect() { // todo:打开摄像头、读写权限 // todo:在 AndroidManifest.xml 中添加 MultiImageSelector.create(this) .single() .showCamera(true) .start(this, REQUEST_SELECT_CODE); ``` -------------------------------- ### GPreviewBuilder Source: https://context7.com/luweiapp/lwbaselib/llms.txt Enables image preview functionality with gesture support for zooming and dragging to dismiss. It includes transition animations and customizable page indicators (dots or numbers), supporting both lists of images and single image previews. ```APIDOC ## 图片预览 — `GPreviewBuilder` `GPreviewBuilder` 提供支持手势缩放、拖拽下滑关闭、过渡动画、点/数字两种翻页指示器的图片预览功能,支持图片列表和单图预览,也可扩展支持视频播放回调。 ```java // 定义数据实体(实现 IThumbViewInfo 接口) public class ImageViewInfo implements IThumbViewInfo, Parcelable { private String url; private Rect bounds; // 缩略图在屏幕上的位置(用于过渡动画) @Override public String getUrl() { return url; } @Override public Rect getBounds() { return bounds; } // ... Parcelable 实现 } // 准备数据 List images = new ArrayList<>(); for (String url : imageUrls) { Rect rect = new Rect(); // 从 ImageView 获取实际位置 targetImageView.getGlobalVisibleRect(rect); images.add(new ImageViewInfo(url, rect)); } // 打开图片预览(点击第 2 张图片,共 5 张) GPreviewBuilder.from(this) .setData(images) .setCurrentIndex(1) // 从第 2 张开始 .setType(GPreviewBuilder.IndicatorType.Dot) // 点型指示器 .setDrag(true, 0.3f) // 开启拖拽关闭,灵敏度 0.3 .setFullscreen(false) // 非全屏 .setDuration(300) // 过渡动画时长 300ms .start(); // 单图预览(无指示器) GPreviewBuilder.from(this) .setSingleData(images.get(0)) .setSingleShowType(false) // 单图不显示指示器 .setSingleFling(true) // 点击黑色区域退出 .start(); ``` ``` -------------------------------- ### Date and Time Formatting Source: https://context7.com/luweiapp/lwbaselib/llms.txt Format timestamps into various string representations (YYYY-MM-DD HH:MM:SS, YYYY-MM-DD, HH:MM) and check date-related properties using Kits.Date. ```java long now = System.currentTimeMillis(); String date1 = Kits.Date.getYmdhms(now); // "2024-01-15 14:30:00" String date2 = Kits.Date.getYmd(now); // "2024-01-15" String date3 = Kits.Date.getHm(now); // "14:30" boolean today = Kits.Date.isToday(timestamp); boolean sameDay = Kits.Date.isSameDay(ts1, ts2); int month = Kits.Date.getMonth(now); // 1-12 int days = Kits.Date.getDaysInMonth(now); // 当月天数 ``` -------------------------------- ### Create a Custom Confirm Dialog Source: https://context7.com/luweiapp/lwbaselib/llms.txt Implement a custom confirmation dialog by extending BaseDialog. Define layout and attach click listeners for confirm and cancel actions. ```java public class ConfirmDialog extends BaseDialog { @Override protected int getLayoutId() { return R.layout.dialog_confirm; } @Override public void onCreateView(DialogViewHolder holder, BaseDialog dialog) { holder.getView(R.id.btn_confirm, Button.class).setOnClickListener(v -> { if (mConfirmLitener != null) mConfirmLitener.onConfirm(); dismiss(); }); holder.getView(R.id.btn_cancel, Button.class).setOnClickListener(v -> { if (mCancelListener != null) mCancelListener.onCancel(); dismiss(); }); } } ``` -------------------------------- ### Select Multiple Images with SimpleForResult Source: https://context7.com/luweiapp/lwbaselib/llms.txt This snippet demonstrates selecting multiple images (up to 9) using SimpleForResult. The selected image paths are returned for further processing, such as uploading. ```java // 多选图片(最多 9 张) simpleForResult.startForResult( PictureIntentHelper.getSelectMultiImageIntent(this, true, 9) ).subscribe(result -> { if (result.getResultCode() == RESULT_OK) { List paths = result.getData() .getStringArrayListExtra(MultiImageSelectorActivity.EXTRA_RESULT); uploadImages(paths); } }); ``` -------------------------------- ### SimpleForResult Source: https://context7.com/luweiapp/lwbaselib/llms.txt Simplifies handling Activity results by injecting a no-UI Fragment into Activity/Fragment. It transforms `startActivityForResult` + `onActivityResult` into RxJava Observable chain callbacks, eliminating the need for `requestCode` management. ```APIDOC ## SimpleForResult ### Description Simplifies Activity return results by injecting a no-UI Fragment into Activity/Fragment, transforming `startActivityForResult` + `onActivityResult` into RxJava Observable chain callbacks, completely eliminating `requestCode` management issues. ### Usage Examples ```java // Initialization (in Activity or Fragment) SimpleForResult simpleForResult = new SimpleForResult(this); // Method 1: RxJava Observable style simpleForResult.startForResult(new Intent(this, EditProfileActivity.class)) .subscribe(result -> { if (result.getResultCode() == RESULT_OK) { String newName = result.getData().getStringExtra("name"); tvName.setText(newName); } }); // Method 2: Callback style Intent intent = new Intent(this, BindPhoneActivity.class); intent.putExtra("source", "login"); simpleForResult.startForResult(intent, (requestCode, resultCode, data) -> { if (resultCode == RESULT_OK) { onBindSuccess(); } }); // Directly pass Class (no need to manually create Intent) simpleForResult.startForResult(CameraActivity.class, (req, res, data) -> { if (res == RESULT_OK) { String photoPath = data.getStringExtra("photo_path"); ImageLoaderUtils.getInstance().loadCircleImage(this, ivAvatar, photoPath); } }); ``` ``` -------------------------------- ### Define Data Entity for Image Preview Source: https://context7.com/luweiapp/lwbaselib/llms.txt Implement the IThumbViewInfo and Parcelable interfaces to create a data entity for image preview. This includes storing the image URL and the bounds of the thumbnail. ```java // 定义数据实体(实现 IThumbViewInfo 接口) public class ImageViewInfo implements IThumbViewInfo, Parcelable { private String url; private Rect bounds; // 缩略图在屏幕上的位置(用于过渡动画) @Override public String getUrl() { return url; } @Override public Rect getBounds() { return bounds; } // ... Parcelable 实现 } ``` -------------------------------- ### Select Images with Native onActivityResult Callback Source: https://context7.com/luweiapp/lwbaselib/llms.txt This method uses the traditional onActivityResult callback for image selection. Configure the maximum number of images and whether to include the camera option. ```java // 原生方式(onActivityResult 回调) MultiImageSelector.create(this) .showCamera(true) .count(3) .multi() .start(this, REQUEST_SELECT_IMAGE); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_SELECT_IMAGE && resultCode == RESULT_OK) { List paths = data.getStringArrayListExtra(MultiImageSelector.EXTRA_RESULT); // 处理选择的图片 } } ``` -------------------------------- ### Send Sticky Event with RxBus Source: https://context7.com/luweiapp/lwbaselib/llms.txt Post a sticky event that will be received by any subscriber, even if they registered after the event was posted. ```java RxBus.getInstance().postStick(new UserUpdateEvent(UserUpdateEvent.FLAG_AVATAR_CHANGED)); ``` -------------------------------- ### Global TitleBar Configuration Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md Configure global properties for the TitleBar in your Application class's onCreate method. This allows for consistent styling across all TitleBars. ```java public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); TitleBar.getConfig() .setTitleTextColor(Color.RED) .setTitleTextSize(20) .setBackGroundColor(Color.GRAY); } } ``` -------------------------------- ### 选择多个图片(SimpleForResult) Source: https://github.com/luweiapp/lwbaselib/blob/master/README.md 使用SimpleForResult选择多个图片,并指定可选数量。结果通过订阅处理。 ```java public void openImageSelect3() { // todo:打开摄像头、读写权限 // todo:在 AndroidManifest.xml 中添加 simpleForResult.startForResult(PictureIntentHelper.getSelectMultiImageIntent(this, false,3)) .subscribe(resultInfo -> { if (resultInfo.getResultCode() == RESULT_OK) { List urls = resultInfo.getData().getStringArrayListExtra(MultiImageSelectorActivity.EXTRA_RESULT); if (urls != null && urls.size() > 0) { mHeadUrl = urls.get(0); ImageLoaderUtils.getInstance().loadCircleImage(this, ivHeader, mHeadUrl); } } }); } ``` -------------------------------- ### Null and Empty Checks Source: https://context7.com/luweiapp/lwbaselib/llms.txt Check if a list is null or empty, a string is null or empty (''), or an object is null using Kits.Empty.check. ```java boolean isEmpty = Kits.Empty.check(list); // null 或 empty 返回 true boolean isNull = Kits.Empty.check(str); // null 或 "" 返回 true boolean isBlank = Kits.Empty.check(obj); // null 返回 true ``` -------------------------------- ### Configure Banner Component in XML Source: https://context7.com/luweiapp/lwbaselib/llms.txt Define the Banner component in your XML layout. Key attributes include auto-play, interval time, indicator visibility, and single transformation effect. ```xml ``` -------------------------------- ### Receive Sticky Event with RxBus Source: https://context7.com/luweiapp/lwbaselib/llms.txt Subscribe to sticky events using ofStickType. These events are delivered immediately upon registration. ```java RxBus.getInstance() .register(this) .ofStickType(UserUpdateEvent.class) .subscribe(event -> { /* 处理粘性事件 */ }); ``` -------------------------------- ### Encapsulate a Reusable ConfirmPopup Source: https://context7.com/luweiapp/lwbaselib/llms.txt Extend BasePopup to create reusable business-specific popups like ConfirmPopup. Override initAttributes and initViews to define layout and behavior. ```java public class ConfirmPopup extends BasePopup { private Callback mCallback; private CharSequence mTitle, mDesc; private ConfirmPopup(Context ctx) { setContext(ctx); } public static ConfirmPopup newInstance(Context ctx) { return new ConfirmPopup(ctx); } @Override protected void initAttributes() { setContentView(R.layout.base_popup_confirm); setBackgroundDimEnable(true); setFocusAndOutsideEnable(true); setWidth(ScreenUtils.getScreenWidth() * 2 / 3); } @Override protected void initViews(View view, ConfirmPopup popup) { ((TextView) view.findViewById(R.id.tv_title)).setText(mTitle); ((TextView) view.findViewById(R.id.tv_desc)).setText(mDesc); view.findViewById(R.id.btn_confirm).setOnClickListener(v -> { if (mCallback != null) mCallback.onConfirm(popup); }); view.findViewById(R.id.btn_cancel).setOnClickListener(v -> popup.dismiss()); } public ConfirmPopup setTitle(CharSequence title) { mTitle = title; return this; } public ConfirmPopup setDesc(CharSequence desc) { mDesc = desc; return this; } public ConfirmPopup setCallback(Callback cb) { mCallback = cb; return this; } public interface Callback { void onConfirm(ConfirmPopup popup); } } ```