【问题标题】:How to pass Retrofit onResponse Data to an Activity?如何将 Retrofit onResponse 数据传递给活动?
【发布时间】:2017-12-25 15:15:06
【问题描述】:

我想将改造响应传递给 Activity,以便我可以在 recyclerview 适配器中设置数据。我不想使用 LiveData 或 RxJava。 这里的 imageDetails 是 Json 对象的列表,我想将它传递给 MainActivity。

TrendingViewModel.kt

class TrendingViewModel : ViewModel() {

fun fetchGifs() {
    val apiService = GiphyApi().getClient()?.create(ApiInterface::class.java)
    val call = apiService?.getTrendingResults(20, Constants.API_KEY)
    var imageDetails: List<ImageDetails>


    call?.enqueue(object : retrofit2.Callback<GiphyResponse> {

        override fun onResponse(call: Call<GiphyResponse>?, response: Response<GiphyResponse>?) {
            imageDetails = response?.body()?.data!!
        }

        override fun onFailure(call: Call<GiphyResponse>?, t: Throwable?) {
        }
    })
}}

MainActivity.kt

class MainActivity : AppCompatActivity() {

private lateinit var layoutManager: RecyclerView.LayoutManager
lateinit var adapter: RecyclerViewAdapter
lateinit var trendingViewModel: TrendingViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    val debugTree: Timber.DebugTree = Timber.DebugTree()
    TrendingViewModel().fetchGifs()
    Timber.plant(debugTree)

    trendingViewModel = ViewModelProviders.of(this).get(TrendingViewModel::class.java)
    trendingViewModel.fetchGifs()
    layoutManager = GridLayoutManager(this, 3) as RecyclerView.LayoutManager
    binding.recyclerview.layoutManager = layoutManager
    adapter = RecyclerViewAdapter(this)
    binding.recyclerview.adapter = adapter
    adapter.setListData(//TODO I need the response data here)

}}

RecyclerViewAdapter.kt

编辑:一切正常,但在调用所有默认函数后,我的列表正在更新。

class RecyclerViewAdapter(context: Context) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>(){


private var gifList: List<ImageDetails>? = Collections.emptyList()
private var mContext: Context? = null

init {
    this.mContext = context
}

fun setListData(list: List<ImageDetails>) {
    gifList=list
    Log.i("Size SetListData", gifList!!.size.toString())

    //Here it is showing List size 20
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? {
    val binding = DataBindingUtil.inflate<RecyclerviewListItemBinding>(LayoutInflater.from(parent.context), R.layout.recyclerview_list_item,
            parent, false)

    return ViewHolder(binding)

}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    //val binding = holder.binding;
    Log.i("Size SizeBindHolder",gifList?.size.toString())

    //Size = 0

    /*Glide.with(mContext)
            .load(gifList?.get(position)?.images?.dimen?.url)
            .into(holder.imageView)*/

}

override fun getItemCount(): Int {
    Log.i("Size ItemCount",gifList?.size.toString())
    // Size = 0 
    return gifList?.size!!
}




class ViewHolder(var binding: RecyclerviewListItemBinding) : RecyclerView.ViewHolder(binding.root) {
    var imageView: ImageView

    init {
        this.binding = binding
        imageView = binding.imageView
    }
}

【问题讨论】:

  • 创建一个函数来更新适配器中的数据。呼唤它作为回应。并调用 notifyDataSetChanged
  • 您能详细说明一下吗??

标签: android mvvm kotlin adapter retrofit2


【解决方案1】:

1- 在您的活动中添加:

    public class MainActivity extends AppCompatActivity implements Observer { 
        ....
    }

2- 在您的activity 中实现方法update()

    @Override
    public void update(Observable o, Object arg) {


    }

3- 创建一个 Observable 对象:

public class RetrofitObservable extends Observable {

    private static RetrofitObservable instance = null;

    public static RetrofitObservable getInstance() {

         if(instance == null) {

             instance = new RetrofitObservable();

         }

         return instance;
    }

    public void notifyObserverWithResponse(Object response) {

        setChanged();

        notifyObservers(response);

    }

}

4- 在您的活动onResume() 添加此行:

RetrofitObservable.getInstance().addObserver(this);

5- 在您的活动onPause() 添加此行:

RetrofitObservable.getInstance().deleteObserver(this);

6- 在您的改造响应中,调用此行:

RetrofitObservable.getInstance(). notifyObserverWithResponse(yourResponseHere);

7- 在您的活动update 方法中,处理您的响应:

@Override
public void update(Observable o, Object arg) {

    YourRetrofitResponse response = (YourRetrofitResponse) arg;

    // make your changes here

}

【讨论】:

  • 嘿男人谢谢你的回复,虽然我还没有尝试过,因为我发现@Akhil 的答案更容易。无论如何,谢谢。
【解决方案2】:

你可以使用传递你想要的方法作为函数参数,在下面试试 fetchGifs 接受一个方法作为参数 & 在 MainActivity 我们传递 adapter.setListData 以它为参数

class TrendingViewModel : ViewModel() {

fun fetchGifs(callback: (giphyResponse: GiphyResponse) -> Any) {
    val apiService = GiphyApi().getClient()?.create(ApiInterface::class.java)
    val call = apiService?.getTrendingResults(20, Constants.API_KEY)
    var imageDetails: List<ImageDetails>


    call?.enqueue(object : retrofit2.Callback<GiphyResponse> {

        override fun onResponse(call: Call<GiphyResponse>?, response: Response<GiphyResponse>?) {
            imageDetails = response?.body()?.data!!
            callback(imageDetails) 
        }

        override fun onFailure(call: Call<GiphyResponse>?, t: Throwable?) {
        }
    })
}}




class MainActivity : AppCompatActivity() {

private lateinit var layoutManager: RecyclerView.LayoutManager
lateinit var adapter: RecyclerViewAdapter
lateinit var trendingViewModel: TrendingViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    val debugTree: Timber.DebugTree = Timber.DebugTree()
    Timber.plant(debugTree)

    trendingViewModel = ViewModelProviders.of(this).get(TrendingViewModel::class.java)
    trendingViewModel.fetchGifs()
    layoutManager = GridLayoutManager(this, 3) as RecyclerView.LayoutManager
    binding.recyclerview.layoutManager = layoutManager
    adapter = RecyclerViewAdapter(this)
    binding.recyclerview.adapter = adapter
    TrendingViewModel().fetchGifs(result -> adapter.setListData(result))


}}

【讨论】:

  • 嘿@Akhil 它就像一个魅力,谢谢你。但是我有一个问题,我在适配器中获得了完整的列表,但无法在 getItemCount() 方法中获得大小。我该怎么做?
  • 在 setListData 你应该更新你的列表数据 & 在 getItemCount 应该返回更新列表的大小
  • 我已经从 setListData 更新了列表,但是这个方法是在所有被覆盖的方法之后调用的,所以列表在所有默认的 recyclerview 方法被调用之后都会更新。
  • 如果list中没有item返回0否则返回更新后list的大小,recycleView会多次调用该方法,都是异步的
  • 使用 notifyDataSetChanged() ...它现在可以工作了.. 谢谢。
猜你喜欢
  • 2014-10-30
  • 2010-11-07
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多