You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:从Adapter获取Spinner数据传递至Activity提交Retrofit请求

嘿,我之前在做RecyclerView适配器和表单提交的时候也遇到过一模一样的问题。这里有几个靠谱的解决方案,能帮你把Spinner的选择数据从Adapter传到MainActivity里,你可以根据自己的项目情况选:

方案一:接口回调(最常用的传统实现方式)

这种方式通过定义回调接口,让Activity实现接口并传递给Adapter,当Spinner选中项变化时,Adapter主动通知Activity更新数据。

步骤1:在Adapter中定义回调接口并持有实例

public class RoutePlanVisitChangeAdapter extends RecyclerView.Adapter<RoutePlanVisitChangeAdapter.RoutePlanVisitChangeView> {
    private List<Retailers> mList;
    private Context context;
    private String[] daysList = {"MON", "TUE", "WED", "THU", "FRI", "SAT"};
    // 新增回调接口实例
    private OnDayChangedListener mDayChangedListener;

    // 定义回调接口
    public interface OnDayChangedListener {
        void onDayUpdated(int position, String newSelectedDay, Retailers originalRetailer);
    }

    // 修改构造方法,传入回调接口
    public RoutePlanVisitChangeAdapter(List<Retailers> mList, Context context, OnDayChangedListener listener) {
        this.mList = mList;
        this.context = context;
        this.mDayChangedListener = listener;
    }

    // 省略其他已有方法...
}

步骤2:给Spinner设置选中监听,触发回调

在onBindViewHolder里添加Spinner的选择监听,当用户选择新日期时,调用回调方法通知Activity:

@Override
public void onBindViewHolder(RoutePlanVisitChangeView holder, int position) {
    Retailers routePlanVisitChange = mList.get(position);
    // 省略原有绑定逻辑...

    // 设置Spinner选中监听
    holder.toDay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            String selectedNewDay = newDayList[pos];
            // 触发回调,把位置、新日期、原始数据传给Activity
            if (mDayChangedListener != null) {
                mDayChangedListener.onDayUpdated(position, selectedNewDay, routePlanVisitChange);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            // 可选:处理未选中的情况
        }
    });
}

步骤3:在MainActivity中实现回调接口,维护变更数据

让MainActivity实现刚才定义的接口,在回调方法里更新RoutePlanDayRequests列表:

public class MainActivity extends AppCompatActivity implements RoutePlanVisitChangeAdapter.OnDayChangedListener {
    private List<RoutePlanDayRequests> mChangedRequests = new ArrayList<>();
    private RoutePlanVisitChangeAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initialLoadingServiceList();
        submitChangeRequest.setOnClickListener(v -> updateServiceList());
    }

    private void initialLoadingServiceList(){
        // 省略加载初始数据逻辑...
        // 初始化Adapter时传入当前Activity(即回调实现类)
        mAdapter = new RoutePlanVisitChangeAdapter(retailers, this, this);
        mRecyclerView.setAdapter(mAdapter);
        // 初始化变更列表,默认填充原始数据
        for (Retailers retailer : retailers) {
            RoutePlanDayRequests req = new RoutePlanDayRequests();
            req.setOldDay(retailer.getRoutePlanDayOfWeek().toUpperCase());
            req.setNewDay(retailer.getRoutePlanDayOfWeek().toUpperCase());
            req.setStatus("unchanged");
            mChangedRequests.add(req);
        }
    }

    // 实现回调方法
    @Override
    public void onDayUpdated(int position, String newSelectedDay, Retailers originalRetailer) {
        // 更新对应位置的请求数据
        RoutePlanDayRequests req = mChangedRequests.get(position);
        req.setNewDay(newSelectedDay);
        req.setStatus("changed"); // 根据业务设置状态
    }

    private void updateServiceList() {
        // 过滤出真正有变更的项(可选,根据接口要求调整)
        List<RoutePlanDayRequests> filteredRequests = new ArrayList<>();
        for (RoutePlanDayRequests req : mChangedRequests) {
            if (!req.getOldDay().equals(req.getNewDay())) {
                filteredRequests.add(req);
            }
        }
        // 调用Retrofit接口
        RetrofitInstance.getInstance(this)
            .create(RoutePlanService.class)
            .getSaveRoutePlanDay(new SaveDayRequest(new RequestBody("", filteredRequests)));
    }
}
方案二:在Adapter内维护变更数据,提供获取方法

这种方式更简单,直接在Adapter里保存每个Item的变更状态,Activity需要数据时直接调用Adapter的方法获取。

步骤1:在Adapter中添加变更数据列表和获取方法

public class RoutePlanVisitChangeAdapter extends RecyclerView.Adapter<RoutePlanVisitChangeAdapter.RoutePlanVisitChangeView> {
    private List<Retailers> mList;
    private Context context;
    private String[] daysList = {"MON", "TUE", "WED", "THU", "FRI", "SAT"};
    // 新增:保存每个Item的变更数据
    private List<RoutePlanDayRequests> mChangedRequests = new ArrayList<>();

    public RoutePlanVisitChangeAdapter(List<Retailers> mList, Context context) {
        this.mList = mList;
        this.context = context;
        // 初始化变更列表
        for (Retailers retailer : mList) {
            RoutePlanDayRequests req = new RoutePlanDayRequests();
            req.setOldDay(retailer.getRoutePlanDayOfWeek().toUpperCase());
            req.setNewDay(retailer.getRoutePlanDayOfWeek().toUpperCase());
            req.setStatus("unchanged");
            mChangedRequests.add(req);
        }
    }

    // 新增:提供获取变更数据的方法
    public List<RoutePlanDayRequests> getChangedRequests() {
        // 可选:过滤未变更的项
        List<RoutePlanDayRequests> filtered = new ArrayList<>();
        for (RoutePlanDayRequests req : mChangedRequests) {
            if (!req.getOldDay().equals(req.getNewDay())) {
                req.setStatus("changed");
                filtered.add(req);
            }
        }
        return filtered;
    }

    // 省略其他已有方法...
}

步骤2:在Spinner选中时更新Adapter内的列表

@Override
public void onBindViewHolder(RoutePlanVisitChangeView holder, int position) {
    Retailers routePlanVisitChange = mList.get(position);
    // 省略原有绑定逻辑...

    holder.toDay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            String selectedNewDay = newDayList[pos];
            // 更新Adapter内对应位置的变更数据
            RoutePlanDayRequests req = mChangedRequests.get(position);
            req.setNewDay(selectedNewDay);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });
}

步骤3:在MainActivity中直接调用Adapter方法获取数据

public class MainActivity extends AppCompatActivity {
    private RoutePlanVisitChangeAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initialLoadingServiceList();
        submitChangeRequest.setOnClickListener(v -> updateServiceList());
    }

    private void initialLoadingServiceList(){
        // 省略加载初始数据逻辑...
        mAdapter = new RoutePlanVisitChangeAdapter(retailers, this);
        mRecyclerView.setAdapter(mAdapter);
    }

    private void updateServiceList() {
        // 直接从Adapter获取变更数据
        List<RoutePlanDayRequests> request = mAdapter.getChangedRequests();
        RetrofitInstance.getInstance(this)
            .create(RoutePlanService.class)
            .getSaveRoutePlanDay(new SaveDayRequest(new RequestBody("", request)));
    }
}
方案三:使用LiveData(适合Jetpack架构项目)

如果你的项目用了Jetpack组件,用LiveData可以更优雅地解耦Adapter和Activity,自动观察数据变化。

步骤1:创建ViewModel持有数据

public class RoutePlanViewModel extends ViewModel {
    private MutableLiveData<List<RoutePlanDayRequests>> mChangedRequestsLiveData = new MutableLiveData<>();
    private List<RoutePlanDayRequests> mRequestList = new ArrayList<>();

    // 初始化数据
    public void init(List<Retailers> retailers) {
        mRequestList.clear();
        for (Retailers retailer : retailers) {
            RoutePlanDayRequests req = new RoutePlanDayRequests();
            req.setOldDay(retailer.getRoutePlanDayOfWeek().toUpperCase());
            req.setNewDay(retailer.getRoutePlanDayOfWeek().toUpperCase());
            req.setStatus("unchanged");
            mRequestList.add(req);
        }
        mChangedRequestsLiveData.setValue(mRequestList);
    }

    // 更新指定位置的日期
    public void updateDay(int position, String newDay) {
        RoutePlanDayRequests req = mRequestList.get(position);
        req.setNewDay(newDay);
        mChangedRequestsLiveData.setValue(mRequestList);
    }

    // 对外提供LiveData观察
    public LiveData<List<RoutePlanDayRequests>> getChangedRequests() {
        return mChangedRequestsLiveData;
    }
}

步骤2:Adapter中持有ViewModel,更新数据

public class RoutePlanVisitChangeAdapter extends RecyclerView.Adapter<RoutePlanVisitChangeAdapter.RoutePlanVisitChangeView> {
    private List<Retailers> mList;
    private Context context;
    private String[] daysList = {"MON", "TUE", "WED", "THU", "FRI", "SAT"};
    private RoutePlanViewModel mViewModel;

    public RoutePlanVisitChangeAdapter(List<Retailers> mList, Context context, RoutePlanViewModel viewModel) {
        this.mList = mList;
        this.context = context;
        this.mViewModel = viewModel;
    }

    @Override
    public void onBindViewHolder(RoutePlanVisitChangeView holder, int position) {
        Retailers routePlanVisitChange = mList.get(position);
        // 省略原有绑定逻辑...

        holder.toDay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                String selectedNewDay = newDayList[pos];
                // 通知ViewModel更新数据
                mViewModel.updateDay(position, selectedNewDay);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
    }

    // 省略其他已有方法...
}

步骤3:MainActivity中观察LiveData

public class MainActivity extends AppCompatActivity {
    private RoutePlanViewModel mViewModel;
    private List<RoutePlanDayRequests> mChangedRequests;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 获取ViewModel实例
        mViewModel = new ViewModelProvider(this).get(RoutePlanViewModel.class);
        initialLoadingServiceList();

        // 观察数据变化
        mViewModel.getChangedRequests().observe(this, requests -> {
            mChangedRequests = requests;
        });

        submitChangeRequest.setOnClickListener(v -> updateServiceList());
    }

    private void initialLoadingServiceList(){
        // 省略加载初始数据逻辑...
        mViewModel.init(retailers);
        RoutePlanVisitChangeAdapter adapter = new RoutePlanVisitChangeAdapter(retailers, this, mViewModel);
        mRecyclerView.setAdapter(adapter);
    }

    private void updateServiceList() {
        // 过滤变更项
        List<RoutePlanDayRequests> filtered = new ArrayList<>();
        for (RoutePlanDayRequests req : mChangedRequests) {
            if (!req.getOldDay().equals(req.getNewDay())) {
                req.setStatus("changed");
                filtered.add(req);
            }
        }
        // 调用Retrofit接口
        RetrofitInstance.getInstance(this)
            .create(RoutePlanService.class)
            .getSaveRoutePlanDay(new SaveDayRequest(new RequestBody("", filtered)));
    }
}

内容的提问来源于stack exchange,提问作者Shiv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:02:29