在RecyclerView.Adapter中,无法在onclick方法中引用非静态字段

时间:2016-10-15 15:28:47

标签: android android-fragments android-recyclerview recycler-adapter

在我的RecyclerView.Adapter中我有一个非静态字段,但我必须在我的ViewHolder中实现onClick,但是在onClick方法中出现错误non static field cannot be referenced from a static context但是我不能将我的字段声明为静态因为回收站视图在制表符片段中多次创建并且值被覆盖,所以请给我一个合适的解决方案。

修改

这是我的代码

public class RecyclerAdapter extends RecyclerView.Adapter{

public static final int VIEW_ITEM = 1;
public static final int VIEW_PROG = 0;

public ArrayList<BlogPosts> blogPostsArrayList;
public OnLoadMoreListener onLoadMoreListener;

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView title, category, time;
    public ImageView blogImage;
    public static Context context;

    public ViewHolder(View view) {
        super(view);
        context = view.getContext();
        title = (TextView) view.findViewById(R.id.textView);
        category = (TextView) view.findViewById(R.id.category);
        time = (TextView) view.findViewById(R.id.textTime);
        blogImage = (ImageView) view.findViewById(R.id.newsListImage);

        view.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        try {
            RecyclerAdapter blogsListRecyclerAdapter = new RecyclerAdapter();
            BlogPosts details;
            details = blogPostsArrayList.get(getPosition());// Problem is here
            Intent i = new Intent(context, ActivityNewsDetail.class);

            context.startActivity(i);
        } catch (Exception e) {

        }
    }


}

public static class ProgressViewHolder extends RecyclerView.ViewHolder {
    public ProgressBar progressBar;

    public ProgressViewHolder(View v) {
        super(v);
        progressBar = (ProgressBar) v.findViewById(R.id.progressBar1);
    }
}

public RecyclerAdapter(ArrayList<BlogPosts> blogPostsArrayList) {
    this.blogPostsArrayList = blogPostsArrayList;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // create a new view
    View v;
    if (viewType == VIEW_ITEM) {
        v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.news_row, parent, false);
        return new DonorListViewHolder(v);
    } else {
        v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.progressbar_item, parent, false);
        return new ProgressViewHolder(v);

    }

}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof DonorListViewHolder) {

        BlogPosts item = blogPostsArrayList.get(position);

        Constants.showLogTag("" + item.getPostId());

        ((DonorListViewHolder) holder).title.setText(item.getPostHeading());
        ((DonorListViewHolder) holder).category.setText(item.getCatagoryId()+"");
        ((DonorListViewHolder) holder).time.setText(getTime(item.getDateReported()));
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
        String baseUrl = settings.getString(Constants.BASE_URL, Constants.BASE_URL);
        Picasso.with(context).load(baseUrl + item.getPhoto350())
                .fit().centerCrop().into( ((DonorListViewHolder) holder).blogImage);

    } else {
        ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
    }
}



@Override
public int getItemCount() {
    return blogPostsArrayList != null ? blogPostsArrayList.size(): 0;
}

@Override
public int getItemViewType(int position) {
    return blogPostsArrayList.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}

public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
    this.onLoadMoreListener = onLoadMoreListener;
}

}

3 个答案:

答案 0 :(得分:2)

首先,我会从viewholder移出onClick监听器。将其设置在onCreateViewHolder的视图上。创建视图持有者的最终实例,在视图上设置单击侦听器,然后可以使用viewholder的getAdapterPosition方法。

但是我建议您尝试清理适配器,因为它编写得不好。根本不应该在适配器中有静态上下文。在最好的情况下甚至不是上下文。您可以使用view.getContext()来获取上下文。

根据您的代码,修复程序应与此类似:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // create a new view
    View v;
    if (viewType == VIEW_ITEM) {
        v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.news_row, parent, false);
     final DonorListViewHolder viewHolder = new DonoerListViewHolder(v);
     v.setOnclickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                  try {
            RecyclerAdapter blogsListRecyclerAdapter = new RecyclerAdapter();
            BlogPosts details;
            details = blogPostsArrayList.get(viewHolder.getAdapterPosition());
            Intent i = new Intent(context, ActivityNewsDetail.class);

            context.startActivity(i);
        } catch (Exception e) {

        }
       }});

        return viewHolder;
    } else {
        v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.progressbar_item, parent, false);
        return new ProgressViewHolder(v);

    }

}

答案 1 :(得分:1)

  • 将您的上下文放入构造函数
  • 创建接口类 处理点击次数
  • 在activity / fragment中实现您的界面 初始化适配器并处理单击操作

我会告诉你我在我的应用程序中做了什么(我在这里使用Butterknife和Lambdas):

public class PhotoFeedAdapter extends RecyclerView.Adapter<PhotoFeedAdapter.FeedViewHolder>  {

private List<GetPhotographsData> historyRides;
PhotoFeedAdapterListener photoFeedAdapterListener;

public PhotoFeedAdapter(PhotoFeedAdapterListener photoFeedAdapterListener, List<GetPhotographsData> historyRides) {
    this.photoFeedAdapterListener = photoFeedAdapterListener;
    this.historyRides=historyRides;

}

@Override
public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    return new FeedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.feedlist_item,parent,false));
}

@Override
public void onBindViewHolder(FeedViewHolder holder, int position) {

    GetPhotographsData tm = historyRides.get(position);

    Glide.with(AppSingl.getAppSingl())
            .load(tm.getPhotoUrl())
            .into(holder.feed_img);

    Glide.with(AppSingl.getAppSingl())
            .load(tm.getUser().getUserPhoto())
            .into(holder.img_avatar);

    holder.tv_username.setText(tm.getUser().getUserName());
    holder.tv_signername.setText(tm.getSigner().getSignerName());



    holder.feed_img.setOnClickListener(v -> {
        if (photoFeedAdapterListener!=null)
            photoFeedAdapterListener.onPhotoClicked(position);
    });

    holder.tv_username.setOnClickListener(v -> {
        if (photoFeedAdapterListener!=null)
        photoFeedAdapterListener.onOwnerClicked(position);
    });

    holder.img_avatar.setOnClickListener(v -> {
        if (photoFeedAdapterListener!=null)
            photoFeedAdapterListener.onOwnerClicked(position);
    });

    holder.tv_likes.setText("55 лайков");
    holder.tv_comments.setText("20 комментариев");

}

public GetPhotographsData getItemAtPosition(int position){
    return historyRides.get(position);
}


@Override
public int getItemCount() {

    return historyRides.size();
}



public class FeedViewHolder extends RecyclerView.ViewHolder {

    @BindView(R.id.feed_img)
    SquareImageView feed_img;

    @BindView(R.id.img_useravatar)
    CircleImageView img_avatar;

    @BindView(R.id.tv_username)
    TextView tv_username;

    @BindView(R.id.tv_signername)
    TextView tv_signername;

    @BindView(R.id.tv_likes)
    TextView tv_likes;

    @BindView(R.id.tv_comments)
    TextView tv_comments;

    public FeedViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}}

}

public interface PhotoFeedAdapterListener {

void onOwnerClicked(int position);

void onSignerClicked(int position);

void onOptionsClicked(int position);

void onPhotoClicked(int position);}

答案 2 :(得分:1)

Adapter类中的ViewHolder类不一定需要static。此外,不需要为不同的视图创建不同的ViewHolder类。

以下代码可能有所帮助。

public class NewsFeedAdapter extends RecyclerView.Adapter<NewsFeedAdapter.ViewHolder> {
JSONArray posts;
Context mContext;


public NewsFeedAdapter(Context context, JSONArray posts) {
    mContext = context;
    this.posts = posts;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    switch (viewType) {
        case 1:
            return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.row_question, parent, false), viewType);
        case 2:
            return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.row_poll, parent, false), viewType);
    }
    return null;
}

@Override
public int getItemViewType(int position) {
    try {
        JSONObject post = posts.getJSONObject(position);
        return Integer.parseInt(post.getString("p_type"));
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return super.getItemViewType(position);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    try {
        switch (holder.viewType) {
            case 1:
                //Question
                JSONObject post = posts.getJSONObject(position);
                holder.content.setText(post.getString("content"));
                holder.upvote.setText("UPVOTE(" + post.getString("upvote") + ")");
                holder.downvote.setText("DOWNVOTE(" + post.getString("downvote") + ")");
                break;
            case 2:
                JSONObject poll = posts.getJSONObject(position);
                holder.poll_content.setText(poll.getString("content"));
                break;
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

}

@Override
public int getItemCount() {
    return posts.length();
}

public String getUserType() {
    return mContext.getSharedPreferences("user_details", Context.MODE_PRIVATE).getString("type", "");
}

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView comment, upvote, downvote, content;
    LinearLayout ll_content, ll_upvote, ll_dvote, ll_comment;
    int viewType;
    TextView poll_content, tv_respond;

    public ViewHolder(View itemView, int viewType) {
        super(itemView);
        this.viewType = viewType;
        switch (viewType) {
            case 1:
                comment = (TextView) itemView.findViewById(R.id.tv_comment);
                upvote = (TextView) itemView.findViewById(R.id.tv_upvote);
                downvote = (TextView) itemView.findViewById(R.id.tv_dvote);
                content = (TextView) itemView.findViewById(R.id.tv_content);
                ll_content = (LinearLayout) itemView.findViewById(R.id.ll_content);
                ll_content.setOnClickListener(this);
                ll_upvote = (LinearLayout) itemView.findViewById(R.id.ll_upvote);
                ll_upvote.setOnClickListener(this);
                ll_dvote = (LinearLayout) itemView.findViewById(R.id.ll_dvote);
                ll_dvote.setOnClickListener(this);
                ll_comment = (LinearLayout) itemView.findViewById(R.id.ll_comment);
                ll_comment.setOnClickListener(this);
                break;
            case 2:
                poll_content = (TextView) itemView.findViewById(R.id.tv_poll_content);
                tv_respond = (TextView) itemView.findViewById(R.id.tv_respond);
                poll_content.setOnClickListener(this);
                tv_respond.setOnClickListener(this);

        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ll_content:
                Bundle bundle = new Bundle();
                Intent intent = new Intent(mContext, PostDetailsActivity.class);
                try {
                    intent.putExtra("postdetails", posts.getJSONObject(getLayoutPosition()).toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                mContext.startActivity(intent);
                break;
            case R.id.ll_upvote:
                try {
                    upvoteThePost(getLayoutPosition());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                break;
        }
    }
}