onClickItem不起作用,出现错误:未连接适配器,跳过布局

huangapple go评论65阅读模式
英文:

onClickItem not working with error No adapter attached, skipping layout

问题

I am using 2 activities (Main and VideoPlayActivity).it shows a recycler view and when clicked on any item the app stop working.

我使用了两个活动(主活动和VideoPlayActivity)。它显示一个可滚动视图,但当单击任何项时,应用程序停止工作。

I am trying to create an intent for onCLickItem to run a new activity I am getting this error

我正在尝试创建一个意图以在单击项目时运行一个新活动,但我遇到了这个错误

my adatper class is like this

我的适配器类如下所示

My MainActivity is as follows

我的MainActivity如下所示

英文:

I am using 2 activities (Main and VideoPlayActivity).it shows a recycler view and when clicked on any item the app stop working.

I am trying to create an intent for onCLickItem to run a new activity I am getting this error

2020-09-06 09:48:56.601 15956-15956/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2020-09-06 09:48:58.827 15956-15956/com.currentmedia.channel E/RecyclerView: No adapter attached; skipping layout
2020-09-06 09:49:10.757 15956-15956/com.currentmedia.channel E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.currentmedia.channel, PID: 15956
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.currentmedia.channel.VideoDetails.getVideoId()' on a null object reference
        at com.currentmedia.channel.adapter$1.onClick(adapter.java:54)
        at android.view.View.performClick(View.java:6935)
        at android.view.View$PerformClick.run(View.java:26214)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:7025)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

my adatper class is like this

public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
    LayoutInflater inflater;
    ArrayList<VideoDetails> videoDetailsArrayList;
    Context ctx;
    VideoDetails videoDetails;
    RecyclerView recyclerView;


//Constructor for adaptor
    public adapter(Context ctx, ArrayList<VideoDetails> videoDetailsArrayList)
    {
        this.videoDetailsArrayList=videoDetailsArrayList;
        //this.videoDetails=videoDetails;
        this.ctx=ctx;
        this.inflater=LayoutInflater.from(ctx);

    }


    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=inflater.inflate(R.layout.custom_layout,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(videoDetailsArrayList.get(position).getTitle());
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i=new Intent(ctx, VideoPlayActivity.class);
                i.putExtra("videoId", videoDetails.getVideoId());
                ctx.startActivity(i);
            }
        });
        final VideoDetails videoDetails=(VideoDetails)
                this.videoDetailsArrayList.get(position);

       // final VideoDetails videoDetails=(VideoDetails) this.videoDetailsArrayList.get(position);

        Picasso.get().load(videoDetails.getUrl()).into(holder.imageView);


    }

    @Override
    public int getItemCount()                                                                                                                           {
        return videoDetailsArrayList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        ImageView imageView;

        public ViewHolder(View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.mytitle);
            imageView=itemView.findViewById(R.id.imageView);
            

                }

        }
    }

My MAinActivity is as follows

public class MainActivity extends AppCompatActivity {
        RecyclerView recyclerView;
        ArrayList<VideoDetails> videoDetailsoArrayList;
    String API_Key = "";
    String url="https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCVMWWQ985A_-SESZUy_SsVQ&maxResults=50&key=";
    adapter adapter;
    Context ctx;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView=findViewById(R.id.listView);
        videoDetailsoArrayList= new ArrayList<>();
        adapter=new adapter(MainActivity.this,videoDetailsoArrayList);

        displayVideos();

    }


    private void displayVideos ()
    {
        RequestQueue requestQueue= Volley.newRequestQueue(this);
        StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {


            @Override
            public void onResponse(String response) {
                    try {
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray jsonArray = jsonObject.getJSONArray("items");
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                            if (jsonObject1.has("id")){
                                JSONObject jsonVideoId=jsonObject1.getJSONObject("id");
                                if (jsonVideoId.has("kind")){
                                    if(jsonVideoId.getString("kind").equals("youtube#video")){
                                        JSONObject jsonObjectSnippet = jsonObject1.getJSONObject("snippet");
                                        JSONObject jsonObjectDefault=jsonObjectSnippet.getJSONObject("thumbnails").getJSONObject("medium");

                                        String video_id=jsonVideoId.getString("videoId");

                                        VideoDetails vd=new VideoDetails();

                                        vd.setVideoId(video_id);
                                        vd.setTitle(jsonObjectSnippet.getString("title"));
                                        vd.setDescription(jsonObjectSnippet.getString("description"));
                                        vd.setUrl(jsonObjectDefault.getString("url"));

                                        videoDetailsoArrayList.add(vd);
                                    }
                                  //  recyclerView.setAdapter(adapter);
                                   // adapter.notifyDataSetChanged();
                                }
                            }
                        }
                    }catch (JSONException e) {
                        e.printStackTrace();
                    }

                recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                    adapter= new adapter(getApplicationContext(),videoDetailsoArrayList);
                recyclerView.setAdapter(adapter);
                           }

            }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),error.getMessage(), LENGTH_LONG).show();
            }
        });
        requestQueue.add(stringRequest);
         }
}

I have tried the stackover solutions <https://stackoverflow.com/questions/37202720/no-adapter-attached-skipping-layout-recyclerview> , https://stackoverflow.com/questions/48057595/no-adapter-attach-skipping-layout , https://stackoverflow.com/questions/47546917/attempt-to-invoke-virtual-method-java-lang-string-android-content-context-getpa ,
I have also applied the NPE declaration method in the adapter constructor ctx=ctx

答案1

得分: 1

Your Viewholder.ctx does not have context reference in that object hence the error, we don't set the onClickListener in ViewHolder class, look at the below.

public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
    LayoutInflater inflater;
    ArrayList<VideoDetails> videoDetailsArrayList;
    Context ctx;
    VideoDetails videoDetails;
    RecyclerView recyclerView;

    //Constructor for adaptor
    public adapter(Context ctx, ArrayList<VideoDetails> videoDetailsArrayList) {
        this.inflater = LayoutInflater.from(ctx);
        this.videoDetailsArrayList = videoDetailsArrayList;
        this.videoDetails = videoDetails;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.custom_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(videoDetailsArrayList.get(position).getTitle());
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(ctx, VideoPlayActivity.class);
                i.putExtra("videoId", videoDetails.getVideoId());
                ctx.startActivity(i);
            }
        });
        final VideoDetails videoDetails = (VideoDetails) 
        this.videoDetailsArrayList.get(position);

        Picasso.get().load(videoDetails.getUrl()).into(holder.imageView);
    }

    @Override
    public int getItemCount() {
        return videoDetailsArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        ImageView imageView;
        Context ctx;

        public ViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.mytitle);
            imageView = itemView.findViewById(R.id.imageView);
        }
    }
}

By this, you dont need to pass context to ViewHolder as Context ctx reference is already there in Adapter class.

英文:

Your Viewholder.ctx does not have context reference in that object hence the error, we don't set the onClickListener in ViewHolder class, look at the below.

public class adapter extends RecyclerView.Adapter&lt;adapter.ViewHolder&gt; {
LayoutInflater inflater;
ArrayList&lt;VideoDetails&gt; videoDetailsArrayList;
Context ctx;
VideoDetails videoDetails;
RecyclerView recyclerView;
//Constructor for adaptor
public adapter(Context ctx, ArrayList&lt;VideoDetails&gt; videoDetailsArrayList)
{
this.inflater=LayoutInflater.from(ctx);
this.videoDetailsArrayList=videoDetailsArrayList;
this.videoDetails=videoDetails;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.custom_layout,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(videoDetailsArrayList.get(position).getTitle());
holder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i=new Intent(ctx, VideoPlayActivity.class);
i.putExtra(&quot;videoId&quot;, videoDetails.getVideoId());
ctx.startActivity(i);
}
});
final VideoDetails videoDetails=(VideoDetails) 
this.videoDetailsArrayList.get(position);
Picasso.get().load(videoDetails.getUrl()).into(holder.imageView);
}
@Override
public int getItemCount() {
return videoDetailsArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView;
Context ctx;
public ViewHolder(View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.mytitle);
imageView=itemView.findViewById(R.id.imageView);
}
}
}

By this, you dont need to pass context to ViewHolder as Context ctx reference is already there in Adapter class.

huangapple
  • 本文由 发表于 2020年9月6日 04:13:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63758094.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定