Search code examples
javaandroidandroid-recyclerviewandroid-adapterandroid-cardview

Show customize pop up in recycler view adapter class - Android Java


I have a fragment class that contains edit text,button and the recycler view. my recycler view use an xml layout of card view. my card view contains text view and a button(?) to show a pop up after being clicked.
enter image description here
I tried to add the pop up code in my fragment class as I usually do, but it's pointing out that my fragment doesn't have access to recycler's view card view layout. So I tried to add it in my adapter class but I'm getting stuck with getActivty() not getting recognize.
this is what I added in my view holder method inside on click

                    btnHelp.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Popup_FreedomWall popup_freedomWall = new Popup_FreedomWall();
                            Bundle args = new Bundle();
                            System.out.println("=================TVFWID==========================");
                            System.out.println(tvFwId.getText().toString());
                            System.out.println("=====================TVFWID======================");
                            //data to get for report - uid(reported,get reported),freedom wall id
                            args.putString("user", mod_freedomWall.uid_report);
                            args.putString("reportedPost", tvFwId.getText().toString());
                            popup_freedomWall.setArguments(args);

                            popup_freedomWall.show();
                            popup_freedomWall.show(getActivity().getSupportFragmentManager(), "My Fragment");
                        }
                    });
    ```
<br/>


`Mod_FreedomWall.java` my Fragment
public class Mod_FreedomWall extends Fragment {
    RecyclerView recyclerView;
    Mod_FreedomWall_UserAdapter myAdapter;
    FragmentManager fragmentManager;
    ArrayList<Mod_FreedomWall_User> user;
  @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.mod_freedomwall, container, false);
        recyclerView = (RecyclerView) v.findViewById(R.id.freedomWallPost);

        return v;

    }

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        recyclerView = (RecyclerView) view.findViewById(R.id.freedomWallPost);
        recyclerView.setHasFixedSize(true);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, true);
        layoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(layoutManager);


        btnPost.setOnClickListener(new View.OnClickListener() {
            final Date c = Calendar.getInstance().getTime();
            final SimpleDateFormat df = new SimpleDateFormat("MM-dd-yy", Locale.getDefault());
            final String formattedDate = df.format(c);
            final Date currentTime = Calendar.getInstance().getTime();
            final DateFormat dateFormat = new SimpleDateFormat("hh.mm aa");
            final String dateString = dateFormat.format(new Date());

            @Override
            public void onClick(View v) {
                String message = etPost.getText().toString();
                createPost(message, user_name, dateString, formattedDate, level);
                myAdapter.notifyDataSetChanged();
                etPost.setText("");
            }
        });

        user = new ArrayList<Mod_FreedomWall_User>();
        retrievePost();

        myAdapter = new Mod_FreedomWall_UserAdapter(this, user);
        myAdapter.setListener(new Mod_FreedomWall_UserAdapter.MyListener() {
            @Override
            public void onItemClicked(String uid, String fwid) {
                Popup_FreedomWall popup_freedomWall = new Popup_FreedomWall();
                Bundle args = new Bundle();

  //just to see if I'm getting data              
System.out.println("=================TVFW==========================");
                System.out.println(fwid);
            System.out.println("=====================TVFW======================");

                args.putString("user",uid);
                args.putString("reportedPost", fwid);
                popup_freedomWall.setArguments(args);
                popup_freedomWall.show(getActivity().getSupportFragmentManager(), "pop_upFreedomWall");
            }
        });
        recyclerView.setAdapter(myAdapter);
    }


My Adapter

public class Mod_FreedomWall_UserAdapter extends RecyclerView.Adapter<Mod_FreedomWall_UserAdapter.ViewHolder> {
    Mod_FreedomWall mod_freedomWall = new Mod_FreedomWall();
    private ArrayList<Mod_FreedomWall_User> user;
    String freeId,reporterId;

    public  Mod_FreedomWall_UserAdapter(Mod_FreedomWall context, ArrayList<Mod_FreedomWall_User> list){
        user = list;
    }
    
public  class ViewHolder extends RecyclerView.ViewHolder{
        ImageView ivUserProfile;
        TextView tv_message,tv_username,tv_date,tvTime,tvFwId;
        Button btnHelp;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            btnHelp = (Button) itemView.findViewById(R.id.btnHelp);
            ivUserProfile = (ImageView) itemView.findViewById(R.id.ivUserProfile);
            tv_message = (TextView) itemView.findViewById(R.id.tv_message);
            tv_username = (TextView) itemView.findViewById(R.id.tv_username);
            tv_date = (TextView) itemView.findViewById(R.id.tv_date);
            tvTime = (TextView) itemView.findViewById(R.id.tvTime);
            tvFwId = (TextView) itemView.findViewById(R.id.tvFwId);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    btnHelp.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            System.out.println("=================TVFWID==========================");
                            System.out.println(tvFwId.getText().toString());
                            System.out.println("=====================TVFWID======================");
                            freeId = tvFwId.getText().toString();
                            reporterId = mod_freedomWall.uid_report;
                        }
                    });
                }
            });
        }
    }


    @NonNull
    @Override
    public Mod_FreedomWall_UserAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.mod_freedomwall_post,viewGroup,false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull Mod_FreedomWall_UserAdapter.ViewHolder viewHolder, int position) {
        viewHolder.itemView.setTag(user.get(position));

        viewHolder.tvFwId.setVisibility(View.INVISIBLE);
        viewHolder.tv_message.setText(user.get(position).getMessage());
        viewHolder.tv_username.setText(user.get(position).getUsername());
        viewHolder.tv_date.setText(user.get(position).getDate());
        viewHolder.tvTime.setText(user.get(position).getTime());
        viewHolder.tvFwId.setText(user.get(position).getFreedomWallId());
        viewHolder.ivUserProfile.setImageResource(R.drawable.ic_username_white);

    }
    @Override
    public int getItemCount() {
        return user.size();
    }
    public interface MyListener {
        void onItemClicked(String uid,String fwid); 
    }

    MyListener mListener;


    public void setListener(MyListener listener) {
        mListener = listener;
    }
}



Thank you in advance!

Solution

  • From what I understand you have two possible approaches to this problem.

    1. Send a Context with in your Adapter's constructor and replace the part where you need the "getActivity()" with that context you passed through (obv via a variable in your Adapter).
    2. Use an Interface approach. I never like the Context style, so I'll give you an example for an Interface approach.

    In your Adapter:

    public abstract class YourAdapter extends ...<> {
    
        public interface MyListener {
            void onItemClicked(String someData); //can change this variable to whatever is needed, if any.
        }
    
        MyListener mListener;
        ...
    

    Then let the onClickListener of the button call the Interface function you just created instead of trying to make a popup directly:

        btnHelp.setOnClickListener(v -> onItemClicked("this is my data i pass through");
    

    Then add a function to your Adapter to set the listener (or add it as argument in the constructor, whatever you want):

    public void setListener(MyListener listener) {
            mListener = listener;
        }
    

    And implement the listener in your Fragment:

    adapter.setListener(new YourAdapter.MyListener() {
            @Override
            public void onItemClicked(String myData) {
                //create your popup and simply call getActivity() since this is inside the Fragment
            }
        });
    

    --- Your Fragment ---

    public class Mod_FreedomWall extends Fragment {
    
        RecyclerView recyclerView;
        RecyclerView.Adapter myAdapter; //<-- 1 *remove*
        RecyclerView.LayoutManager layoutManager; // obsolete, can be deleted. You make a local variable later on.
        Mod_FreedomWall_UserAdapter adapter; // <-- 2 *rename to myAdapter*
      @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.mod_freedomwall, container, false);
            recyclerView = (RecyclerView) v.findViewById(R.id.freedomWallPost);
    
            return v;
    
        }
    
    @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
            recyclerView = (RecyclerView) view.findViewById(R.id.freedomWallPost);
            recyclerView.setHasFixedSize(true);
    
            LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, true);
            layoutManager.setStackFromEnd(true);
            recyclerView.setLayoutManager(layoutManager);
    
    // You call a function of `adapter` here, but adapter hasn't been 
    // properly initialised yet, it's null so far, so that won't go well. 
    // *rename adapter to myAdapter and move this part down*
    adapter.setListener(new Mod_FreedomWall_UserAdapter.MyListener() {
                @Override
                public void onItemClicked(String uid, String fwid) {
                    Popup_FreedomWall popup_freedomWall = new Popup_FreedomWall();
                    Bundle args = new Bundle();
                    //data to get for report - uid(reported,get reported),freedom wall id
                    args.putString("user",uid);
                    args.putString("reportedPost", fwid);
                    popup_freedomWall.setArguments(args);
                    popup_freedomWall.show(getActivity().getSupportFragmentManager(), "My Fragment");
                }
            });
    
            btnPost.setOnClickListener(new View.OnClickListener() {
                final Date c = Calendar.getInstance().getTime();
                final SimpleDateFormat df = new SimpleDateFormat("MM-dd-yy", Locale.getDefault());
                final String formattedDate = df.format(c);
                final Date currentTime = Calendar.getInstance().getTime();
                final DateFormat dateFormat = new SimpleDateFormat("hh.mm aa");
                final String dateString = dateFormat.format(new Date());
    
                @Override
                public void onClick(View v) {
                    String message = etPost.getText().toString();
                    createPost(message, user_name, dateString, formattedDate, level);
                    myAdapter.notifyDataSetChanged();
                    etPost.setText("");
                }
            });
    
            user = new ArrayList<Mod_FreedomWall_User>();
            retrievePost();
    
            //Here you initialise your adapter
            myAdapter = new Mod_FreedomWall_UserAdapter(this, user);
            //you can move your `myAdapter.setListener` to this spot.
            recyclerView.setAdapter(myAdapter);
        }
    

    Well, you declared two adapters but only really used one. Seems a bit mixed up.

    To-do; Scrap one of the adapters (number 1). Then the simplest way is to rename adapter at number 2 to myAdapter and also change the adapter at adapter.setListener to myAdapter.setListener(....

    Then move that myAdapater.setListener(... to a place below myAdapter = new Mod_FreedomWall_UserAdapter(this, user); since that is where you actually initialise your adapter. Before that point you can't safely call the your adapter's functions.