6

I have a series of, what used to be called listViews, within my app that are now RecyclerViews. I am curious as to the most efficient way to raise the modularity and reduce repetition of this section of my app.

For example, I have the GroupMemberFragment and FriendFragment, that have near identical RecyclerView.ViewHolders and RecyclerView.Adapters

What is the best possible way to refactor so as to reduce code duplication yet still allow each respective item list to be unique to its data and flexible enough for adding more data in the future?

GroupMemberFragment:

public class GroupMemberFragment extends Fragment {

    RecyclerView mRecyclerView;
    ArrayList<Group> mGRoups;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.recycler_layout, container, false);

        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_layout);
        mRecyclerView.setHasFixedSize(true);

        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        // Only things that need to change across all the list classes....
        mGRoups = GroupListProvider.getInstance(getActivity()).getGroups();
        mRecyclerView.setAdapter(new GroupAdapter(mGRoups));

        return view;
    }


    // inner Class

    private class GroupViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private final TextView mName;
        private final TextView mChannel;

        public GroupViewHolder(View itemView) {
            super(itemView);

            mName = (TextView) itemView.findViewById(R.id.tv_name);
            mChannel = (TextView) itemView.findViewById(R.id.tv_number);

            mName.setOnClickListener(this);
        }

        public void bindGroup(Group group){
            mName.setText(group.getName().toString());
            mChannel.setText(group.getGroupChannelID().toString());
        }

        @Override
        public void onClick(View view) {
            int itemPosition = getAdapterPosition();
            Toast.makeText(getContext(), "Position is: " + String.valueOf(itemPosition), Toast.LENGTH_LONG).show();
        }
    }


    class GroupAdapter extends RecyclerView.Adapter<GroupViewHolder> {
        ArrayList<Group> groupList;

        GroupAdapter(ArrayList<Group> object){
            this.groupList = object;
        }

        @Override
        public GroupViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.rv_item, parent, false);

            return new GroupViewHolder(view);

        }

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

            Group group = groupList.get(position);
            holder.bindGroup(group);
        }

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

FriendFragment:

public class FriendFragment extends Fragment {

    RecyclerView mRecyclerView;
    ArrayList<Friend> mContacts;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.recycler_layout, container, false);

        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_layout);
        mRecyclerView.setHasFixedSize(true);

        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        mContacts = FriendProvider.getInstance(getActivity()).getFriends();
        mRecyclerView.setAdapter(new ContactAdapter(mContacts));

        return view;
    }

    // Inner Class

    private class ContactViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        private final TextView mName;
        private final TextView mNumber;
        private Friend mContact;

        public ContactViewHolder(View itemView) {
            super(itemView);

            mName = (TextView) itemView.findViewById(R.id.tv_name);
            mNumber = (TextView) itemView.findViewById(R.id.tv_number);

            mName.setOnClickListener(this);
        }

        public void bindContact(Friend contact){
            mContact = contact;
            mName.setText(contact.getFirstName().toString() + " " + contact.getLastName());
            mNumber.setText(contact.getFriendChannelID().toString());
        }

        @Override
        public void onClick(View view) {
            int itemPosition = getAdapterPosition();
            Toast.makeText(getContext(), "Position is: " + String.valueOf(itemPosition), Toast.LENGTH_LONG).show();
        }

    }

    class ContactAdapter extends RecyclerView.Adapter<ContactViewHolder> {
        ArrayList<Friend> contactList;

        ContactAdapter(ArrayList<Friend> object){
            this.contactList = object;
        }

        @Override
        public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.rv_item, parent, false);

            return new ContactViewHolder(view);

        }

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

            Friend contact = contactList.get(position);
            holder.bindContact(contact);
        }


        @Override
        public int getItemCount() {
            return contactList.size();
        }
    }
}
Sauron
  • 6,399
  • 14
  • 71
  • 136
  • Hi! What did you mean by telling "adding more data in future"? What changes you are going to make? Now it seems your adapters have very little in common (except of both have list data) – j2esu Jan 19 '16 at 05:16
  • What did you end up doing? – SMBiggs Sep 03 '16 at 18:35

2 Answers2

0

you can take out the adapter class from both classes and create a separate Java file for it and use the same adapter for both the classes you have. To do this you can create two different constructors for the adapter and achieve it.

Avinash Joshi
  • 1,307
  • 8
  • 25
-1

You could create factory methods for your object creation to make it a little neater but your code isnt tightly coupled it just looks sloppy becayse you are doing the same thing twice , however they are doing totally seperate things, so either leave it or , clean it up with some object factories or app class variables