Search code examples
androidandroid-intentandroid-recyclerviewonclicklistenerandroid-contacts

Setting contact's name and number to title and subtitle into a toolbar


I built an application that read contacts from a phone (in this case my phone). For the activity where contacts has been displayed, I used TabLayout along with a ViewPager. For displaying the contacts I used RecyclerView. The point is that I handle it how to read contacts and my next movement after that was to open an external activity (MessageToContact_Activity) after clicking on a contact. In present in this activity (MessageToContact_Activity) I want to send a message to the contact that I have selected and for that firstly I am trying to set the contact's name and number to the toolbar's title and subtitle. Instead of default ActionBar I've decided to use a toolbar because is more flexible. The problem is that I don't know how to get the values of name and number and use them into MessageToContact_Activity.

Here is the implementation for Contacts_Fragment:

        public class Contacts_Fragment extends Fragment {
            View v;

            public Contacts_Fragment() {
            }

            @Nullable
            @Override
            public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                v = inflater.inflate(R.layout.contacts_fragment, container, false);

                RecyclerView recyclerView = v.findViewById(R.id.recycleView_search);
                LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
                RecyclerView.LayoutManager layoutManager = linearLayoutManager;
                recyclerView.setLayoutManager(layoutManager);
                ContactsAdapter adapter = new ContactsAdapter(getContext(), getContacts());
                recyclerView.setAdapter(adapter);

                return v;
            }

            private List<ContactModel> getContacts() {

                List<ContactModel> list = new ArrayList<>();

                if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_CONTACTS}, 1);
                }

                Cursor cursor = getContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                        null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");

                cursor.moveToFirst();

                while (cursor.moveToNext()) {
                    list.add(new ContactModel(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
                    )), cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))));
                }

                return list;
            }
        }

Here is the implementation for ContactsAdapter:

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

        private Context mContext;
        private LayoutInflater inflater;
        private List<ContactModel> mListContacts;

        public ContactsAdapter(Context context, List<ContactModel> listContacts){
            this.mContext = context;
            this.mListContacts = listContacts;
        }

        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            inflater = LayoutInflater.from(mContext);
            View view = inflater.inflate(R.layout.item_contact,parent, false);
            final ViewHolder viewHolder = new ViewHolder(view);

            viewHolder.item_contact.setOnClickListener(new View.OnClickListener(){

                @Override
                public void onClick(View view) {
                    Toast.makeText(mContext, "Test Click "+String.valueOf(viewHolder.getAdapterPosition()), Toast.LENGTH_SHORT).show();

                    /*This is where I've tried to get them with setters and use them
                            with getters in MessageToContact_Activity*/
                    String name = mListContacts.get(viewHolder.getAdapterPosition()).getName();
                    String number = mListContacts.get(viewHolder.getAdapterPosition()).getNumber();

                    MessageToContact_Activity mC = new MessageToContact_Activity();
                    mC.setName(name);
                    mC.setNumber(number);
                    /*----------------------------------------------------------------------------*/

                    onContactClick(view);
                }
            });
            return viewHolder;
        }

        public void onContactClick(View v){
            Intent myIntent = new Intent(v.getContext(), MessageToContact_Activity.class);
            mContext.startActivity(myIntent);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            TextView c_name, c_number;

            c_name = holder.cV_name;
            c_number = holder.cV_number;

            c_name.setText(mListContacts.get(position).getName());
            c_number.setText(mListContacts.get(position).getNumber());
        }

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

        public class ViewHolder extends RecyclerView.ViewHolder{
            TextView cV_name, cV_number;
            AppCompatImageButton messageButton;

            private LinearLayout item_contact;

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

                cV_name = itemView.findViewById(R.id.name_contact);
                cV_number = itemView.findViewById(R.id.phone_contact );
                messageButton = itemView.findViewById(R.id.message_button);

                item_contact = (LinearLayout) itemView.findViewById(R.id.contact_item_id);

            }
        }
    }

Where you see some code between /**..*/ and /**..*/, I just tried to isolate my methods of getting the values of name and number and to use them for setting the title and subtitle from MessageToContact_Activity. Here is the implementation for MessageToContact_Activity:


    public class MessageToContact_Activity extends AppCompatActivity{
        private String name, number;

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

            Toolbar toolbar = findViewById(R.id.messageToolbar);
            setSupportActionBar(toolbar);

            getSupportActionBar().setDisplayShowHomeEnabled(true);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);

            /*************************/
            getSupportActionBar().setTitle(getName());
            getSupportActionBar().setSubtitle(getNumber());
            /*************************/
        }
        /*************************/
        public MessageToContact_Activity(){}

        public String getName() {
            return name;
        }

        public String getNumber() {
            return number;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setNumber(String number) {
            this.number = number;
        }
        /*************************/
        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {

            if(item.getItemId() == android.R.id.home){
                finish();
            }
            return super.onOptionsItemSelected(item);
        }
    }

Here are the items of a contact :


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="16dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:text="Contact Name"
            android:id="@+id/name_contact" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Phone Number"
            android:id="@+id/phone_contact"/>
    </LinearLayout>

Here is the output when I use getSupportActionBar().setTitle(getName()); and getSupportActionBar().setSubtitle(getNumber());

Here is the output when I use getSupportActionBar().setTitle("Name"); and getSupportActionBar().setSubtitle("Number");

I will be so thankful to anyone who could help me. I have a hunch that the solution is not so hard but I still don't know it. And forgive me if there are some things wrong in my code but I'm still at the beginning with android application development.


Solution

  • Activities are not created using new MyActivity(), instead they need to be launched using an intent, as in:

    Intent i = new Intent(this, MyActivity.class);
    startActivity(i);
    

    If you need to pass to your new activity some parameters, you add them to your intent as extras, like so:

    Intent i = new Intent(this, MyActivity.class);
    i.putExtra("name", "Bob");
    i.putExtra("number", "12345");
    startActivity(i);
    

    So in your case, you need to replace your onClick method with something like this:

    @Override
    public void onClick(View view) {
        String name = mListContacts.get(viewHolder.getAdapterPosition()).getName();
        String number = mListContacts.get(viewHolder.getAdapterPosition()).getNumber();
    
        Intent myIntent = new Intent(v.getContext(), MessageToContact_Activity.class);
        myIntent.putExtra("name", name);
        myIntent.putExtra("number", number);
        mContext.startActivity(myIntent);
    }
    

    Then in your MessageToContact_Activity you can access those extras via:

    Bundle extras = getIntent().getExtras();
    String name = extras.getString("name");
    String number = extras.getString("number");