首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android Activity 與 Adapter 非啟動傳值:接口回調、ViewModel、EventBus 三大模式詳解

     編輯:程式設計疑難解答

場景

Activity 解析數據(如輪播圖 URL 列表),需傳遞給同一 Activity 內的 PagerAdapter 顯示,**不啟動新 Activity**,不使用 startActivity。

方案一:接口回調(最輕量、解耦)

1. 定義接口

public interface OnDataReadyListener {
    void onSliderDataReady(List<String> imageUrls, List<String> linkUrls);
}

2. Adapter 實現接口

public class AdvertisementAdapter extends PagerAdapter implements OnDataReadyListener {
    private List<String> mImageUrls = new ArrayList<>();
    private List<String> mLinkUrls = new ArrayList<>();

    @Override
    public void onSliderDataReady(List<String> imageUrls, List<String> linkUrls) {
        this.mImageUrls.clear();
        this.mImageUrls.addAll(imageUrls);
        this.mLinkUrls.clear();
        this.mLinkUrls.addAll(linkUrls);
        notifyDataSetChanged(); // 刷新 ViewPager
    }

    // getItem/instantiateItem 中使用 mImageUrls, mLinkUrls
    // 點擊事件中直接用 mLinkUrls.get(position) 跳轉
}

3. Activity 中調用

AdvertisementAdapter adapter = new AdvertisementAdapter();
// ... 解析 JSON 後
adapter.onSliderDataReady(imageUrls, linkUrls);

方案二:共享 ViewModel(架構組件,生命周期感知)

public class SliderViewModel extends ViewModel {
    private MutableLiveData<Pair<List<String>, List<String>>> sliderData = new MutableLiveData<>();

    public void setData(List<String> images, List<String> links) {
        sliderData.setValue(new Pair<>(images, links));
    }

    public LiveData<Pair<List<String>, List<String>>> getData() {
        return sliderData;
    }
}

// Activity 中
SliderViewModel vm = new ViewModelProvider(this).get(SliderViewModel.class);
vm.setData(imageUrls, linkUrls);

// Adapter 中(需持有 LifecycleOwner 或在 Activity 觀察後傳給 Adapter)
vm.getData().observe(this, pair -> adapter.updateData(pair.first, pair.second));

優勢:配置變更(旋轉屏幕)數據不丟,自動生命周期管理。

方案三:EventBus / RxBus(跨組件通用)

// 定義事件
public class SliderDataEvent {
    public final List<String> images;
    public final List<String> links;
    public SliderDataEvent(List<String> i, List<String> l) { images = i; links = l; }
}

// Activity 發送
EventBus.getDefault().post(new SliderDataEvent(imageUrls, linkUrls));

// Adapter 訂閱(需註冊/反註冊)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSliderData(SliderDataEvent event) {
    updateData(event.images, event.links);
}
@Override
public void onAttachedToWindow() { super.onAttachedToWindow(); EventBus.getDefault().register(this); }
@Override
public void onDetachedFromWindow() { super.onDetachedFromWindow(); EventBus.getDefault().unregister(this); }

方案對比與選型建議

維度接口回調ViewModelEventBus
耦合度低(面向接口)低(共享實例)極低(事件總線)
生命周期感知無有無
配置變更保活需手動處理自動需手動處理
適用場景同 Activity 內、簡單直接現代架構、需跨 Fragment/Activity跨模塊、多發多收、插件化
依賴庫無lifecycle-viewmodelgreenrobot/EventBus 或 RxJava

關鍵代碼修正點(針對原問題)

  1. 不要在 Handler 中直接 new Adapter,Adapter 應在 onCreate 建立並持有引用。
  2. JSON 解析完成後調用接口方法,而非在 Adapter 構造函數中解析。
  3. 點擊事件使用當前持有的列表:mLinkUrls.get(position),避免閉包捕獲舊變量。

總結

Activity 到 Adapter 傳值**無需 startActivity**。**接口回調**最簡直接,**ViewModel**最規範,**EventBus**最解耦。根據項目架構選型,核心原則:**Adapter 持有數據引用,數據源更新後 notifyDataSetChanged()**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved