### 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); }
}
```