【问题标题】:How to transform the context of fragment into a LifecycleOwner?如何将片段的上下文转换为 LifecycleOwner?
【发布时间】:2019-06-24 22:43:32
【问题描述】:

我有以下情况。我有一个包含片段的活动。在这个片段中,我显示了来自后端数据库的一些记录。我也在使用一个看起来像这样的适配器:

public class MovieAdapter extends PagedListAdapter<Movie, MovieAdapter.MovieViewHolder> {
    private Context context;

    public MovieAdapter(Context context) {this.context = context;}

    @NonNull
    @Override
    public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //Create the view
    }

    @Override
    public void onBindViewHolder(@NonNull final MovieViewHolder holder, int position) {
        Movie movie = getItem(position);
        String title = movie.title;
        holder.titleTextView.setText(title);

        MovieRepository movieRepository = new MovieRepository(context);
        LiveData<Movie> liveData = movieRepository.retrieveFavoriteMovie(movie.id);
        liveData.observe(context, m -> { //Error
            if(m != null) {
                boolean favorite = m.favorite;
                if(favorite) {
                    //Do something
                } else {
                    //Do something else
                }
            }
        });
    }

    class MovieViewHolder extends RecyclerView.ViewHolder {
        ImageView favoriteImageView;
        TextView titleTextView;

        MovieViewHolder(View itemView) {
            super(itemView);
            titleTextView = itemView.findViewById(R.id.title_text_view);                favoriteImageView = itemView.findViewById(R.id.favorite_image_view);
        }
    }
}

onBindViewHolder 中,我正在尝试检查 Romm 数据库中是否存在特定电影,但我收到此错误:

Wrong 1st argument type. Found: 'android.content.Context', required: 'android.arch.lifecycle.LifecycleOwner'

那么如何将片段的上下文转换为LifecycleOwner,以便我可以在我的方法中使用它作为参数?

【问题讨论】:

  • 你的 Activity 实现了 LifecycleOwner 吗?另外,您如何将Context 传递给适配器?
  • 如果 contextFragment 的实例,您可以将 context 用作 ((Fragment) context)
  • @ADM 不,它没有。我将上下文传递给构造函数public MovieAdapter(Context context) {this.context = context;}。你知道我该如何解决这个问题吗?还是谢谢!
  • @JeelVankhede 我得到Inconvertible types; cannot cast 'android.content.Context' to 'android.support.v4.app.Fragment'
  • @ADM 作为一个片段,我正在使用这个adapter = new MovieAdapter(getContext()); 这是正确的吗?

标签: java android android-room android-livedata


【解决方案1】:

android.content.Context 没有实现android.arch.lifecycle.LifecycleOwner

您必须传递一个 AppCompatActivity 的实例,它实现了 android.arch.lifecycle.LifecycleOwner(或任何其他实现该功能的类)。

或转换(AppCompatActivity) context,当contextinstanceof AppCompatActivity。要以可靠的方式从 Context 中获取 Activity,请检查 https://stackoverflow.com/a/46205896/2413303

【讨论】:

  • 谢谢马丁,我会试试的。
  • 我正在尝试将 Fragment 的新实例传递给构造函数,在该实例中我正在构建适配器,但没有任何反应。你有其他想法吗?谢谢!
  • AppCompatActivity 的简单转换终于成功了,但似乎在这种情况下观察者没有被删除:( 我会检查一下并提出另一个问题。
  • @IoanaP。还有.observeForever(Observer).removeObserver(Observer) 如果需要手动控制观察的删除。见developer.android.com/topic/libraries/architecture/livedata
【解决方案2】:

为那些想出上面建议的解决方案的人发布这个,下面我为 kotlin android 添加了 this 的简写扩展版本

private fun Context?.getLifeCycleOwner() : AppCompatActivity? = when {
    this is ContextWrapper -> if (this is AppCompatActivity) this else this.baseContext.getLifeCycleOwner()
    else -> null
}

在片段中使用上述扩展如下所示:

private var mainActivityContext: Context? = null //class level variable

//below statement called after context variable assigned / OnCreate
mainActivityContext?.getLifeCycleOwner()?.let { lifeCycleOwner ->
            YourViewModel.liveDataReturningMethod(text.toString())
                .observe(lifeCycleOwner , Observer { x ->
                    //your logic here...
                })
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 2018-12-01
    相关资源
    最近更新 更多