Dana Dalloul نشر 13 مايو أرسل تقرير نشر 13 مايو لقد جربت طريقتين اكواد مربع البحث للبحث عن اسم ويظهر اخطاء... اريد طريقة مضمونة ل اكواد مربع البحث واكواد يظهر الاسم عند البحث عنه.. وشكرا ليكم.. 2 اقتباس
0 محمد_عاطف نشر 13 مايو أرسل تقرير نشر 13 مايو يمكننا إستخدام الطريق التي تعتمد على استخدام EditText كمربع للبحث و RecyclerView لعرض النتائج. أولا سنقوم بإضافة مربع البحث EditText والقائمة اللتي ستعرض النتائج RecyclerView في ملف ال Layout الخاص بال Activity أو ال Fragment. بعد ذلك في ملف ال Java سنحصل على مراجع للعناصر اللتي أضفناها باستخدام ال findViewById. ومن ثم سنستخدم واجهة TextWatcher حتى نستمع للتغييرات اللتي تحدث في مربع البحث أولا بأول. وفي كل مرة يتغير فيها النص في مربع البحث سنقوم بفلترة البيانات الأصلية ونعرض النتائج المتطابقة في ال RecyclerView. وأخيرا سننشأ ال Adapter لل RecyclerView لربط البيانات بال RecyclerView وعرضها بشكل صحيح. الآن إليك ملف التنسيق XML وليكن بإسم activity_main.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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp" tools:context=".MainActivity"> <EditText android:id="@+id/searchEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="ابحث عن اسم..." android:inputType="text" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginTop="8dp" android:layout_weight="1" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> </LinearLayout> وملف ال Activity أو ال Fragment وليكن بإسم MainActivity.java: import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private EditText searchEditText; private RecyclerView recyclerView; private NameAdapter adapter; private List<String> originalNameList; private List<String> filteredNameList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); searchEditText = findViewById(R.id.searchEditText); recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); originalNameList = new ArrayList<>(); originalNameList.add("ahmed"); originalNameList.add("danaa"); originalNameList.add("mohamed"); originalNameList.add("mona"); originalNameList.add("ali"); originalNameList.add("mostafe"); filteredNameList = new ArrayList<>(originalNameList); adapter = new NameAdapter(filteredNameList); recyclerView.setAdapter(adapter); searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { filterNames(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); } private void filterNames(String query) { filteredNameList.clear(); if (query.isEmpty()) { filteredNameList.addAll(originalNameList); } else { query = query.toLowerCase(); for (String name : originalNameList) { if (name.toLowerCase().contains(query)) { filteredNameList.add(name); } } } adapter.notifyDataSetChanged(); } } وأخيرا ملف ال Adapter لل RecyclerView وليكن بإسم NameAdapter.java: import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class NameAdapter extends RecyclerView.Adapter<NameAdapter.NameViewHolder> { private List<String> nameList; public NameAdapter(List<String> nameList) { this.nameList = nameList; } @NonNull @Override public NameViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new NameViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull NameViewHolder holder, int position) { String name = nameList.get(position); holder.nameTextView.setText(name); } @Override public int getItemCount() { return nameList.size(); } public static class NameViewHolder extends RecyclerView.ViewHolder { public TextView nameTextView; public NameViewHolder(@NonNull View itemView) { super(itemView); nameTextView = itemView.findViewById(android.R.id.text1); } } } في ملف ال XML قمنا بإنشاء ال EditText بال ID searchEditText وهو مربع البحث اللذي سيقوم المستخدم بالكتابة فيه. و أنشأنا RecyclerView بال ID recyclerView وسيعرض قائمة الأسماء المتطابقة. واستخدمنا LinearLayoutManager حتى نعرض العناصر بشكل عمودي. وفي ملف في ملف ال Activity قمنا بالحصول على مراجع ل EditText و RecyclerView باستخدام findViewById وأنشأنا قائمتين: originalNameList: تحتوي على جميع الأسماء الأصلية. filteredNameList: ستحتوي على الأسماء اللي تتطابق مع نص البحث. وفي البداية تكون نسخة من originalNameList. وأنشأنا ال NameAdapter وربطناه بال RecyclerView وقمنا باستخدام TextWatcher حتى نستمع للتغييرات في نص searchEditText في كل مرة بيتغير النص ونقوم بإستدعاء الدالة filterNames. وفي ملف ال Adapter قمنا بإستقبال قائمة الأسماء nameList اللتي سيتم إرسالها وهنا هي filteredNameList. 1 اقتباس
0 Mustafa Suleiman نشر 13 مايو أرسل تقرير نشر 13 مايو تتوفر مكتبة androidx.appcompat.widget.SearchView ضمن مكتبة أندرويد نفسها لإضافة مربع بحث بسهولة وخاصة مع قائمة RecyclerView أو حتى مع Toolbar ولا تحتاج لمكتبة خارجية. كمثال لملف واجهة وليكن باسم search_menu.xml: <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_search" android:title="بحث" android:icon="@android:drawable/ic_menu_search" android:showAsAction="always" android:actionViewClass="androidx.appcompat.widget.SearchView" /> </menu> ثم في Activity: @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.search_menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { // عند الضغط على زر البحث return false; } @Override public boolean onQueryTextChange(String newText) { nameAdapter.filter(newText); return false; } }); return true; } أما لو أردتي تنفيذ الأمر بشكل يدوي وتحكم كامل، ستحتاجين إلى RecyclerView للبحث عن اسم وعرض النتائج، أي لو لديكِ قائمة بأسماء وتريدين البحث فيهم، ستقومين بإنشاء layout/activity_main.xml لتصميم الواجهة. لكن للعلم تلك الطريقة على عكس SearchView لا تقدم تجربة مستخدم رسمية أي زر إكس للحذف أو دعم إدراج صوتي وخلافه، وستحتاجين إلى تنفيذ الخيارات متقدمة بنفسك من إخفاء لوحة المفاتيح والاحتفاظ بالسجل. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/searchEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="ابحث عن اسم" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ثم NameAdapter.java وهو الأدابتر الخاص بالأسماء: public class NameAdapter extends RecyclerView.Adapter<NameAdapter.NameViewHolder> { private List<String> nameList; private List<String> nameListFull; public NameAdapter(List<String> nameList) { this.nameList = new ArrayList<>(nameList); this.nameListFull = new ArrayList<>(nameList); // نسخة كاملة للبحث } @NonNull @Override public NameViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new NameViewHolder(view); } @Override public void onBindViewHolder(@NonNull NameViewHolder holder, int position) { holder.textView.setText(nameList.get(position)); } @Override public int getItemCount() { return nameList.size(); } public void filter(String text) { nameList.clear(); if (text.isEmpty()) { nameList.addAll(nameListFull); } else { text = text.toLowerCase(); for (String name : nameListFull) { if (name.toLowerCase().contains(text)) { nameList.add(name); } } } notifyDataSetChanged(); } static class NameViewHolder extends RecyclerView.ViewHolder { TextView textView; NameViewHolder(View itemView) { super(itemView); textView = itemView.findViewById(android.R.id.text1); } } } ثم في MainActivity.java نكتب المنطقي البرمجي للبحث: public class MainActivity extends AppCompatActivity { private NameAdapter nameAdapter; private EditText searchEditText; private RecyclerView recyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); searchEditText = findViewById(R.id.searchEditText); recyclerView = findViewById(R.id.recyclerView); // إعداد قائمة بأسماء، استبدليهم بأسماءك List<String> names = Arrays.asList("محمد", "علي", "سارة", "خالد", "فاطمة", "يوسف"); nameAdapter = new NameAdapter(names); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(nameAdapter); searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { nameAdapter.filter(s.toString()); } @Override public void afterTextChanged(Editable s) {} }); } } مربع البحث هو EditText عند الكتابة به يتم فلترة الأسماء في قائمة RecyclerView تلقائيًا. اقتباس
0 Dana Dalloul نشر 13 مايو الكاتب أرسل تقرير نشر 13 مايو بتاريخ 19 دقائق مضت قال محمد عاطف17: يمكننا إستخدام الطريق التي تعتمد على استخدام EditText كمربع للبحث و RecyclerView لعرض النتائج. أولا سنقوم بإضافة مربع البحث EditText والقائمة اللتي ستعرض النتائج RecyclerView في ملف ال Layout الخاص بال Activity أو ال Fragment. بعد ذلك في ملف ال Java سنحصل على مراجع للعناصر اللتي أضفناها باستخدام ال findViewById. ومن ثم سنستخدم واجهة TextWatcher حتى نستمع للتغييرات اللتي تحدث في مربع البحث أولا بأول. وفي كل مرة يتغير فيها النص في مربع البحث سنقوم بفلترة البيانات الأصلية ونعرض النتائج المتطابقة في ال RecyclerView. وأخيرا سننشأ ال Adapter لل RecyclerView لربط البيانات بال RecyclerView وعرضها بشكل صحيح. الآن إليك ملف التنسيق XML وليكن بإسم activity_main.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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp" tools:context=".MainActivity"> <EditText android:id="@+id/searchEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="ابحث عن اسم..." android:inputType="text" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginTop="8dp" android:layout_weight="1" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> </LinearLayout> وملف ال Activity أو ال Fragment وليكن بإسم MainActivity.java: import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private EditText searchEditText; private RecyclerView recyclerView; private NameAdapter adapter; private List<String> originalNameList; private List<String> filteredNameList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); searchEditText = findViewById(R.id.searchEditText); recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); originalNameList = new ArrayList<>(); originalNameList.add("ahmed"); originalNameList.add("danaa"); originalNameList.add("mohamed"); originalNameList.add("mona"); originalNameList.add("ali"); originalNameList.add("mostafe"); filteredNameList = new ArrayList<>(originalNameList); adapter = new NameAdapter(filteredNameList); recyclerView.setAdapter(adapter); searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { filterNames(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); } private void filterNames(String query) { filteredNameList.clear(); if (query.isEmpty()) { filteredNameList.addAll(originalNameList); } else { query = query.toLowerCase(); for (String name : originalNameList) { if (name.toLowerCase().contains(query)) { filteredNameList.add(name); } } } adapter.notifyDataSetChanged(); } } وأخيرا ملف ال Adapter لل RecyclerView وليكن بإسم NameAdapter.java: import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class NameAdapter extends RecyclerView.Adapter<NameAdapter.NameViewHolder> { private List<String> nameList; public NameAdapter(List<String> nameList) { this.nameList = nameList; } @NonNull @Override public NameViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new NameViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull NameViewHolder holder, int position) { String name = nameList.get(position); holder.nameTextView.setText(name); } @Override public int getItemCount() { return nameList.size(); } public static class NameViewHolder extends RecyclerView.ViewHolder { public TextView nameTextView; public NameViewHolder(@NonNull View itemView) { super(itemView); nameTextView = itemView.findViewById(android.R.id.text1); } } } في ملف ال XML قمنا بإنشاء ال EditText بال ID searchEditText وهو مربع البحث اللذي سيقوم المستخدم بالكتابة فيه. و أنشأنا RecyclerView بال ID recyclerView وسيعرض قائمة الأسماء المتطابقة. واستخدمنا LinearLayoutManager حتى نعرض العناصر بشكل عمودي. وفي ملف في ملف ال Activity قمنا بالحصول على مراجع ل EditText و RecyclerView باستخدام findViewById وأنشأنا قائمتين: originalNameList: تحتوي على جميع الأسماء الأصلية. filteredNameList: ستحتوي على الأسماء اللي تتطابق مع نص البحث. وفي البداية تكون نسخة من originalNameList. وأنشأنا ال NameAdapter وربطناه بال RecyclerView وقمنا باستخدام TextWatcher حتى نستمع للتغييرات في نص searchEditText في كل مرة بيتغير النص ونقوم بإستدعاء الدالة filterNames. وفي ملف ال Adapter قمنا بإستقبال قائمة الأسماء nameList اللتي سيتم إرسالها وهنا هي filteredNameList. طريقة رائعة وسهلة ولكن سؤال: انت اضفت البيانات يدوياً للتطبيق.. التطبيق بتاعي رح اضيف البيانات من sql ف كيف رح ابحث منه يعني ايش احط بدا كود originalNameList.add("danaa"); لانو البيانات رح تكون اضافتها الياً مش يدوياً 1 اقتباس
0 محمد_عاطف نشر 13 مايو أرسل تقرير نشر 13 مايو بتاريخ 14 دقائق مضت قال Dana Dalloul: طريقة رائعة وسهلة ولكن سؤال: انت اضفت البيانات يدوياً للتطبيق.. التطبيق بتاعي رح اضيف البيانات من sql ف كيف رح ابحث منه يعني ايش احط بدا كود originalNameList.add("danaa"); لانو البيانات رح تكون اضافتها الياً مش يدوياً نعم وضعتها يدويا . ولكن بالفعل يمكنكِ إما إستدعاء البيانات من قاعدة البيانات . او لو كان لديكِ API يقوم بجلبها . وإذا كنتِ تريدين إستدعائها من قاعدة البيانات فيمكننا إستخدام قاعدة بيانات sqlite وجلب البيانات منها . ولنفرض أن ملف قاعدة البيانات لديكِ هو بإسم database_file.db وإسم الجدول هو names والعمود الذي به الأسماء هو name . وحينها سيكون ملف MainActivity.java كالتالي : import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private EditText searchEditText; private RecyclerView recyclerView; private NameAdapter adapter; private List<NameItem> originalNameList; private List<NameItem> filteredNameList; private DatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); searchEditText = findViewById(R.id.searchEditText); recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); dbHelper = new DatabaseHelper(this); originalNameList = getAllNamesFromDatabase(); // جلب البيانات من قاعدة البيانات filteredNameList = new ArrayList<>(originalNameList); adapter = new NameAdapter(filteredNameList); recyclerView.setAdapter(adapter); searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { filterNames(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); } private List<NameItem> getAllNamesFromDatabase() { List<NameItem> names = new ArrayList<>(); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.query( "names", // اسم الجدول new String[]{"_id", "name"}, // الأعمدة اللي نريد جلبها null, null, null, null, null ); if (cursor != null && cursor.moveToFirst()) { do { int id = cursor.getInt(cursor.getColumnIndexOrThrow("_id")); String name = cursor.getString(cursor.getColumnIndexOrThrow("name")); names.add(new NameItem(id, name)); } while (cursor.moveToNext()); cursor.close(); } db.close(); return names; } private void filterNames(String query) { filteredNameList.clear(); if (query.isEmpty()) { filteredNameList.addAll(originalNameList); } else { query = query.toLowerCase(); for (NameItem nameItem : originalNameList) { if (nameItem.getName().toLowerCase().contains(query)) { filteredNameList.add(nameItem); } } } adapter.notifyDataSetChanged(); } public static class NameItem { private int id; private String name; public NameItem(int id, String name) { this.id = id; this.name = name; } public String getName() { return name; } } // صنف مساعد للتعامل مع قاعدة البيانات public static class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "database_file.db"; private static final int DATABASE_VERSION = 1; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } } وسنحتاج إلى تعديل ال Adapter حتى يستقبل قائمة من نوع NameItem ويعرض الاسم بداخل الكائن : import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class NameAdapter extends RecyclerView.Adapter<NameAdapter.NameViewHolder> { private List<NameItem> nameList; public NameAdapter(List<NameItem> nameList) { this.nameList = nameList; } @NonNull @Override public NameViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new NameViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull NameViewHolder holder, int position) { NameItem currentItem = nameList.get(position); holder.nameTextView.setText(currentItem.getName()); // الوصول للاسم من كائن NameItem } @Override public int getItemCount() { return nameList.size(); } public static class NameViewHolder extends RecyclerView.ViewHolder { public TextView nameTextView; public NameViewHolder(@NonNull View itemView) { super(itemView); nameTextView = itemView.findViewById(android.R.id.text1); } } public static class NameItem { private int id; private String name; public NameItem(int id, String name) { this.id = id; this.name = name; } public String getName() { return name; } } } 1 اقتباس
السؤال
Dana Dalloul
لقد جربت طريقتين اكواد مربع البحث للبحث عن اسم ويظهر اخطاء...
اريد طريقة مضمونة ل اكواد مربع البحث واكواد يظهر الاسم عند البحث عنه..
وشكرا ليكم..
5 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.