انشاء تطبيق note باستخدام room & rx java ( تطبيقات اندرويد ستوديو مفتوحة المصدر )

انشاء تطبيق note باستخدام room & rx java ( تطبيقات اندرويد ستوديو مفتوحة المصدر )
 

انشاء تطبيق note باستخدام room & rx java ( تطبيقات اندرويد ستوديو مفتوحة المصدر )


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


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


كيفة عمل تطبيق ملاحظات باستخدام الروم في android studio


لو تلاحظون ان التطبيق شرحنا فكرته كامله تقريبا في المقالات السابقه وايضا شرحنا لكم كل ما تريد معرفته عن room data base وفي هذا المقال سنقوم بعمل تطبيق بسيط جدا يمكنك تسجيل ملاحظاتك بداخله وايضا في النهايه ساترك لكم رابط github للتطبيق ولكل ما قمنا بشرحه في هذا القسم


الان دعونا نبدء ب التصميم الموجود في activity_main


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    android:orientation="vertical"
    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"
    tools:context=".MainActivity">

        <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/editTexttitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:ems="10"
        android:hint="title" />

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/editTextBody"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:inputType="textPersonName"
        android:hint="body"  />

<LinearLayout
    android:layout_gravity="center"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/insertButton"
        android:layout_margin="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:text="اضف"
/>

    <Button
        android:id="@+id/getButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="اعرض الملاحظات" />

    <Button
        android:id="@+id/delButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="احذف"
        android:layout_margin="10dp" />

</LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/posts_recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
/>

</LinearLayout>


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


كيفة عمل تطبيق ملاحظات باستخدام الروم في android studio

الكود السابق



<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView

    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"
    app:cardCornerRadius="8dp"
    android:layout_margin="12dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


    <LinearLayout
        android:orientation="vertical"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    <TextView
        android:id="@+id/item_title_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textColor="#7A2DE6"
        android:textSize="18dp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.045"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="MissingConstraints" />

        <ImageView
            android:id="@+id/ic_edit"
            android:layout_marginStart="230dp"
            android:src="@drawable/ic_edit"
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/ic_delete"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:src="@drawable/ic_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />


    </LinearLayout>

    <TextView
        android:id="@+id/item_body_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:text="TextView"
        android:textSize="18dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.045"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/item_title_textView" />

    </LinearLayout>
</androidx.cardview.widget.CardView>


بعدها سنقوم بعمل تصميم لل dialog الذي سوف يظهر عندما يقوم المستخدم بالتعديل على اي عنصر وهو باسم dialog_update .


انشاء تطبيق note باستخدام room & rx java ( تطبيقات اندرويد ستوديو مفتوحة المصدر )

dialog_update.xml


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/editTexttitle_edite"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:ems="10"
        android:hint="title" />

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/editTextBody_edite"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:inputType="textPersonName"
        android:hint="body"  />

    <Button
        android:id="@+id/getButton_edit"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="عدل البيانات" />

</LinearLayout>


في كلاس NoteEntity نضع المتغيرات ولا ننسى عمل لها notion كل هذا قد شرحناه سابقا .


NoteEntity.class



package com.example.localdatabaseroom.Room;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
@Entity(tableName = "NoteTable")

public class NoteEntity {
    @ColumnInfo (name = "name")
    private String name;
    @ColumnInfo (name = "content")
    private String content;

    @PrimaryKey (autoGenerate = true)
    private int id;
    public NoteEntity(String name, String content) {
        this.name = name;
        this.content = content;

    }
    public String getName() {
        return name;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}


انتقل بعدها الى interface NoteDAO وضع بها التالي وهي sql لاوامر معينه سوف تستخدم , لاحظ اننا هنا قمنا باضافة update وسوف نقوم بعمل تحديث لعنوان الملاحظة ولنص المحادثة ولكن نقوم بعمل اي تعديل في id فقط سوف نضعه لكي يعرف اننا نقف في هذا المكان .


انشاء تطبيق note باستخدام room & rx java ( تطبيقات اندرويد ستوديو مفتوحة المصدر )

NoteEntity.class


package com.example.localdatabaseroom.Room;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single;

@Dao
public interface NoteDAO {

    @Insert
    Completable insertNote (NoteEntity note);

    @Query(&quot;Select * from NoteTable&quot;)
    Single &lt;List&lt;NoteEntity&gt;&gt; getnote ();
    @Delete
    Completable deletenote(NoteEntity note);

    //delete all query
    @Delete
    Completable del(List&lt;NoteEntity&gt; noteEntities);

    //update
  @Query(&quot;UPDATE NoteTable SET name = :sname , content = :scontent WHERE id =:sid &quot;)
    Completable update (String sname , String scontent , int sid );
    @Query(&quot;Delete from NoteTable&quot;)
    Completable deleteallnote ();
}


بعدها كلاس NoteDatabase واجعله يرث من RoomDatabase وضع بداخلة التالي 


NoteDatabase.class


@Database(entities = NoteEntity.class, version = 2 , exportSchema = false)
@TypeConverters(RoomConverter.class)

public abstract class NoteDatabase extends RoomDatabase {

    private static NoteDatabase instance;
    public abstract NoteDAO noteDAO();
    public static synchronized NoteDatabase getInstance(Context context) {

if (instance == null) {
instance = Room.databaseBuilder(context.getApplicationContext(), NoteDatabase.class, "NoteDatabase")
.fallbackToDestructiveMigration()
.build();
        }

        return instance;
    }
}


بعدها كلاس الادبتر تقريبا كلاس الادبتر هو الذي به اختلاف عن السابق لان كل السابق اكواد قديمه وتم شرحها ولكن هنا تظهر فكرة edit و delete لملاحظه واحده , بكل بساطة ما سنقوم به هو اضافة ImageView داخل PostsViewHolder لكي نقوم بتعريفها عن طريق findViewById وبعدها نرجع الى onBindViewHolder نقوم بعمل لهم setOnClickListener الاول هو الخاص بالتعديل بكل بساطة سنقوم بعمل getContent و getName وgetId من الlist لنعرف اين نحن وما نريده وهذة وظيفة context بعدها سنقوم بتصميم dialog عادي جدا يمكنك عملة في fragment كما تعلمنا سابقا او استخدام الطريقة الحالية الامر راجع لك , بعدها سنقوم بعمل setText للذي سوف ندخله سواء الاسم او المحتوى ونفس الوضع مع delete ولكن هنا استخدمت rx java .


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.PostsViewHolder> {

    private List<NoteEntity> postsList;
    private Activity context;
    private NoteDatabase noteDatabase;
    @NonNull

    @Override
public PostsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new PostsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.note, parent, false));
}

    public RecyclerAdapter(List<NoteEntity> postsList, Activity context) {
        this.postsList = postsList;
        this.context = context;
    }

    @Override
    public void onBindViewHolder(@NonNull PostsViewHolder holder, int position) {
        holder.titleTV.setText(postsList.get(position).getName());
        holder.bodyTV.setText(postsList.get(position).getContent());
        noteDatabase = NoteDatabase.getInstance(context);
        NoteEntity entity = postsList.get(holder.getAdapterPosition());

        // تعديل على عنصر في note
        holder.image_edit.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                int sid = entity.getId();
                String sname = entity.getName();
                String scontent = entity.getContent();
                Dialog dialog = new Dialog(context);
                dialog.setContentView(R.layout.dialog_update);
                int width = WindowManager.LayoutParams.MATCH_PARENT;
                int higth = WindowManager.LayoutParams.WRAP_CONTENT;
                dialog.getWindow().setLayout(width, higth);
                dialog.show();

                EditText name_edit = dialog.findViewById(R.id.editTexttitle_edite);
                EditText body_edit = dialog.findViewById(R.id.editTextBody_edite);
                Button button_edit = dialog.findViewById(R.id.getButton_edit);
                name_edit.setText(sname);
                body_edit.setText(scontent);
                button_edit.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
dialog.dismiss();

noteDatabase.noteDAO().update(name_edit.getEditableText().toString(), body_edit.getEditableText().toString(), sid).subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
                            }

                            @Override
                            public void onComplete() {
                            }

@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
                            }
                        });
                        postsList.clear();
                        notifyDataSetChanged();
                    }
                });
            }
        });

        // حذف عنصر من note
        holder.image_delete.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                NoteEntity entity = postsList.get(holder.getAdapterPosition());
                noteDatabase.noteDAO().deletenote(entity);
                int position = holder.getAdapterPosition();
                postsList.remove(position);
                notifyItemRemoved(position);
                notifyItemRangeChanged(position, postsList.size());
            }
        });
    }

    public void setPostsList(List<NoteEntity> postsList) {
        this.postsList = postsList;
        notifyDataSetChanged();
    }

    public void delete(List<NoteEntity> delete) {
        this.postsList = delete;
        delete.clear();
        notifyDataSetChanged();

    }

    public class PostsViewHolder extends RecyclerView.ViewHolder {
        private TextView titleTV, bodyTV;
        private ImageView image_delete, image_edit;
        public PostsViewHolder(@NonNull View itemView) {
            super(itemView);
            titleTV = itemView.findViewById(R.id.item_title_textView);
            bodyTV = itemView.findViewById(R.id.item_body_textView);
            image_delete = itemView.findViewById(R.id.ic_delete);
            image_edit = itemView.findViewById(R.id.ic_edit);
        }
    }

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


بعدها ارجع الى mainactivity وقم بعمل ميثود باسم room_with_rx وضع بها زر لعرض المحتوى وزر للحذف وزر للاضافة وكل هذا تعرفنا عليه سابقا وقمنا بشرحه .


public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private RecyclerView postsRecyclerView;

    private List<NoteEntity> entities;

    private NoteDatabase database;

    private Button insertBtn, getBtn, deldata;

    private EditText noteTitle, bodyEt;

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

        room_with_rx();
    }

    private void room_with_rx() {
        entities = new ArrayList<>();
        insertBtn = findViewById(R.id.insertButton);
        getBtn = findViewById(R.id.getButton);
        deldata = findViewById(R.id.delButton);
        noteTitle = findViewById(R.id.editTexttitle);
bodyEt = findViewById(R.id.editTextBody);
postsRecyclerView = findViewById(R.id.posts_recyclerView);
RecyclerAdapter adapter = new RecyclerAdapter(entities, MainActivity.this);
postsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
postsRecyclerView.setAdapter(adapter);
database = NoteDatabase.getInstance(this);

insertBtn.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View view) {

database.noteDAO().insertNote(new NoteEntity(Objects.requireNonNull(noteTitle.getEditableText()).toString(), bodyEt.getEditableText().toString()))
                        .subscribeOn(Schedulers.computation())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new CompletableObserver() {

                            @Override
                            public void onSubscribe(Disposable d) {
                            }
                            @Override
                            public void onComplete() {
                                getdata(adapter);
                                adapter.notifyDataSetChanged();

                            }
                            @Override
                            public void onError(Throwable e) {
                            }
                        });
            }
        });

        deldata.setOnClickListener(new View.OnClickListener() {
            @Override

            public void onClick(View v) {
                database.noteDAO().deleteallnote()
                        .subscribeOn(Schedulers.computation())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new CompletableObserver() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {
                            }

                            @Override
                            public void onComplete() {
                                adapter.delete(entities);
                                adapter.notifyDataSetChanged();
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {
                            }
                        });
            }
        });
    }

    private void getdata(RecyclerAdapter adapter) {
            database.noteDAO().getnote()
                    .subscribeOn(Schedulers.computation())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<NoteEntity>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(List<NoteEntity> posts) {
                            adapter.setPostsList(posts);
                            adapter.notifyDataSetChanged();
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });
    }
}


الى هنا نكون انتهينا معكم في درس حول عمل تطبيق بسيط جدا باستخدام rx java و room وليكن في اعتقادك ان rx الذي قمنا باستخدامه هنا بسيط جدا لم نتعمق بها ولمشاهدة المزيد من الاكواد والشروحات يمكنك مشاهدة باقي المقالات على الموقع .


تعليقات