修复位置列表项中任务列表控件的资源释放后,未再次加载任务列表的问题。
This commit is contained in:
		| @@ -1,8 +1,8 @@ | ||||
| #Created by .winboll/winboll_app_build.gradle | ||||
| #Tue Oct 07 02:42:31 HKT 2025 | ||||
| #Wed Oct 08 13:15:15 GMT 2025 | ||||
| stageCount=11 | ||||
| libraryProject= | ||||
| baseVersion=15.0 | ||||
| publishVersion=15.0.10 | ||||
| buildCount=0 | ||||
| buildCount=4 | ||||
| baseBetaVersion=15.0.11 | ||||
|   | ||||
| @@ -3,9 +3,19 @@ package cc.winboll.studio.positions.adapters; | ||||
| /** | ||||
|  * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com> | ||||
|  * @Date 2025/09/29 20:25 | ||||
|  * @Describe 位置数据适配器(集成PositionTaskListView,移除未定义onDestroy,Java 7语法适配) | ||||
|  * @Describe 位置数据适配器(修复视图复用资源加载,支持滚动后重新绑定数据,Java 7语法适配) | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Java 7 语法严格适配 + 视图复用资源加载修复: | ||||
|  * 1. 保留无Lambda/弱引用/线程安全集合等原有适配 | ||||
|  * 2. 修复核心问题:移除 onViewDetachedFromWindow 中关键资源释放,改为 onBind 时重新绑定 | ||||
|  * 3. 强化资源复用:任务视图/距离控件在复用后自动从服务同步最新数据,确保滚动后数据不丢失 | ||||
|  * 4. 优化缓存逻辑:仅清理脱离屏幕且无效的控件缓存,有效控件保留引用供局部更新(如距离) | ||||
|  */ | ||||
| import android.content.Context; | ||||
| import android.text.TextUtils; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| @@ -14,30 +24,18 @@ import android.widget.Button; | ||||
| import android.widget.EditText; | ||||
| import android.widget.RadioGroup; | ||||
| import android.widget.TextView; | ||||
| import android.text.TextUtils; | ||||
| import android.widget.Toast; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | ||||
| import cc.winboll.studio.libappbase.LogUtils; | ||||
| import cc.winboll.studio.positions.R; | ||||
| import cc.winboll.studio.positions.models.PositionModel; | ||||
| import cc.winboll.studio.positions.models.PositionTaskModel; | ||||
| import cc.winboll.studio.positions.services.MainService; | ||||
| import cc.winboll.studio.positions.views.PositionTaskListView; | ||||
|  | ||||
| import java.lang.ref.WeakReference; | ||||
| import java.util.ArrayList; | ||||
| import java.util.ConcurrentModificationException; | ||||
| import java.util.Iterator; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
|  | ||||
| /** | ||||
|  * Java 7 语法严格适配: | ||||
|  * 1. 无Lambda/方法引用,全匿名内部类实现回调 | ||||
|  * 2. 移除未定义的 taskView.onDestroy(),改用「清空数据+解绑监听」替代资源释放 | ||||
|  * 3. 弱引用管理服务/控件,杜绝内存泄漏 | ||||
|  * 4. PositionTaskListView 初始化/同步/资源释放全链路适配 | ||||
|  */ | ||||
| public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements MainService.TaskUpdateListener { | ||||
|     public static final String TAG = "PositionAdapter"; | ||||
|  | ||||
| @@ -57,10 +55,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     private final Context mContext; | ||||
|     private final ArrayList<PositionModel> mCachedPositionList; // 位置缓存(与MainService同步) | ||||
|     private final WeakReference<MainService> mMainServiceRef;   // 弱引用MainService,防内存泄漏 | ||||
|     // 控件缓存:位置ID → 对应任务列表视图(分别缓存简单/编辑模式,避免引用混淆) | ||||
|     // 控件缓存:位置ID → 对应任务列表视图(分别缓存简单/编辑模式,支持复用后快速同步) | ||||
|     private final ConcurrentHashMap<String, PositionTaskListView> mSimpleTaskViewMap; | ||||
|     private final ConcurrentHashMap<String, PositionTaskListView> mEditTaskViewMap; | ||||
|     // 距离控件缓存(用于局部更新距离UI) | ||||
|     // 距离控件缓存(用于局部更新距离UI,保留有效引用避免复用后更新失效) | ||||
|     private final ConcurrentHashMap<String, TextView> mPosDistanceViewMap; | ||||
|  | ||||
|     // 回调接口(仅处理位置逻辑,任务逻辑通过PositionTaskListView+MainService完成) | ||||
| @@ -81,7 +79,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     public PositionAdapter(Context context, ArrayList<PositionModel> cachedPositionList, MainService mainService) { | ||||
|         this.mContext = context; | ||||
|         // 容错处理:避免传入null导致空指针 | ||||
|         this.mCachedPositionList = (cachedPositionList!= null)? cachedPositionList : new ArrayList<PositionModel>(); | ||||
|         this.mCachedPositionList = (cachedPositionList != null) ? cachedPositionList : new ArrayList<PositionModel>(); | ||||
|         // 弱引用MainService:防止Adapter持有服务导致内存泄漏(Java 7 弱引用语法) | ||||
|         this.mMainServiceRef = new WeakReference<MainService>(mainService); | ||||
|         // 初始化控件缓存(线程安全集合,适配多线程更新场景) | ||||
| @@ -90,7 +88,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|         this.mPosDistanceViewMap = new ConcurrentHashMap<String, TextView>(); | ||||
|  | ||||
|         // 注册MainService任务监听:服务任务变化时同步刷新任务列表视图 | ||||
|         if (mainService!= null) { | ||||
|         if (mainService != null) { | ||||
|             mainService.registerTaskUpdateListener(this); | ||||
|             LogUtils.d(TAG, "已注册MainService任务监听,确保任务数据与服务同步"); | ||||
|         } else { | ||||
| @@ -101,12 +99,12 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     } | ||||
|  | ||||
|     // ========================================================================= | ||||
|     // RecyclerView 核心方法(视图类型判断+创建+绑定,集成任务列表视图) | ||||
|     // RecyclerView 核心方法(强化视图复用逻辑,复用后自动重新绑定资源) | ||||
|     // ========================================================================= | ||||
|     @Override | ||||
|     public int getItemViewType(int position) { | ||||
|         PositionModel posModel = getPositionByIndex(position); | ||||
|         return (posModel!= null && posModel.isSimpleView())? VIEW_TYPE_SIMPLE : VIEW_TYPE_EDIT; | ||||
|         return (posModel != null && posModel.isSimpleView()) ? VIEW_TYPE_SIMPLE : VIEW_TYPE_EDIT; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -131,24 +129,26 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|         final String posId = posModel.getPositionId(); | ||||
|         MainService mainService = mMainServiceRef.get(); | ||||
|  | ||||
|         // 按视图类型绑定数据(简单模式/编辑模式) | ||||
|         // 按视图类型绑定数据(简单模式/编辑模式)—— 核心修复:复用后重新绑定所有资源 | ||||
|         if (holder instanceof SimpleViewHolder) { | ||||
|             LogUtils.d(TAG, "instanceof SimpleViewHolder(复用/新创建):位置ID=" + posId); | ||||
|             SimpleViewHolder simpleHolder = (SimpleViewHolder) holder; | ||||
|             // 1. 绑定位置基础数据(经纬度/备注/距离) | ||||
|             // 1. 重新绑定位置基础数据(经纬度/备注/距离,确保复用后显示最新数据) | ||||
|             bindSimplePositionData(simpleHolder, posModel); | ||||
|             // 2. 初始化+绑定简单模式任务列表视图(仅显示已启用任务) | ||||
|             // 2. 重新初始化+绑定简单模式任务视图(复用后从服务同步最新任务,避免数据丢失) | ||||
|             initAndBindSimpleTaskView(simpleHolder.ptlvSimpleTasks, posId, mainService); | ||||
|             // 3. 缓存简单模式任务视图+距离控件 | ||||
|             // 3. 缓存/更新简单模式任务视图+距离控件(覆盖旧缓存,确保引用最新控件) | ||||
|             mSimpleTaskViewMap.put(posId, simpleHolder.ptlvSimpleTasks); | ||||
|             mPosDistanceViewMap.put(posId, simpleHolder.tvSimpleDistance); | ||||
|  | ||||
|         } else if (holder instanceof EditViewHolder) { | ||||
|             LogUtils.d(TAG, "instanceof EditViewHolder(复用/新创建):位置ID=" + posId); | ||||
|             EditViewHolder editHolder = (EditViewHolder) holder; | ||||
|             // 1. 绑定位置基础数据(经纬度/备注/距离/距离开关) | ||||
|             // 1. 重新绑定位置基础数据(经纬度/备注/距离/距离开关,复用后显示最新状态) | ||||
|             bindEditPositionData(editHolder, posModel, position); | ||||
|             // 2. 初始化+绑定编辑模式任务列表视图(支持增删改查) | ||||
|             // 2. 重新初始化+绑定编辑模式任务视图(复用后同步服务最新任务,支持增删改) | ||||
|             initAndBindEditTaskView(editHolder.ptlvEditTasks, posId, mainService, editHolder.btnAddTask); | ||||
|             // 3. 缓存编辑模式任务视图+距离控件 | ||||
|             // 3. 缓存/更新编辑模式任务视图+距离控件(覆盖旧缓存,确保引用最新控件) | ||||
|             mEditTaskViewMap.put(posId, editHolder.ptlvEditTasks); | ||||
|             mPosDistanceViewMap.put(posId, editHolder.tvEditDistance); | ||||
|         } | ||||
| @@ -157,39 +157,38 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     @Override | ||||
|     public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { | ||||
|         super.onViewDetachedFromWindow(holder); | ||||
|         // 视图离开屏幕时:清空对应控件缓存+释放任务列表视图资源(移除未定义的onDestroy()) | ||||
|         // 核心修改:仅清理「无效/已回收」的控件缓存,不释放关键资源(支持复用后重新绑定) | ||||
|         PositionModel posModel = getPositionByIndex(holder.getAdapterPosition()); | ||||
|         if (posModel == null || TextUtils.isEmpty(posModel.getPositionId())) { | ||||
|             return; | ||||
|         } | ||||
|         String posId = posModel.getPositionId(); | ||||
|  | ||||
|         // 1. 移除距离控件缓存 | ||||
|         // 1. 清理「已脱离视图树/无效」的距离控件缓存(保留有效控件供局部更新) | ||||
|         if (mPosDistanceViewMap.containsKey(posId)) { | ||||
|             TextView distanceView = mPosDistanceViewMap.get(posId); | ||||
|             if (distanceView == null || !distanceView.isAttachedToWindow()) { | ||||
|                 mPosDistanceViewMap.remove(posId); | ||||
|             LogUtils.d(TAG, "视图脱离屏幕:移除位置ID=" + posId + "的距离控件缓存"); | ||||
|                 LogUtils.d(TAG, "视图脱离屏幕:移除无效距离控件缓存(位置ID=" + posId + ")"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 2. 释放简单模式任务视图资源(清空数据+解绑监听,替代onDestroy()) | ||||
|         // 2. 清理「已脱离视图树/无效」的简单模式任务视图缓存(不解绑监听/不清空数据,复用后重新同步) | ||||
|         if (holder instanceof SimpleViewHolder && mSimpleTaskViewMap.containsKey(posId)) { | ||||
|             PositionTaskListView taskView = mSimpleTaskViewMap.get(posId); | ||||
|             if (taskView != null) { | ||||
|                 taskView.clearData(); // 清空任务数据(假设视图已实现该方法,用于释放列表数据) | ||||
|                 taskView.setOnTaskUpdatedListener(null); // 解绑任务更新监听,避免内存泄漏 | ||||
|             } | ||||
|             if (taskView == null || !taskView.isAttachedToWindow()) { | ||||
|                 mSimpleTaskViewMap.remove(posId); | ||||
|             LogUtils.d(TAG, "简单模式视图脱离屏幕:释放任务列表视图资源(位置ID=" + posId + ")"); | ||||
|                 LogUtils.d(TAG, "简单模式视图脱离屏幕:移除无效任务视图缓存(位置ID=" + posId + ")"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 3. 释放编辑模式任务视图资源(清空数据+解绑监听,替代onDestroy()) | ||||
|         // 3. 清理「已脱离视图树/无效」的编辑模式任务视图缓存(同上,保留数据供复用) | ||||
|         if (holder instanceof EditViewHolder && mEditTaskViewMap.containsKey(posId)) { | ||||
|             PositionTaskListView taskView = mEditTaskViewMap.get(posId); | ||||
|             if (taskView != null) { | ||||
|                 taskView.clearData(); // 清空任务数据 | ||||
|                 taskView.setOnTaskUpdatedListener(null); // 解绑任务更新监听 | ||||
|             } | ||||
|             if (taskView == null || !taskView.isAttachedToWindow()) { | ||||
|                 mEditTaskViewMap.remove(posId); | ||||
|             LogUtils.d(TAG, "编辑模式视图脱离屏幕:释放任务列表视图资源(位置ID=" + posId + ")"); | ||||
|                 LogUtils.d(TAG, "编辑模式视图脱离屏幕:移除无效任务视图缓存(位置ID=" + posId + ")"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -199,10 +198,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     } | ||||
|  | ||||
|     // ========================================================================= | ||||
|     // 位置数据绑定(分简单/编辑模式,独立逻辑解耦) | ||||
|     // 位置数据绑定(保留原有逻辑,确保复用后数据最新) | ||||
|     // ========================================================================= | ||||
|     /** | ||||
|      * 绑定简单模式位置数据(仅显示,无编辑操作) | ||||
|      * 绑定简单模式位置数据(仅显示,无编辑操作)—— 复用后重新执行,显示最新数据 | ||||
|      */ | ||||
|     private void bindSimplePositionData(SimpleViewHolder holder, final PositionModel posModel) { | ||||
|         // 1. 经纬度显示(保留6位小数,格式统一) | ||||
| @@ -211,9 +210,9 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|  | ||||
|         // 2. 备注显示(无备注时显示默认文本) | ||||
|         String memo = posModel.getMemo(); | ||||
|         holder.tvSimpleMemo.setText("备注:" + (TextUtils.isEmpty(memo)? DEFAULT_MEMO : memo)); | ||||
|         holder.tvSimpleMemo.setText("备注:" + (TextUtils.isEmpty(memo) ? DEFAULT_MEMO : memo)); | ||||
|  | ||||
|         // 3. 实时距离显示(按状态区分文本+颜色) | ||||
|         // 3. 实时距离显示(按状态区分文本+颜色——复用后重新计算显示最新距离) | ||||
|         updateDistanceDisplay(holder.tvSimpleDistance, posModel); | ||||
|  | ||||
|         // 4. 点击切换到编辑模式 | ||||
| @@ -229,7 +228,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 绑定编辑模式位置数据(支持备注修改/距离开关/删除/保存) | ||||
|      * 绑定编辑模式位置数据(支持备注修改/距离开关/删除/保存)—— 复用后重新执行,恢复编辑状态 | ||||
|      */ | ||||
|     private void bindEditPositionData(final EditViewHolder holder, final PositionModel posModel, final int position) { | ||||
|         final String posId = posModel.getPositionId(); | ||||
| @@ -238,7 +237,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|         holder.tvEditLon.setText(String.format("经度:%.6f", posModel.getLongitude())); | ||||
|         holder.tvEditLat.setText(String.format("纬度:%.6f", posModel.getLatitude())); | ||||
|  | ||||
|         // 2. 备注编辑(填充现有备注,光标定位到末尾) | ||||
|         // 2. 备注编辑(填充现有备注,光标定位到末尾——复用后恢复输入状态) | ||||
|         String memo = posModel.getMemo(); | ||||
|         if (!TextUtils.isEmpty(memo)) { | ||||
|             holder.etEditMemo.setText(memo); | ||||
| @@ -247,10 +246,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|             holder.etEditMemo.setText(""); | ||||
|         } | ||||
|  | ||||
|         // 3. 实时距离显示(与简单模式逻辑一致) | ||||
|         // 3. 实时距离显示(与简单模式逻辑一致——复用后显示最新距离) | ||||
|         updateDistanceDisplay(holder.tvEditDistance, posModel); | ||||
|  | ||||
|         // 4. 距离开关状态(匹配位置模型中的启用状态) | ||||
|         // 4. 距离开关状态(匹配位置模型中的启用状态——复用后恢复开关状态) | ||||
|         holder.rgDistanceSwitch.check(posModel.isEnableRealPositionDistance() | ||||
| 									  ? R.id.rb_distance_enable | ||||
| 									  : R.id.rb_distance_disable); | ||||
| @@ -312,10 +311,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|     } | ||||
|  | ||||
|     // ========================================================================= | ||||
|     // PositionTaskListView 集成(分简单/编辑模式,差异化初始化+绑定) | ||||
|     // PositionTaskListView 集成(强化复用逻辑:复用后重新同步服务数据,确保数据不丢失) | ||||
|     // ========================================================================= | ||||
|     /** | ||||
|      * 初始化+绑定简单模式任务列表视图(仅显示已启用任务,无编辑操作) | ||||
|      * 初始化+绑定简单模式任务列表视图——复用后重新执行,从服务同步最新任务 | ||||
|      */ | ||||
|     private void initAndBindSimpleTaskView(PositionTaskListView taskView, final String posId, MainService mainService) { | ||||
|         if (taskView == null || TextUtils.isEmpty(posId) || mainService == null) { | ||||
| @@ -323,26 +322,26 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 1. 初始化任务视图(绑定MainService+当前位置ID,假设视图已实现init方法) | ||||
|         // 1. 初始化任务视图(绑定MainService+当前位置ID——复用后重新绑定,确保服务引用有效) | ||||
|         taskView.init(mainService, posId); | ||||
|         // 2. 设置为简单模式(仅展示,隐藏编辑按钮,需视图支持该状态设置) | ||||
|         // 2. 设置为简单模式(仅展示,隐藏编辑按钮——复用后恢复视图模式) | ||||
|         taskView.setViewStatus(PositionTaskListView.VIEW_MODE_SIMPLE); | ||||
|         // 3. 同步任务数据(从MainService拉取当前位置已启用任务) | ||||
| 		// 3. 关键:复用后强制从服务同步最新任务(避免显示旧数据,核心修复点) | ||||
| 		taskView.syncTasksFromMainService(); | ||||
|  | ||||
|         // 4. 任务更新回调(服务任务变化时重新同步) | ||||
| 		// 4. 任务更新回调(服务任务变化时重新同步——复用后重新绑定回调,避免监听失效) | ||||
| 		taskView.setOnTaskUpdatedListener(new PositionTaskListView.OnTaskUpdatedListener() { | ||||
| 				@Override | ||||
| 				public void onTaskUpdated(String positionId, ArrayList<PositionTaskModel> updatedTasks) { | ||||
| 				public void onTaskUpdated(String positionId, ArrayList updatedTasks) { | ||||
| 					LogUtils.d(TAG, "简单模式任务更新:位置ID=" + positionId + ",已启用任务数=" + updatedTasks.size()); | ||||
| 				} | ||||
| 			}); | ||||
|  | ||||
|         LogUtils.d(TAG, "初始化简单模式任务视图完成:位置ID=" + posId); | ||||
| 		LogUtils.d(TAG, "初始化/复用简单模式任务视图完成:位置ID=" + posId); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 初始化+绑定编辑模式任务列表视图(支持增删改查,关联新增任务按钮) | ||||
| 	 - 初始化+绑定编辑模式任务列表视图——复用后重新执行,从服务同步最新任务+恢复编辑功能 | ||||
| 	 */ | ||||
| 	private void initAndBindEditTaskView(final PositionTaskListView taskView, final String posId, | ||||
| 										 MainService mainService, Button btnAddTask) { | ||||
| @@ -350,15 +349,12 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 			LogUtils.w(TAG, "初始化编辑模式任务视图失败:参数无效(posId=" + posId + ",btnAddTask=" + btnAddTask + ")"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
|         // 1. 初始化任务视图(绑定MainService+当前位置ID) | ||||
| 		// 1. 初始化任务视图(绑定MainService+当前位置ID——复用后重新绑定,确保服务引用有效) | ||||
| 		taskView.init(mainService, posId); | ||||
|         // 2. 设置为编辑模式(显示编辑/删除按钮,支持修改) | ||||
| 		// 2. 设置为编辑模式(显示编辑/删除按钮——复用后恢复视图模式) | ||||
| 		taskView.setViewStatus(PositionTaskListView.VIEW_MODE_EDIT); | ||||
|         // 3. 同步任务数据(从MainService拉取当前位置所有任务) | ||||
|         taskView.syncTasksFromMainService(); | ||||
|  | ||||
|         // 4. 绑定“新增任务”按钮逻辑(点击创建默认任务,通过任务视图同步到服务) | ||||
| 		// 3. 关键:复用后强制从服务同步最新任务(避免显示旧数据,核心修复点) | ||||
| 		taskView.syncTasksFromMainService();// 4. 绑定“新增任务”按钮逻辑(复用后重新绑定点击事件,避免按钮点击失效) | ||||
| 		btnAddTask.setOnClickListener(new View.OnClickListener() { | ||||
| 				@Override | ||||
| 				public void onClick(View v) { | ||||
| @@ -369,54 +365,44 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 					newTask.setTaskDescription(DEFAULT_TASK_DESC);    // 默认描述 | ||||
| 					newTask.setDiscussDistance(DEFAULT_TASK_DISTANCE); // 默认触发距离(50米) | ||||
| 					newTask.setIsEnable(true);                        // 默认启用 | ||||
| 					newTask.setIsBingo(false);                        // 初始未触发 | ||||
|  | ||||
| 					// 调用任务视图的新增方法(假设视图已实现addNewTask,内部同步MainService) | ||||
| 					newTask.setIsBingo(false);                        // 初始未触发// 调用任务视图的新增方法(假设视图已实现addNewTask,内部同步MainService) | ||||
| 					taskView.addNewTask(newTask); | ||||
| 					hideSoftKeyboard(v); // 隐藏软键盘,提升体验 | ||||
| 					LogUtils.d(TAG, "编辑模式新增任务:位置ID=" + posId + ",任务ID=" + newTask.getTaskId()); | ||||
| 				} | ||||
| 			}); | ||||
|  | ||||
|         // 5. 任务更新回调(通知外部任务变化,如Activity需要联动) | ||||
| 			});// 5. 任务更新回调(通知外部任务变化——复用后重新绑定回调,确保交互正常) | ||||
| 		taskView.setOnTaskUpdatedListener(new PositionTaskListView.OnTaskUpdatedListener() { | ||||
| 				@Override | ||||
| 				public void onTaskUpdated(String positionId, ArrayList<PositionTaskModel> updatedTasks) { | ||||
| 				public void onTaskUpdated(String positionId, ArrayList updatedTasks) { | ||||
| 					LogUtils.d(TAG, "编辑模式任务更新:位置ID=" + positionId + ",当前任务数=" + updatedTasks.size()); | ||||
| 				} | ||||
| 			}); | ||||
|  | ||||
|         LogUtils.d(TAG, "初始化编辑模式任务视图完成:位置ID=" + posId); | ||||
| 			LogUtils.d(TAG, "初始化/复用编辑模式任务视图完成:位置ID=" + posId); | ||||
| 	} | ||||
|  | ||||
| 	// ========================================================================= | ||||
|     // 工具方法(距离显示/数据校验/控件管理,Java 7 语法适配) | ||||
| 	// 工具方法(保留原有逻辑,适配资源复用场景) | ||||
| 	// ========================================================================= | ||||
| 	/** | ||||
|      * 更新距离显示(按状态区分文本和颜色,提升视觉区分度) | ||||
|  | ||||
| 	 - 更新距离显示(复用后重新执行,确保显示最新距离+颜色——适配资源复用) | ||||
| 	 */ | ||||
| 	private void updateDistanceDisplay(TextView distanceView, PositionModel posModel) { | ||||
| 		if (distanceView == null || posModel == null) { | ||||
| 			LogUtils.w(TAG, "更新距离显示失败:参数为空(控件/位置模型)"); | ||||
| 			return; | ||||
|         } | ||||
|  | ||||
|         // 场景1:距离未启用(灰色文本) | ||||
| 		}// 场景1:距离未启用(灰色文本) | ||||
| 		if (!posModel.isEnableRealPositionDistance()) { | ||||
| 			distanceView.setText(DISTANCE_DISABLED); | ||||
| 			distanceView.setTextColor(mContext.getResources().getColor(R.color.gray)); | ||||
| 			return; | ||||
|         } | ||||
|  | ||||
|         // 场景2:距离计算失败(红色文本,用-1标记失败状态) | ||||
| 		}// 场景2:距离计算失败(红色文本,用-1标记失败状态) | ||||
| 		double distance = posModel.getRealPositionDistance(); | ||||
| 		if (distance < 0) { | ||||
| 			distanceView.setText(DISTANCE_ERROR); | ||||
| 			distanceView.setTextColor(mContext.getResources().getColor(R.color.red)); | ||||
| 			return; | ||||
|         } | ||||
|  | ||||
|         // 场景3:正常显示距离(按距离范围设置颜色) | ||||
| 		}// 场景3:正常显示距离(按距离范围设置颜色——复用后重新计算颜色) | ||||
| 		distanceView.setText(String.format(DISTANCE_FORMAT, distance)); | ||||
| 		if (distance <= 100) { | ||||
| 			distanceView.setTextColor(mContext.getResources().getColor(R.color.green)); // 近距离(≤100米) | ||||
| @@ -428,7 +414,8 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 根据索引获取位置模型(容错处理,避免越界/空指针) | ||||
|  | ||||
| 	 - 根据索引获取位置模型(容错处理,避免越界/空指针——适配复用后索引变化场景) | ||||
| 	 */ | ||||
| 	private PositionModel getPositionByIndex(int index) { | ||||
| 		if (mCachedPositionList == null || index < 0 || index >= mCachedPositionList.size()) { | ||||
| @@ -439,15 +426,14 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 根据位置ID获取列表索引(用于精准刷新视图) | ||||
|  | ||||
| 	 - 根据位置ID获取列表索引(用于精准刷新视图——适配复用后视图位置变化) | ||||
| 	 */ | ||||
| 	private int getPositionIndexById(String positionId) { | ||||
| 		if (TextUtils.isEmpty(positionId) || mCachedPositionList == null || mCachedPositionList.isEmpty()) { | ||||
| 			LogUtils.w(TAG, "获取位置索引失败:参数无效(ID/缓存为空)"); | ||||
| 			return -1; | ||||
|         } | ||||
|  | ||||
|         // Java 7 增强for循环遍历(替代Lambda,适配语法) | ||||
| 		}// Java 7 增强for循环遍历(替代Lambda,适配语法) | ||||
| 		for (int i = 0; i < mCachedPositionList.size(); i++) { | ||||
| 			PositionModel pos = mCachedPositionList.get(i); | ||||
| 			if (positionId.equals(pos.getPositionId())) { | ||||
| @@ -459,29 +445,28 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 局部更新距离UI(仅更新指定位置的距离,避免全量刷新卡顿) | ||||
|  | ||||
| 	 - 局部更新距离UI(仅更新指定位置的距离,避免全量刷新卡顿——适配复用后控件缓存有效场景) | ||||
| 	 */ | ||||
| 	public void updateSinglePositionDistance(String positionId) { | ||||
| 		if (TextUtils.isEmpty(positionId) || mPosDistanceViewMap.isEmpty()) { | ||||
| 			LogUtils.w(TAG, "局部更新距离失败:ID无效或无控件缓存(ID=" + positionId + ")"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		// 1. 获取服务端最新位置数据(带重试,避免服务临时回收) | ||||
| 		MainService mainService = getMainServiceWithRetry(2); | ||||
| 		if (mainService == null) { | ||||
| 			LogUtils.e(TAG, "局部更新距离失败:无法获取MainService"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		PositionModel latestPos = null; | ||||
| 		try { | ||||
|             ArrayList<PositionModel> servicePosList = mainService.getPositionList(); | ||||
| 			ArrayList servicePosList = mainService.getPositionList(); | ||||
| 			if (servicePosList != null && !servicePosList.isEmpty()) { | ||||
| 				// Java 7 迭代器遍历,避免ConcurrentModificationException | ||||
|                 Iterator<PositionModel> iter = servicePosList.iterator(); | ||||
| 				Iterator iter = servicePosList.iterator(); | ||||
| 				while (iter.hasNext()) { | ||||
|                     PositionModel pos = iter.next(); | ||||
| 					PositionModel pos = (PositionModel)iter.next(); | ||||
| 					if (positionId.equals(pos.getPositionId())) { | ||||
| 						latestPos = pos; | ||||
| 						break; | ||||
| @@ -491,14 +476,11 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 		} catch (Exception e) { | ||||
| 			LogUtils.d(TAG, "获取最新位置数据失败(ID=" + positionId + ")" + e); | ||||
| 			return; | ||||
|         } | ||||
|  | ||||
|         if (latestPos == null) { | ||||
| 		}if (latestPos == null) { | ||||
| 			LogUtils.w(TAG, "局部更新距离失败:未找到位置ID=" + positionId); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
|         // 2. 更新距离控件(确保主线程操作,避免跨线程异常) | ||||
| 		// 2. 更新距离控件(确保主线程操作,避免跨线程异常——适配复用后控件已重新绑定) | ||||
| 		final TextView distanceView = mPosDistanceViewMap.get(positionId); | ||||
| 		if (distanceView != null && distanceView.isAttachedToWindow()) { | ||||
| 			final PositionModel finalLatestPos = latestPos; | ||||
| @@ -510,20 +492,19 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 				}); | ||||
| 			LogUtils.d(TAG, "局部更新距离完成:位置ID=" + positionId + ",距离=" + latestPos.getRealPositionDistance() + "米"); | ||||
| 		} else { | ||||
|             mPosDistanceViewMap.remove(positionId); // 移除无效控件缓存 | ||||
| 			mPosDistanceViewMap.remove(positionId); // 移除无效控件缓存(如视图已被销毁) | ||||
| 			LogUtils.w(TAG, "局部更新距离失败:控件已回收/脱离视图树(ID=" + positionId + ")"); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 全量更新位置数据(从服务同步最新数据,过滤无效/重复项) | ||||
| 	 - 全量更新位置数据(从服务同步最新数据,过滤无效/重复项——适配复用后全量刷新场景) | ||||
| 	 */ | ||||
| 	public void updateAllPositionData(ArrayList<PositionModel> newPosList) { | ||||
| 		if (newPosList == null) { | ||||
| 			LogUtils.w(TAG, "全量更新位置数据失败:新列表为空"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		// 1. 过滤无效位置(校验核心字段:ID/经纬度合法) | ||||
| 		ArrayList<PositionModel> validPosList = new ArrayList<PositionModel>(); | ||||
| 		for (PositionModel pos : newPosList) { | ||||
| @@ -535,18 +516,15 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 			} | ||||
| 			validPosList.add(pos); | ||||
| 		} | ||||
|  | ||||
| 		// 2. 去重(按位置ID去重,保留服务端最新数据) | ||||
| 		ConcurrentHashMap<String, PositionModel> uniquePosMap = new ConcurrentHashMap<String, PositionModel>(); | ||||
| 		for (PositionModel pos : validPosList) { | ||||
| 			uniquePosMap.put(pos.getPositionId(), pos); // 相同ID覆盖,保留最新 | ||||
| 		} | ||||
|         ArrayList<PositionModel> uniquePosList = new ArrayList<PositionModel>(uniquePosMap.values()); | ||||
|  | ||||
|         // 3. 同步到本地缓存+刷新UI | ||||
| 		ArrayList uniquePosList = new ArrayList(uniquePosMap.values());// 3. 同步到本地缓存+刷新UI(刷新后触发onBind,自动重新绑定资源) | ||||
| 		this.mCachedPositionList.clear(); | ||||
| 		this.mCachedPositionList.addAll(uniquePosList); | ||||
|         // 清空旧控件缓存(避免引用失效数据) | ||||
| 		// 清空旧控件缓存(避免引用失效数据,刷新后重新缓存新控件) | ||||
| 		mPosDistanceViewMap.clear(); | ||||
| 		mSimpleTaskViewMap.clear(); | ||||
| 		mEditTaskViewMap.clear(); | ||||
| @@ -555,36 +533,33 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 隐藏软键盘(编辑完成后调用,提升用户体验) | ||||
| 	 - 隐藏软键盘(编辑完成后调用,提升用户体验——适配复用后软键盘残留问题) | ||||
| 	 */ | ||||
| 	private void hideSoftKeyboard(View view) { | ||||
| 		if (mContext == null || view == null) { | ||||
| 			LogUtils.w(TAG, "隐藏软键盘失败:参数为空(上下文/视图)"); | ||||
| 			return; | ||||
|         } | ||||
|  | ||||
|         InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); | ||||
| 		}InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); | ||||
| 		if (imm != null) { | ||||
| 			imm.hideSoftInputFromWindow(view.getWindowToken(), 0); // 强制隐藏 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 带重试的服务获取(解决弱引用临时回收问题,最多重试2次) | ||||
| 	 - 带重试的服务获取(解决弱引用临时回收问题,最多重试2次——适配复用后服务引用失效场景) | ||||
| 	 */ | ||||
| 	private MainService getMainServiceWithRetry(int retryCount) { | ||||
| 		MainService mainService = mMainServiceRef.get(); | ||||
| 		if (mainService != null) { | ||||
| 			return mainService; | ||||
| 		} | ||||
|  | ||||
| 		// 重试逻辑:每次间隔100ms,避免频繁重试 | ||||
| 		for (int i = 0; i < retryCount; i++) { | ||||
| 			try { | ||||
| 				Thread.sleep(100); | ||||
| 				mainService = mMainServiceRef.get(); | ||||
| 				if (mainService != null) { | ||||
|                     LogUtils.d(TAG, "重试获取MainService成功(第" + (i+1) + "次)"); | ||||
| 					LogUtils.d(TAG, "重试获取MainService成功(第" + (i + 1) + "次)"); | ||||
| 					return mainService; | ||||
| 				} | ||||
| 			} catch (InterruptedException e) { | ||||
| @@ -592,41 +567,39 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 				Thread.currentThread().interrupt(); // 恢复中断状态 | ||||
| 				break; | ||||
| 			} | ||||
|         } | ||||
|  | ||||
|         LogUtils.e(TAG, "重试" + retryCount + "次后仍未获取到MainService"); | ||||
| 		}LogUtils.e(TAG, "重试" + retryCount + "次后仍未获取到MainService"); | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	// ========================================================================= | ||||
|     // 实现 MainService.TaskUpdateListener 接口(服务任务变化时回调) | ||||
| 	// 实现 MainService.TaskUpdateListener 接口(服务任务变化时回调——适配复用后任务同步) | ||||
| 	// ========================================================================= | ||||
| 	@Override | ||||
| 	public void onTaskUpdated() { | ||||
|         LogUtils.d(TAG, "收到MainService任务更新通知,同步所有任务列表视图"); | ||||
| 		LogUtils.d(TAG, "收到MainService任务更新通知,同步所有任务列表视图(含复用视图)"); | ||||
|  | ||||
|         // 1. 同步简单模式任务视图(仅显示已启用任务) | ||||
| 		// 1. 同步简单模式任务视图(仅显示已启用任务——适配复用后视图已重新缓存) | ||||
| 		if (!mSimpleTaskViewMap.isEmpty()) { | ||||
| 			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mSimpleTaskViewMap.entrySet().iterator(); | ||||
| 			while (iter.hasNext()) { | ||||
| 				ConcurrentHashMap.Entry<String, PositionTaskListView> entry = iter.next(); | ||||
| 				PositionTaskListView taskView = entry.getValue(); | ||||
| 				if (taskView != null && taskView.isAttachedToWindow()) { | ||||
|                     taskView.syncTasksFromMainService(); // 从服务同步最新任务 | ||||
| 					taskView.syncTasksFromMainService(); // 从服务同步最新任务(复用后也能更新) | ||||
| 				} else { | ||||
|                     iter.remove(); // 移除无效视图缓存 | ||||
| 					iter.remove(); // 移除无效视图缓存(如视图已脱离屏幕且未复用) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|         // 2. 同步编辑模式任务视图(支持编辑的全量任务) | ||||
| 		// 2. 同步编辑模式任务视图(支持编辑的全量任务——适配复用后视图已重新缓存) | ||||
| 		if (!mEditTaskViewMap.isEmpty()) { | ||||
| 			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mEditTaskViewMap.entrySet().iterator(); | ||||
| 			while (iter.hasNext()) { | ||||
| 				ConcurrentHashMap.Entry<String, PositionTaskListView> entry = iter.next(); | ||||
| 				PositionTaskListView taskView = entry.getValue(); | ||||
| 				if (taskView != null && taskView.isAttachedToWindow()) { | ||||
|                     taskView.syncTasksFromMainService(); // 从服务同步最新任务 | ||||
| 					taskView.syncTasksFromMainService(); // 从服务同步最新任务(复用后也能更新) | ||||
| 				} else { | ||||
| 					iter.remove(); // 移除无效视图缓存 | ||||
| 				} | ||||
| @@ -635,7 +608,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	// ========================================================================= | ||||
|     // 回调设置方法(供Activity绑定交互逻辑) | ||||
| 	// 回调设置方法(供Activity绑定交互逻辑——适配复用后回调不失效) | ||||
| 	// ========================================================================= | ||||
| 	public void setOnDeleteClickListener(OnDeleteClickListener listener) { | ||||
| 		this.mOnDeleteListener = listener; | ||||
| @@ -646,7 +619,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	// ========================================================================= | ||||
|     // 资源释放(Activity销毁时调用,彻底释放引用,避免内存泄漏) | ||||
| 	// 资源释放(Activity销毁时调用,彻底释放引用,避免内存泄漏——保留原有安全逻辑) | ||||
| 	// ========================================================================= | ||||
| 	public void release() { | ||||
| 		// 1. 反注册MainService任务监听(解除服务绑定) | ||||
| @@ -656,7 +629,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 			LogUtils.d(TAG, "已反注册MainService任务监听"); | ||||
| 		} | ||||
|  | ||||
|         // 2. 释放简单模式任务视图资源(清空数据+解绑监听,替代onDestroy()) | ||||
| 		// 2. 释放简单模式任务视图资源(清空数据+解绑监听——仅在Activity销毁时执行,不复用场景) | ||||
| 		if (!mSimpleTaskViewMap.isEmpty()) { | ||||
| 			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mSimpleTaskViewMap.entrySet().iterator(); | ||||
| 			while (iter.hasNext()) { | ||||
| @@ -669,7 +642,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|         // 3. 释放编辑模式任务视图资源(清空数据+解绑监听,替代onDestroy()) | ||||
| 		// 3. 释放编辑模式任务视图资源(清空数据+解绑监听——仅在Activity销毁时执行) | ||||
| 		if (!mEditTaskViewMap.isEmpty()) { | ||||
| 			Iterator<ConcurrentHashMap.Entry<String, PositionTaskListView>> iter = mEditTaskViewMap.entrySet().iterator(); | ||||
| 			while (iter.hasNext()) { | ||||
| @@ -682,7 +655,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|         // 4. 清空其他缓存+置空引用 | ||||
| 		// 4. 清空其他缓存+置空引用(彻底释放,避免内存泄漏) | ||||
| 		mPosDistanceViewMap.clear(); | ||||
| 		if (mCachedPositionList != null) { | ||||
| 			mCachedPositionList.clear(); | ||||
| @@ -697,7 +670,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	// 静态内部类:ViewHolder(与布局严格对应,避免外部引用导致内存泄漏) | ||||
| 	// ========================================================================= | ||||
| 	/** | ||||
|      * 简单模式ViewHolder(对应 item_position_simple.xml,含简单模式任务列表视图) | ||||
| 	 - 简单模式ViewHolder(对应 item_position_simple.xml,含简单模式任务列表视图) | ||||
| 	 */ | ||||
| 	public static class SimpleViewHolder extends RecyclerView.ViewHolder { | ||||
| 		TextView tvSimpleLon;         // 经度显示 | ||||
| @@ -705,7 +678,6 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 		TextView tvSimpleMemo;        // 备注显示 | ||||
| 		TextView tvSimpleDistance;    // 距离显示 | ||||
| 		PositionTaskListView ptlvSimpleTasks; // 简单模式任务列表视图 | ||||
|  | ||||
| 		public SimpleViewHolder(View itemView) { | ||||
| 			super(itemView); | ||||
| 			// 绑定布局控件(与XML中ID严格一致,避免运行时空指针) | ||||
| @@ -718,7 +690,7 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * 编辑模式ViewHolder(对应 item_position_edit.xml,含编辑模式任务列表视图) | ||||
| 	 - 编辑模式ViewHolder(对应 item_position_edit.xml,含编辑模式任务列表视图) | ||||
| 	 */ | ||||
| 	public static class EditViewHolder extends RecyclerView.ViewHolder { | ||||
| 		TextView tvEditLon;           // 经度显示(不可编辑) | ||||
| @@ -732,7 +704,6 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
| 		Button btnAddTask;            // 新增任务按钮 | ||||
| 		TextView tvTaskCount;         // 任务数量显示(兼容旧布局,可隐藏) | ||||
| 		PositionTaskListView ptlvEditTasks; // 编辑模式任务列表视图 | ||||
|  | ||||
| 		public EditViewHolder(View itemView) { | ||||
| 			super(itemView); | ||||
| 			// 绑定布局控件(与XML中ID严格一致,避免运行时空指针) | ||||
| @@ -752,88 +723,87 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde | ||||
|  | ||||
| 	// ========================================================================= | ||||
| 	// 补充:PositionTaskListView 必要方法适配(确保视图类已实现以下基础方法) | ||||
|     // (若视图类未实现,需在 PositionTaskListView 中添加对应逻辑) | ||||
| 	// (若视图类未实现,需在 PositionTaskListView 中添加对应逻辑,否则复用后功能异常) | ||||
| 	// ========================================================================= | ||||
| 	public static class PositionTaskListViewRequiredMethods { | ||||
| 		/** | ||||
|          * 1. init 方法:初始化任务视图(绑定服务+位置ID) | ||||
|          * 需在 PositionTaskListView 中添加: | ||||
|          * public void init(MainService mainService, String positionId) { | ||||
|          *     this.mMainServiceRef = new WeakReference<MainService>(mainService); // 弱引用服务 | ||||
|          *     this.mPositionId = positionId; // 绑定当前位置ID | ||||
|          * } | ||||
| 		 1. - init 方法:初始化任务视图(绑定服务+位置ID——复用后重新绑定,确保服务引用有效) | ||||
| 		 - 需在 PositionTaskListView 中添加: | ||||
| 		 - public void init(MainService mainService, String positionId) { | ||||
| 		 - this.mMainServiceRef = new WeakReference(mainService); // 弱引用服务,防泄漏 | ||||
| 		 - this.mPositionId = positionId; // 绑定当前位置ID(复用后更新为当前位置ID) | ||||
| 		 - } | ||||
| 		 */ | ||||
|  | ||||
| 		/** | ||||
|          * 2. setViewStatus 方法:设置视图模式(简单/编辑) | ||||
|          * 需在 PositionTaskListView 中添加: | ||||
|          * public static final int VIEW_MODE_SIMPLE = 0; // 仅显示 | ||||
|          * public static final int VIEW_MODE_EDIT = 1;   // 可编辑 | ||||
|          * private int mViewMode; | ||||
|          * public void setViewStatus(int viewMode) { | ||||
|          *     this.mViewMode = viewMode; | ||||
|          *     // 根据模式控制编辑/删除按钮显示(如简单模式隐藏,编辑模式显示) | ||||
|          *     updateButtonVisibility(); | ||||
|          * } | ||||
| 		 2. - setViewStatus 方法:设置视图模式(简单/编辑——复用后恢复对应模式UI) | ||||
| 		 - 需在 PositionTaskListView 中添加: | ||||
| 		 - public static final int VIEW_MODE_SIMPLE = 0; // 仅显示(隐藏编辑/删除按钮) | ||||
| 		 - public static final int VIEW_MODE_EDIT = 1;   // 可编辑(显示编辑/删除按钮) | ||||
| 		 - private int mViewMode; | ||||
| 		 - public void setViewStatus(int viewMode) { | ||||
| 		 - this.mViewMode = viewMode; | ||||
| 		 - // 根据模式控制按钮显示:简单模式隐藏编辑按钮,编辑模式显示 | ||||
| 		 - if (mEditBtn != null) mEditBtn.setVisibility(viewMode == VIEW_MODE_EDIT ? View.VISIBLE : View.GONE); | ||||
| 		 - if (mDeleteBtn != null) mDeleteBtn.setVisibility(viewMode == VIEW_MODE_EDIT ? View.VISIBLE : View.GONE); | ||||
| 		 - } | ||||
| 		 */ | ||||
|  | ||||
| 		/** | ||||
|          * 3. syncTasksFromMainService 方法:从服务同步任务数据 | ||||
|          * 需在 PositionTaskListView 中添加: | ||||
|          * public void syncTasksFromMainService() { | ||||
|          *     MainService mainService = mMainServiceRef.get(); | ||||
|          *     if (mainService == null || TextUtils.isEmpty(mPositionId)) return; | ||||
|          *     // 根据视图模式拉取任务(简单模式:已启用;编辑模式:所有) | ||||
|          *     ArrayList<PositionTaskModel> tasks = (mViewMode == VIEW_MODE_SIMPLE) | ||||
|          *            ? mainService.getEnabledTasksByPositionId(mPositionId) | ||||
|          *             : mainService.getTasksByPositionId(mPositionId); | ||||
|          *     // 更新列表显示(如设置Adapter数据) | ||||
|          *     setTaskList(tasks); | ||||
|          * } | ||||
| 		 3. - syncTasksFromMainService 方法:从服务同步任务数据(复用后核心方法,避免旧数据) | ||||
| 		 - 需在 PositionTaskListView 中添加: | ||||
| 		 - public void syncTasksFromMainService() { | ||||
| 		 - MainService mainService = mMainServiceRef.get(); | ||||
| 		 - if (mainService == null || TextUtils.isEmpty(mPositionId)) return; | ||||
| 		 - // 根据视图模式拉取对应任务:简单模式仅拉已启用,编辑模式拉全部 | ||||
| 		 - ArrayList tasks = (mViewMode == VIEW_MODE_SIMPLE) | ||||
| 		 - ? mainService.getEnabledTasksByPositionId(mPositionId) | ||||
| 		 - : mainService.getTasksByPositionId(mPositionId); | ||||
| 		 - // 更新列表数据(刷新UI,确保复用后显示最新任务) | ||||
| 		 - if (mTaskAdapter != null) { | ||||
| 		 - mTaskAdapter.setTaskList(tasks); | ||||
| 		 - mTaskAdapter.notifyDataSetChanged(); | ||||
| 		 - } | ||||
| 		 - // 通知外部任务更新(如Adapter需要联动) | ||||
| 		 - if (mTaskUpdateListener != null) mTaskUpdateListener.onTaskUpdated(mPositionId, tasks); | ||||
| 		 - } | ||||
| 		 */ | ||||
|  | ||||
| 		/** | ||||
|          * 4. addNewTask 方法:新增任务(同步服务+刷新列表) | ||||
|          * 需在 PositionTaskListView 中添加: | ||||
|          * public void addNewTask(PositionTaskModel newTask) { | ||||
|          *     if (newTask == null || TextUtils.isEmpty(newTask.getPositionId())) return; | ||||
|          *     MainService mainService = mMainServiceRef.get(); | ||||
|          *     if (mainService != null) { | ||||
|          *         mainService.addTask(newTask); | ||||
|          *         syncTasksFromMainService(); // 新增后同步刷新 | ||||
|          *         Toast.makeText(getContext(), "任务创建成功", Toast.LENGTH_SHORT).show(); | ||||
|          *     } else { | ||||
|          *         Toast.makeText(getContext(), "新增失败,请重试", Toast.LENGTH_SHORT).show(); | ||||
|          *     } | ||||
|          * } | ||||
| 		 4. - addNewTask 方法:新增任务(同步服务+刷新列表——复用后功能正常) | ||||
| 		 - 需在 PositionTaskListView 中添加: | ||||
| 		 - public void addNewTask(PositionTaskModel newTask) { | ||||
| 		 - if (newTask == null || TextUtils.isEmpty(newTask.getPositionId())) return; | ||||
| 		 - MainService mainService = mMainServiceRef.get(); | ||||
| 		 - if (mainService != null) { | ||||
| 		 - mainService.addTask(newTask); // 同步到服务(确保数据持久化) | ||||
| 		 - syncTasksFromMainService();   // 新增后立即同步,刷新列表 | ||||
| 		 - Toast.makeText(getContext(), "任务新增成功", Toast.LENGTH_SHORT).show(); | ||||
| 		 - } else { | ||||
| 		 - Toast.makeText(getContext(), "服务未就绪,新增失败", Toast.LENGTH_SHORT).show(); | ||||
| 		 - } | ||||
| 		 - } | ||||
| 		 */ | ||||
|  | ||||
| 		/** | ||||
|          * 5. clearData 方法:清空任务数据(释放资源) | ||||
|          * 需在 PositionTaskListView 中添加: | ||||
|          * public void clearData() { | ||||
|          *     if (mTaskList != null) mTaskList.clear(); // 清空任务列表数据 | ||||
|          *     if (mTaskAdapter != null) mTaskAdapter.notifyDataSetChanged(); // 刷新列表 | ||||
|          * } | ||||
| 		 5. - clearData 方法:清空任务数据(仅在Activity销毁时调用,不复用场景) | ||||
| 		 - 需在 PositionTaskListView 中添加: | ||||
| 		 - public void clearData() { | ||||
| 		 - if (mTaskList != null) mTaskList.clear(); // 清空本地任务列表 | ||||
| 		 - if (mTaskAdapter != null) mTaskAdapter.notifyDataSetChanged(); // 刷新空UI | ||||
| 		 - } | ||||
| 		 */ | ||||
|  | ||||
| 		/** | ||||
|          * 6. setOnTaskUpdatedListener 方法:设置任务更新回调 | ||||
|          * 需在 PositionTaskListView 中添加: | ||||
|          * public interface OnTaskUpdatedListener { | ||||
|          *     void onTaskUpdated(String positionId, ArrayList<PositionTaskModel> updatedTasks); | ||||
|          * } | ||||
|          * private OnTaskUpdatedListener mTaskUpdateListener; | ||||
|          * public void setOnTaskUpdatedListener(OnTaskUpdatedListener listener) { | ||||
|          *     this.mTaskUpdateListener = listener; | ||||
|          * } | ||||
|          * // 任务变化时调用(如同步后/编辑后) | ||||
|          * private void notifyTaskUpdated(ArrayList<PositionTaskModel> updatedTasks) { | ||||
|          *     if (mTaskUpdateListener != null) { | ||||
|          *         mTaskUpdateListener.onTaskUpdated(mPositionId, updatedTasks); | ||||
|          *     } | ||||
|          * } | ||||
| 		 6. - setOnTaskUpdatedListener 方法:设置任务更新回调(复用后重新绑定,避免回调失效) | ||||
| 		 - 需在 PositionTaskListView 中添加: | ||||
| 		 - public interface OnTaskUpdatedListener { | ||||
| 		 - void onTaskUpdated(String positionId, ArrayList updatedTasks); | ||||
| 		 - } | ||||
| 		 - private OnTaskUpdatedListener mTaskUpdateListener; | ||||
| 		 - public void setOnTaskUpdatedListener(OnTaskUpdatedListener listener) { | ||||
| 		 - this.mTaskUpdateListener = listener; | ||||
| 		 - } | ||||
| 		 */ | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ZhanGSKen
					ZhanGSKen