تحديث جميع البيانات لمستخدمي التطبيق وتصميم صفحة للمستخدمين

 

تحديث جميع البيانات لمستخدمي التطبيق وتصميم صفحة للمستخدمين

تحديث جميع البيانات لمستخدمي التطبيق وتصميم صفحة للمستخدمين

في هذا الدرس سوف نقوم بتصميم صفحة تحتوي على قائمة بها جميع مستخدمي التطبيق لكي تتمكن من اضافتهم والتحدث معهم , وايضا سوف نتعرف على كيفية عرض جميع مستخدمي التطبيق للجميع لكي تتمكن من اضافتهم وبدء محادثة جديدة معهم اذا كنت ترغب بذلك .


أصبح الاقبال على ظيفة android developer كبير جدا في هذه الايام وذلك لان مجال ال developing اصبح مطور بكثره في مختلف الدول سواء العربيه او الاجنبيه وليس فقط android developer بل هناك ios developer وهو الشخص المتخصص في تطوير تطبيقات نظام ios الخاص بشركة apple وفي الغالب يكون راتب الios developer اكبر في بعض الاحيان وذلك بسبب قلة المبرمجين في نظام ios واصبحت الكثير من القنوات والمواقع على منصة YouTube تختص بشروحات ios وايضا android ويعد موقعنا واحد من اكبر المواقع المختصه في هذا المجال ومساعدة المبرمجين في التعلم .


اثناء تعلمك للdevelopment يفضل ان يكون لديك ورقه وقلم لتدوين كل ما تحتاجه وتتعلمه ولكن نحن في موقعنا نقوم بتوفير لك كل ما تريد دون الحاجه الى الورقه والقلم فقط كل ما تحتاجه هو التطبيق على الدروس التي نضعها وحسب لكي تفهم كيف يعمل الكود وايضا تكتسب خبره من كثرة كتابة الcode, ودائما حاول ان تعتمد بشكل كبير على انماط التصميم في البرجخ مثل mvvm وهو اشهر نمط حاليا والكثير من الشركات تطلبه ولك لاهميته التنظميه في كتابة الكود مما يجعل من اي شخص اخر قادر على التعديل على الكود الخاص بك ويعرف كل شخص عمله ui , back , developer يكون كل شخص قادر على معرفة وظيفته بالتحديد 


تصميم recyclerview تحتوي على بيانات المستخدمين للتطبيق

سوف نقوم اولا بتصميم شكل recyclerview لبيانات المستخدمين وبكل بساطة نريد ان نعرض الاسم الخاص بالمستخدم وايضا الاميل الخاص به والصورة الخاصه به ولذلك سوف نقوم بعمل تصميم يحتوي على هذة المواصفات فقط داخل recyclerview كما يظهر .


تصميم recyclerview تحتوي على بيانات المستخدمين للتطبيق

item_container_user.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/_8sdp">

    <com.makeramen.roundedimageview.RoundedImageView
        android:id="@+id/imageProfile"
        android:layout_width="@dimen/_35sdp"
        android:layout_height="@dimen/_35sdp"
        android:background="@drawable/background_image"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:riv_corner_radius="@dimen/_15sdp"
        app:riv_oval="true" />

    <TextView
        android:id="@+id/text_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/_8sdp"
        android:layout_marginEnd="@dimen/_8sdp"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="Chat app"
        android:textColor="@color/primary_text"
        android:textSize="@dimen/_13ssp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/imageProfile"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textEmail"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/_8sdp"
        android:layout_marginTop="@dimen/_5sdp"
        android:layout_marginEnd="@dimen/_8sdp"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="email@gmail.com"
        android:textColor="@color/secondary_text"
        android:textSize="@dimen/_10ssp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/imageProfile"
        app:layout_constraintTop_toBottomOf="@id/text_name" />

</androidx.constraintlayout.widget.ConstraintLayout>


تصميم صفحة البحث عن مستخدمي التطبيق 

سوف نقوم هنا بعمل صفحة جديدة تحتوي على مكان لتحديد مستخدمي التطبيق مثال على ذلك , يظهر هنا كل مستخدمي التطبيق بنفس الشكل الذي قمنا به بالاعلى ويمكنك النقر على اي مستخدم منهم وسوف ينقلك الى صفحة المحادثة معه لكي تتمكن من بدء محادثة مع المستخدم .


تصميم صفحة البحث عن مستخدمي التطبيق

activity_user


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/primary"
    android:animateLayoutChanges="true"
    tools:context=".activities.UserActivity">

    <com.makeramen.roundedimageview.RoundedImageView
        android:id="@+id/imageBack"
        android:background="@drawable/background_icon"
        android:src="@drawable/ic_back"
        android:padding="@dimen/_6sdp"
        android:layout_margin="@dimen/_14sdp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_width="@dimen/_30sdp"
        android:layout_height="@dimen/_30sdp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/select_image"
        android:textColor="@color/white"
        app:layout_constraintBottom_toBottomOf="@id/imageBack"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/imageBack"
        android:textStyle="bold" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="@dimen/_12sdp"
        android:background="@drawable/background_content_bottom"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/imageBack" >

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="@dimen/_20sdp"
            android:overScrollMode="never"
            android:visibility="gone"
            android:orientation="vertical"
            android:clipToPadding="false"
            />

        <ProgressBar
            android:id="@+id/progress"
            android:layout_gravity="center"
            android:layout_width="@dimen/_25sdp"
            android:layout_height="@dimen/_25sdp"/>

        <TextView
            android:id="@+id/textErrorMessage"
            android:layout_gravity="center"
            android:layout_marginStart="@dimen/_24sdp"
            android:layout_marginEnd="@dimen/_24sdp"
            android:gravity="center"
            android:textColor="@color/error"
            android:textSize="@dimen/_12ssp"
            android:visibility="gone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        
    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>


تصميم background_content_bottom

سوف نقوم بعمل الشكل الابيض وهو عبارة عن التصميم الذي قمنا به بالاعلى وسوف يحتوي على المحتويات الخاصه بالمستخدمين .


تصميم background_content_bottom

background


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@color/white" />

    <corners
        android:topRightRadius="@dimen/_32sdp"
        android:topLeftRadius="@dimen/_32sdp" />

</shape>


عمل كلاس لتمرير البيانات

عمل كلاس لتمرير البيانات

في طبيعة الحال نريد تمرير اسم المستخدم والبريد الصورة والتوكن اذا اردت وسوف نقوم بعمل هذة الخطوات كما يظهر بالصورة لكي نتمكن من تمريرهم .


User.class


public class User implements Serializable {

    public String name , image , email , token ;

    public String getName() {
        return name;
    }

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

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}


عمل Adapter لل recyclerView باستخدام ViewBinding

عمل Adapter لل recyclerView باستخدام ViewBinding

في هذة المرحلة سوف نقوم بعمل الخاص بالrecyclerView لكي نستطيع تكرار الrecyclerView اكثر من مره على حسب عدد المستخدمين ولقد شرحنا الrecyclerView في كثير من الدروس .

AdapterUser.class


public class AdapterUser extends RecyclerView.Adapter&lt;AdapterUser.Holder&gt; {
    private List&lt;User&gt; users;

    public AdapterUser(List&lt;User&gt; users) {
        this.users = users;
    }

    private Bitmap getUserImage(String encodeImage) {
        byte[] bytes = Base64.decode(encodeImage , Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes,0,bytes.length);
    }


    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new Holder(ItemContainerUserBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {
        holder.setData(users.get(position));
    }

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


    class Holder extends RecyclerView.ViewHolder {
        ItemContainerUserBinding binding;

        public Holder(@NonNull ItemContainerUserBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }

        // define all id in ItemContainerUser .
        void setData(User user) {
            binding.textEmail.setText(user.email);
            binding.textName.setText(user.name);
            binding.imageProfile.setImageBitmap(getUserImage(user.image));
        }
    }
}


استخدام UserActivity لعرض بيانات جميع مستخدمي عند الدخول اليها 

في هذة الصفحة سوف نقوم بكتابة methode للحصول على جميع المستخدمين الذين قاموا بالتسجل في هذا التطبيق عن طريق خدمة firebase وايضا سوف نقوم بفلتره البيانات التي نريد الحصول عليها ونريد فقط الحصول على الاسم والبريد والصورة والتوكن وهذا سوف نحتاجه بشكل اكبر عندما نريد ارسال رسائل له تظهر في الnotification 


استخدام UserActivity لعرض بيانات جميع مستخدمي عند الدخول اليها

UserActivity.class


public class UserActivity extends AppCompatActivity {

    private ActivityUserBinding binding;
    private PreferenceManager preferenceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityUserBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        preferenceManager = new PreferenceManager(getApplicationContext());
        getUsers();
        setListeners();

    }

    private void setListeners(){
        binding.imageBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
    }

    // عرض كل الاشخاص الذين قامو بالتسجيل في التطبيق داخل recyclerView
    private void getUsers() {
        loading(true);
        FirebaseFirestore firestore = FirebaseFirestore.getInstance();
        firestore.collection(Constants.KEY_COLLECTION_USERS).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                loading(false);
                String currentUserId = preferenceManager.getString(Constants.KEY_USER_ID);
                if (task.isSuccessful() && task.getResult() != null) {
                    List<User> users = new ArrayList<>();
                    for (QueryDocumentSnapshot queryDocumentSnapshot : task.getResult()) {
                        if (currentUserId.equals(queryDocumentSnapshot.getId())) {
                            continue;
                        }
                        User user = new User();
                        user.name = queryDocumentSnapshot.getString(Constants.KEY_NAME);
                        user.email = queryDocumentSnapshot.getString(Constants.KEY_EMAIL);
                        user.image = queryDocumentSnapshot.getString(Constants.KEY_IMAGE);
                        user.token = queryDocumentSnapshot.getString(Constants.KEY_FCM_TOKEN);
                        users.add(user);
                        }
                        if (users.size() > 0) {
                        AdapterUser adapterUser = new AdapterUser(users);
                        binding.recyclerview.setAdapter(adapterUser);
                        binding.recyclerview.setLayoutManager(new LinearLayoutManager(UserActivity.this));
                        binding.recyclerview.setVisibility(View.VISIBLE);
                    } else {
                        showErrorMessage();
                    }
                } else {
                    showErrorMessage();
                }
            }
        });
    }

    private void showErrorMessage() {
        binding.textErrorMessage.setText(String.format("%s" , getString(R.string.No_User_available)));
        binding.textErrorMessage.setVisibility(View.VISIBLE);
    }

    protected void loading (Boolean isLoading) {
        if (isLoading) {
            binding.progress.setVisibility(View.VISIBLE);
        } else {
            binding.progress.setVisibility(View.INVISIBLE);
        }
    }

}


التعديل على صفحة activity_main واضافة FloatingActionButton لاضافة مستخدمين

سوف نقوم بالتعديل على activity_main ونضيف بداخلها فقط FloatingActionButton وهو عباره عن زر دائري يظهر في زاوية التطبيق لكي يتمكن المستخدم من النقر عليه والتحويل الى صفحة جديدة بها مستخدمي التطبيق .


التعديل على صفحة activity_main واضافة FloatingActionButton لاضافة مستخدمين

activity_main


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:animateLayoutChanges="true"
    android:background="@color/primary"

    tools:context=".activities.MainActivity">

    <com.makeramen.roundedimageview.RoundedImageView
        android:id="@+id/imageProfile"
        android:layout_width="@dimen/_30sdp"
        android:layout_height="@dimen/_30sdp"
        android:layout_margin="@dimen/_16sdp"
        android:scaleType="centerCrop"
        app:riv_corner_radius="@dimen/_16sdp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"  />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/image_signOut"
        android:layout_width="@dimen/_30sdp"
        android:layout_height="@dimen/_30sdp"
        android:layout_margin="@dimen/_16sdp"
        android:padding="@dimen/_6sdp"
        android:src="@drawable/ic_logout"
        android:background="@drawable/background_icon"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"  />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="@color/white"
        android:textStyle="bold"
        android:textSize="@dimen/_14ssp"
        android:layout_marginEnd="@dimen/_8sdp"
        android:layout_marginStart="@dimen/_8sdp"
        app:layout_constraintBottom_toBottomOf="@id/imageProfile"
        app:layout_constraintEnd_toStartOf="@id/image_signOut"
        app:layout_constraintStart_toEndOf="@id/imageProfile"
        app:layout_constraintTop_toTopOf="@id/imageProfile" />

    <ProgressBar
        android:id="@+id/progressbar"
        android:layout_width="@dimen/_25sdp"
        android:layout_height="@dimen/_25sdp"
        android:layout_gravity="center"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:background="@drawable/background_content_bottom"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/imageProfile"
        android:layout_marginTop="@dimen/_16sdp"
        android:layout_width="match_parent"
        android:layout_height="0dp" >

    </FrameLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fa_new_chat"
        android:layout_width="wrap_content"
        android:layout_margin="@dimen/_18sdp"
        app:layout_constraintEnd_toEndOf="parent"
        android:contentDescription="@string/app_name"
        android:src="@drawable/ic_add"
        android:backgroundTint="@color/primary"
        app:layout_constraintBottom_toBottomOf="parent"
        android:tint="@color/white"
        android:layout_height="wrap_content" />

</androidx.constraintlayout.widget.ConstraintLayout>


عمل انتقال من MainActivity الى UserActivity

في النهاية سوف نقوم بعمل الكود الخاص بالFloatingActionButton وهو بكل بساطة ينقل المستخدم من الموقع الحالي الى الصفحة الخاصه بمستخدمي التطبيق لكي يتمكن من اضافة الاشخاص الذي يستخدمون التطبيق .


عمل انتقال من MainActivity الى UserActivity

MainActivity


private void listener() {
        binding.imageSignOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loading(true);
                sign_out();
            }
        });
        binding.faNewChat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(getApplicationContext() , UserActivity.class));
                finish();
            }
        });
    }
    


تعليقات