Easy Way To Reuse A Bottom Sheet

Easy Way To Reuse A Bottom Sheet

Introduction

We find a single activity in an Android app that has a number of bottom sheets and is attempting to handle them all at once, which might be highly worrying and result in a large amount of code being accumulated. I'll show you exactly how to accomplish it right here.

A "bottom sheet" is a component that is used to display information by sliding the view up from the bottom of the screen; you can also dismiss this bottom sheet when the message is sent to the users. This is a good way to communicate a message or complete a task on Android. In this section, I will create a custom modal bottom sheet that can be used in a single activity to do the same function with a single call using viewType.

You may be wondering what a view type is.🤔

A view type is similar to a holder in this regard, as it is only called when a new view layout is necessary. Rather than building many bottom sheets for each item in an activity, when the bottom sheet is required, the view type will request that item and present the bottom sheet with the correct information for that item.

Step 1

Create a custom bottom layout.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#ffffff" >
   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="@drawable/bg_white1"
       android:backgroundTint="@color/semi_gray"
       android:orientation="vertical">
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_marginLeft="20dp"
           android:layout_marginRight="20dp"
           android:layout_marginTop="10dp"
           android:orientation="vertical"
           android:paddingBottom="20dp">
           <TextView
               android:id="@+id/fullName"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="Full name"
               android:textColor="@color/dark_gray"
               android:textStyle="bold"
               android:textSize="16sp"/>
           <EditText
               android:id="@+id/editName"
               android:layout_width="match_parent"
               android:layout_height="50dp"
               android:layout_marginTop="30dp"
               android:background="@drawable/white_bg"
               android:hint="Ola dimeji"
               android:textColorHint="#78849E"
               android:padding="15dp"/>
           <RelativeLayout
               android:id="@+id/spinLayout"
               android:visibility="gone"
               android:layout_width="match_parent"
               android:layout_height="50dp"
               android:layout_marginTop="20dp"
               android:background="@drawable/white_bg">
               <Spinner
                   android:id="@+id/spinner"
                   android:layout_width="match_parent"
                   android:layout_height="70dp"
                   android:entries="@array/array_name"
                   style="@style/Spinner"
                   android:layout_alignParentRight="true"
                   android:spinnerMode="dropdown" />
               <ImageView
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:layout_alignParentRight="true"
                   android:layout_marginRight="18dp"
                   android:layout_marginTop="10dp"
                   android:tint="@color/gray"
                   app:srcCompat="@drawable/ic_spinner"/>
           </RelativeLayout>
        <Button
               android:id="@+id/btnUpdate"
               android:layout_width="match_parent"
               android:layout_height="40dp"
               android:layout_marginTop="70dp"
               android:background="@drawable/active"
               android:text="Update name"
               android:textAllCaps="false"
               android:textColor="#ffffff"
               android:textSize="16dp" />
       </LinearLayout>
   </LinearLayout>
</LinearLayout>

Step 2

Make a fragment and extend it all the way to the bottomSheetFragment, where all of the properties in the bottom sheet are stored. The XML protocol will be used.

public class ProfileFragment extends BottomSheetDialogFragment {
}

Make a new instance of the fragment to be used in the activity.

 public static ProfileFragment newInstance(int viewType) {
       Bundle args = new Bundle(1);
       args.putInt("viewType", viewType);

       ProfileFragment fragment = new ProfileFragment();
       fragment.setArguments(args);

       return fragment;
 }

In the onCreateView function, inflate the bottom sheet layout and call each element in the fragment, assigning them to their respective ids. View types are connected to elements to make it easier to identify them when they are called. When these view types are called or clicked, the bottom sheet property containing the appropriate information is assigned to the view type. The hint, text name, and button name will be set to Name View.

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

        imageView = getActivity().findViewById(R.id.fullIcon);
        emailView = getActivity().findViewById(R.id.emailIcon);
        phoneView = getActivity().findViewById(R.id.phoneIcon);

       TextView textName = view.findViewById(R.id.fullName);
       EditText hint = view.findViewById(R.id.editName);
       Button updateButton = view.findViewById(R.id.btnUpdate);

       if (currentViewType == NAME_VIEW) {
           textName.setText("Full name");
           hint.setHint("Andrea yung");
           updateButton.setText("Update name");
           updateButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view1) {
                   ProfileFragment.this.updateNameImpl();
               }
           });
       } else if (currentViewType == PHONE_VIEW) {
           textName.setText("Phone number");
           hint.setHint("09023456789");
           hint.setInputType(InputType.TYPE_CLASS_PHONE);
           updateButton.setText("update  phone number");
           updateButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view1) {
                   ProfileFragment.this.updatePhoneNumberImpl();
               }
           });
       } else if (currentViewType == EMAIL_VIEW) {

      textName.setText("Email address");
           hint.setHint("Doe@gmail.com");
           hint.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
           updateButton.setText("Update Email");
           updateButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view1) {
                   ProfileFragment.this.updateEmailImpl();
               }
           });
       }

       return view;
   }

Full code for the fragment class.

public class ProfileFragment extends BottomSheetDialogFragment {

   public static final int NAME_VIEW = 1;
   public static final int PHONE_VIEW = 2;
    private int currentViewType;
   ImageView imageView,emailView,phoneView;

   public static ProfileFragment newInstance(int viewType) {
       Bundle args = new Bundle(1);
       args.putInt("viewType", viewType);

       ProfileFragment fragment = new ProfileFragment();
       fragment.setArguments(args);

       return fragment;
   }

   @Override
   public void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       currentViewType = getArguments().getInt("viewType", 0);
       if (currentViewType == 0) {
           dismiss();
       }
   }


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

        imageView = getActivity().findViewById(R.id.fullIcon);
        phoneView = getActivity().findViewById(R.id.phoneIcon);

       TextView textName = view.findViewById(R.id.fullName);
       EditText hint = view.findViewById(R.id.editName);
       Button updateButton = view.findViewById(R.id.btnUpdate);

       if (currentViewType == NAME_VIEW) {
           textName.setText("Full name");
           hint.setHint("Andrea yung");
           updateButton.setText("Update name");
           updateButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view1) {
                   ProfileFragment.this.updateNameImpl();
               }
           });
       } else if (currentViewType == PHONE_VIEW) {
           textName.setText("Phone number");
           hint.setHint("09023456789");
           hint.setInputType(InputType.TYPE_CLASS_PHONE);
           updateButton.setText("update  phone number");
           updateButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view1) {
                   ProfileFragment.this.updatePhoneNumberImpl();
               }
           });
       } 
       return view;
   }

   private void updateNameImpl() {
       imageView.animate().rotation(0).start();
       dismiss();

   }

   private void updatePhoneNumberImpl() {
       phoneView.animate().rotation(0).start();
       dismiss();
   }

}

Step 3

In the activity, the fragment instance will be called and assigned to each element according to their view type.

public class Profile extends AppCompatActivity {

   Button button;
   ImageView mFullIcon,mPhoneIcon;
   ImageView profile;
   RelativeLayout name, number;
   ProfileFragment mProfileFragment;


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

       mFullIcon = findViewById(R.id.fullIcon);
       mPhoneIcon = findViewById(R.id.phoneIcon);

       mProfileFragment = new ProfileFragment();
       name = findViewById(R.id.namePath);
       name.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               mFullIcon.animate().rotation(90).start();
              startProfileFragment(ProfileFragment.NAME_VIEW);

           }
       });
       number = findViewById(R.id.phonePath);
       number.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               mPhoneIcon.animate().rotation(90).start();
               startProfileFragment(ProfileFragment.PHONE_VIEW);
           }
       });

   }

   private void startProfileFragment(int viewType) {
       ProfileFragment fragment = ProfileFragment.newInstance(viewType);
       fragment.show(getSupportFragmentManager(), fragment.getTag());
   }


}

Output

Screenshot 2021-09-23 at 15.47.32.png