How do I make an event to a specific View in a RecyclerView?

0

I have the following code in onCreate() of the activity that contains the RecyclerView :

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_courses);
        recyclerView = findViewById(R.id.recyclerViewCourses);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        ArrayList<Course> datos = new ArrayList<>();
        datos.add(new Course("Relational databases", 500,
                "A complete course about relational databases.", R.drawable.bbdd));
        datos.add(new Course("OOP", 500,
                "A complete course about objects oriented programming.", R.drawable.objetos));
        datos.add(new Course("Android", 0,
                "A complete course about Android.", R.drawable.android));

        adapter = new CoursesAdapter(datos);
        adapter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch(view.getId()){
                    case R.id.buttonBuy:{
                    Toast.makeText(getApplicationContext(),
                            "Seleccion: "+recyclerView.getChildAdapterPosition(view)
                            ,Toast.LENGTH_SHORT).show();
                        break;
                    }
                }
            }
        });

And the code of my adapter with the View.OnClickListener implemented is this:

    public class CoursesAdapter
            extends RecyclerView.Adapter<CoursesAdapter.ViewHolder>
                implements View.OnClickListener{
        ArrayList<Course> dataSet;
        private View.OnClickListener listener;
        public void setOnClickListener(View.OnClickListener l){
            this.listener = l;
        }

        @Override
        public void onClick(View view) {
            if(listener != null){
                listener.onClick(view);
            }
        }

        static class ViewHolder extends RecyclerView.ViewHolder{
            TextView title;
            TextView description;
            TextView cost;
            ImageView image;
            Button buttonBuy, buttonSeeMore;
            Context context;
            public ViewHolder(View itemView) {
                super(itemView);
                context = itemView.getContext();
                title = itemView.findViewById(R.id.textViewTitle);
                description = itemView.findViewById(R.id.textViewDescription);
                cost = itemView.findViewById(R.id.textViewCost);
                image = itemView.findViewById(R.id.imageViewCover);
            }

        }

    public CoursesAdapter(ArrayList<Course> dataSet){
        this.dataSet = dataSet;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.
                from(parent.getContext()).inflate(R.layout.card_course, parent, false);
        view.setOnClickListener(this);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.title.setText(dataSet.get(position).getName());
        if(dataSet.get(position).getCost() == 0){
            holder.cost.setText("FREE");
        }else{
            holder.cost.setText("$"+dataSet.get(position).getCost());
        }
        holder.description.setText(dataSet.get(position).getDescription());
        holder.image.setImageResource(dataSet.get(position).getCover());
        //events
    }

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

The adapter works fine, but I try to tell you a specific element ( R.id.buttonBuy ) in setOnClickListener but it does not work.

I just checked that the onClick serves, but I want to specify an element (such as TexView , etc) within the CardView that is the item.xml associated with the elements of the RecyclerView .

    
asked by Parzival 20.11.2017 в 16:48
source

3 answers

1

Modify the click listener so that it points to the UI you want:

 @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.title.setText(dataSet.get(position).getName());
        if(dataSet.get(position).getCost() == 0){
            holder.cost.setText("FREE");
        }else{
            holder.cost.setText("$"+dataSet.get(position).getCost());
        }
      holder.description.setText(dataSet.get(position).getDescription());
        holder.image.setImageResource(dataSet.get(position).getCover());
        //events
       holder.description.setOnClickListener(this);
    }
    
answered by 20.11.2017 в 17:09
0

I base myself on what David answered here in this question and thus the class that contains the RecyclerView remained

public class ViewCoursesActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    RecyclerView.LayoutManager layoutManager;
    private CourseAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_courses);
        recyclerView = findViewById(R.id.recyclerViewCourses);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        ArrayList<Course> datos = new ArrayList<>();
        datos.add(new Course("Relational databases", 500,
                "A complete course about relational databases.", R.drawable.bbdd));
        datos.add(new Course("OOP", 500,
                "A complete course about objects oriented programming.", R.drawable.objetos));
        datos.add(new Course("Android", 0,
                "A complete course about Android.", R.drawable.android));

        adapter = new CourseAdapter(datos, R.layout.card_course,
                this, new CourseAdapter.OnItemClickListener() {

            @Override
            public void onItemClickListener(View view) {
                    switch (view.getId()){
                        case R.id.buttonBuy:{
                            Toast.makeText(getApplicationContext(), "Funciona", Toast.LENGTH_SHORT).show();
                             break;
                        }
                    }
                }
            });
        recyclerView.setAdapter(adapter);
    }
}

And the adapter like that, where I implemented the OnItemClickListener in the ViewHolder, etc.

public class CourseAdapter extends RecyclerView.Adapter<CourseAdapter.ViewHolder>{

    ArrayList<Course> dataSet;
    private int layout;
    private Activity activity;
    private static OnItemClickListener listener;

    public CourseAdapter(ArrayList<Course> dataSet, int layout, Activity activity, OnItemClickListener listener) {
        this.dataSet = dataSet;
        this.layout = layout;
        this.activity = activity;
        this.listener = listener;
    }

    @Override
    public CourseAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(CourseAdapter.ViewHolder holder, int position) {
        holder.title.setText(dataSet.get(position).getName());
        if(dataSet.get(position).getCost() == 0){
            holder.cost.setText("FREE");
        }else{
            holder.cost.setText("$"+dataSet.get(position).getCost());
        }
        holder.description.setText(dataSet.get(position).getDescription());
        holder.image.setImageResource(dataSet.get(position).getCover());
        //events
    }

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


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

        TextView title;
        TextView description;
        TextView cost;
        ImageView image;
        Button buttonBuy, buttonSeeMore;
        Context context;
        public ViewHolder(View itemView) {
            super(itemView);
            context = itemView.getContext();
            title = itemView.findViewById(R.id.textViewTitle);
            description = itemView.findViewById(R.id.textViewDescription);
            cost = itemView.findViewById(R.id.textViewCost);
            image = itemView.findViewById(R.id.imageViewCover);
            buttonBuy = itemView.findViewById(R.id.buttonBuy);
            buttonSeeMore = itemView.findViewById(R.id.buttonSeeMore);
            buttonBuy.setOnClickListener(this);
            buttonSeeMore.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            // Llamas el método onItemClickListener() de la interfaz OnItemClickListener
            listener.onItemClickListener(view);
        }
    }
    public interface OnItemClickListener{
        // Este método recibe como parámetro la vista del elemento seleccionado
        void onItemClickListener(View view);
    }
}

It works as I wanted, however now I have the problem of identifying which CardView belongs to each view, which I will post in another question.

    
answered by 20.11.2017 в 17:58
0

You are missing several things so that it works as you need. Initially in class static class ViewHolder... the button buttonBuy is declared but you did not initialize it in the constructor.

In the method onCreateViewHolder delete the line view.setOnClickListener(this); you will no longer hear the clicks on the View.

If you want and I recommend that the adapter does not listen to events therefore quitalo of implements as well as the listener attribute of the adapter.

Finally in the onBindViewHolder method you have holder.buttonBuy.setOnClickListener ....


Then it is possible that in the onClick you need to open an activity or even interact with other elements of the activity that are outside the adapter. If that were your case, I recommend you use a callback (interface) in the adapter constructor, declare it and implement it in the activity and pass it to the adapter constructor. In the onClick of the adapter you execute it callback.miOnClick for example and that is executed in the activity.

    
answered by 20.11.2017 в 18:09