我有一个由2个主要项目组成的活动:RecyclerView和ListView。 RecyclerView充当过滤器,选择/取消选择项目将影响ListView的内容。一切顺利,直到我尝试在RecyclerView上实现onClickListener,并意识到这不是一个选项。
我尝试过在ViewHolder中设置OnClickListener的路线,但它需要调用main活动中的一个函数并刷新它的listView。任何此类交互都会触发以下错误:
java.lang.NullPointerException
at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:117)
at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149)
at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29)
at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:202)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183)
at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190)
at .newsScreen._$_findCachedViewById(newsScreen.kt)
at .newsScreen.filterNews(newsScreen.kt:71)
at Cells.NewsFeedList$NewsSource$1.onClick(News Lists.kt:84)
假设它有意义,因为我试图从它的外部访问UI,但我找不到它的替代品。
RecyclerView适配器:
class NewsFeedList() : RecyclerView.Adapter<NewsFeedList.NewsSource>() {
private var source: List<NewsFeed> = ArrayList()
constructor(s: ArrayList<NewsFeed>) : this() {
source = s
}
class NewsSource : RecyclerView.ViewHolder {
private var mTextView: TextView? = null
constructor(v: View): super(v) {
mTextView = v.title
}
fun bindInfo(news: NewsFeed, view: View, int: Int) {
mTextView!!.text = news.title
view.tag = int
view.setOnClickListener { newsScreen().filterNews(view.tag.toString().toInt()) }
if (news.selected) view.background = ColorDrawable(Color.parseColor(news.color))
else view.background = ColorDrawable(Color.parseColor(design.backgroundColor))
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): NewsFeedList.NewsSource {
val view = LayoutInflater.from(parent!!.context).inflate(R.layout.newsfeed_list, parent, false)
return NewsSource(view)
}
override fun onBindViewHolder(holder: NewsFeedList.NewsSource, position: Int) {
holder.bindInfo(source[position], holder.itemView, position)
}
override fun getItemCount(): Int {
return source.count()
}
}
然后,在我的newsScreen类中,我需要使用新数据访问RecyclerView适配器
fun filterNews(i: Int) {
newsFeed[i].selected = !newsFeed[i].selected
filter.adapter = NewsFeedList(newsFeed)
}
如果删除对filter(RecyclerView)的任何引用,一切都很好,但onClickListener的目的是刷新Activities内容。
有没有办法实现这一点,还是应该将RecyclerView更改为其他UI元素?
修改 我尝试将一个OnClickListener添加到RecyclerView但它似乎没有被触发。的代码:
filter.adapter = NewsFeedList(newsFeed)
filter.layoutManager = LinearLayoutManager(this@newsScreen, LinearLayoutManager.HORIZONTAL, false)
filter.setOnClickListener { v: View? ->
filterNews(v!!.tag.toString().toInt())
}
答案 0 :(得分:1)
对于您的Adapter类,您将拥有一个ViewHolder类(可能作为内部类),它在此代码中实现OnClickListener:
class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
TextView textView;
ImageView imageView;
ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text_view);
imageView = (ImageView) itemView.findViewById(R.id.image_view);
}
@Override
void onClick(View v) {
}
}
假设您的适配器不是您的Activity类的内部类,如果您愿意使用onClick()来访问您的Activity类&#39;方法/变量你必须有参考。
最好的方法是通过适配器的构造函数传递Context引用,因为ViewHolder是适配器的内部类:
class MyAdapter extends extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
MyAdapter(Context context) {
this.context = context;
}
class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
TextView textView;
ImageView imageView;
ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text_view);
imageView = (ImageView) itemView.findViewById(R.id.image_view);
}
@Override
void onClick(View v) {
// Here we gain access to non-private methods/variables
// of the Activity, which Context reference we are holding.
((MyActivity) context).someMethod();
}
}
}
希望,这有帮助。
答案 1 :(得分:1)
好的,这是您可以尝试的另一种解决方案:
将此界面添加到您的应用中:
interface ClickListener {
void onItemClicked(int position);
}
在MainActivity(或任何有按钮的活动)中实现它。
在Adapter构造函数中传递接口的引用: ArrayList mList; ClickListener监听器;
public MyAdapter(ArrayList<NewsFeed> mList, ClickListener listener) {
this.listener = listener;
}
@Override
public MyAdapter.NavViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.someL, parent, false);
return new ViewHolder(v, listener);
}
public void getItemClicked(int position){
mList.get(position);
}
最后,在你的ViewHolder类中:
class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
TextView textView;
ImageView imageView;
ClickListener listener;
ViewHolder(View itemView, ClickListener listener) {
super(itemView);
this.listener = listener;
textView = (TextView) itemView.findViewById(R.id.text_view);
imageView = (ImageView) itemView.findViewById(R.id.image_view);
textView.setOnClickListener(this)
}
@Override
void onClick(View v) {
listener.onItemClicked(getAdapterPosition());
}
最后在您的Activity(实现ClickListener接口)中,您必须覆盖void onItemClicked(int position);
,您将在其中执行操作。
P.S。:这个答案是在用户的主要帮助下编写的:https://stackoverflow.com/users/2667883/chaynik
答案 2 :(得分:0)
在适配器中,将上下文传递给类对象,如
MyActivity activity = (MyActivity)context
并调用以下方法:
activity.reload();