آموزش جستجو در RecyclerView در برنامه نویسی اندروید
سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش جستجو در RecyclerView در برنامه نویسی اندروید می پردازیم برای جستجو از EditText استفاده می کنیم در ادامه با ما همراه باشید تا نحوه استفاده از آن را یاد بگیرید.
در قبل آموزش ConstraintLayout را قرار دادیم و از این به بعد بیشتر آموزش ما بخش Layout آن شامل ConstraintLayout خواهد بود پس اگر آن را مطالعه نکردید در سایت جستجو کنید و همینطور RecyclerView را هم در شکل و ها و انواع مختلف برای شما مثال زدیم می توانید برای تکمیل شدن آموزش به آنها رجوع کنید.
ابتدای امر چون از RecyclerView و CardView استفاده می کنیم باید کتاب خانه آن ها را اضافه کنیم.
پس وارد فایل Build.gradle شده از نوع module و خط زیر را به آن اضافه کنید.
compile 'com.android.support:recyclerview-v7:23.4.0' compile 'com.android.support:cardview-v7:23.3.+'
هم اکنون پروژه را sync کنید علت خطاهای گریدل را قبلا بررسی کرده ایم.
حالا در بخش layout خودمان کد های زیر را قرار می دهیم اسم layout ما برابر با activity_main.xml است .
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
tools:context="net.simplifiedlearning.recyclerviewsearch.MainActivity">
<EditText
android:id="@+id/editTextSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Enter search term"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="16dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/editTextSearch"
tools:layout_constraintLeft_creator="1"
android:layout_marginBottom="8dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintVertical_bias="1.0">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
دوستان تعجب نکنید گفتم باید حتما آموزش ConstraintLayout را مطالعه کنید تا متوجه شوید این کدها از کجا آماده اند اگر دوست نداشتید بدانید در بالا فقط یک EditText و یک Recyclerview قرار گرفته است بقیه کد ها مربوط به ConstraintLayout است.کد بالا layout به شکل زیر ایجاد می کند.

حالا یک فایل برای لیست آیتم های خودمان درست می کنیم این لیست در RecyclerView نمایش داده می شود.
پس یک فایل به نام list_layout.xml در پوشه layout ایجاد می کنیم و کد زیر را در آن قرار می دهیم.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textViewName"
android:padding="15dp"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
</LinearLayout>
لیست ما شامل یک CardView است که در آن یک TextView گنجانده شده است.
مثل همیشه باید آداپتور خودمان را ایجاد کنیم پس یک فایل جاوا به نام CustomAdapter.java ایجاد کرده و کد زیر را در آن قرار دهید.
package ir.programchi;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by Jfp on 6/6/2017.
*/
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private ArrayList<String> names;
public CustomAdapter(ArrayList<String> names) {
this.names = names;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_layout, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textViewName.setText(names.get(position));
}
@Override
public int getItemCount() {
return names.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView textViewName;
ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
}
}
public void filterList(ArrayList<String> filterdNames) {
this.names = filterdNames;
notifyDataSetChanged();
}
}
فکر می کنم این کلاس رو حدودا 8 بار توضیح داده ام در سایت جستجو کنید.
حالا کد مربوط به اکتیویتی اصلیمان را قرار میدهیم نام آن برابر با MainActivity.java است.
package ir.programchi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
EditText editTextSearch;
ArrayList<String> names;
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
names = new ArrayList<>();
names.add("Iran");
names.add("America");
names.add("Canada");
names.add("South Korea");
names.add("Pakistan");
names.add("Yaman");
names.add("Qatar");
names.add("Turkey");
names.add("Somalia");
names.add("Kenya");
names.add("ethiopia");
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
editTextSearch = (EditText) findViewById(R.id.editTextSearch);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new CustomAdapter(names);
recyclerView.setAdapter(adapter);
}
}
در ابتدا view مربوط به هر کدام را به دست آوردیم سپس در بالا ما یکسری داده sample به RecyclerView خودمان اضافه کردیم.
حالا برای اینکه بخش سرچ ما تکمیل شود کد های زیر را به اکتیویتی بالا اضافه کنید.
ابتدا باید یک void ایجاد کنیم که کار فیلتر را انجام دهد مثل زیر
private void filter(String text) {
ArrayList<String> filterdNames = new ArrayList<>();
for (String s : names) {
if (s.toLowerCase().contains(text.toLowerCase())) {
filterdNames.add(s);
}
}
adapter.filterList(filterdNames);
}
و حالا باید از این فیلتر درست شده استفاده کنیم همانند زیر
editTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
filter(editable.toString());
}
});
به علت اینکه میدونم 90 درصد کاربرای ما آماتورن کد اصلی رو به صورت تکمیلی در زیر قرار میدم
پس در آخر MainActivity.java همانند زیر می شود.
package net.ir.programchi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
EditText editTextSearch;
ArrayList<String> names;
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
names = new ArrayList<>();
names.add("Ramiz");
names.add("Belal");
names.add("Azad");
names.add("Manish");
names.add("Sunny");
names.add("Shahid");
names.add("Deepak");
names.add("Deepika");
names.add("Sumit");
names.add("Mehtab");
names.add("Vivek");
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
editTextSearch = (EditText) findViewById(R.id.editTextSearch);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new CustomAdapter(names);
recyclerView.setAdapter(adapter);
editTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
filter(editable.toString());
}
});
}
private void filter(String text) {
ArrayList<String> filterdNames = new ArrayList<>();
for (String s : names) {
if (s.toLowerCase().contains(text.toLowerCase())) {
filterdNames.add(s);
}
}
adapter.filterList(filterdNames);
}
}
آموزش برنامه نویسی اندروید |
سلام،ممنون از اموزش خوب شما
من توی نرم افزار از یک کلاس Initalizer استفاده کردم
این روش سرچ روی اون حالت جواب نمیده
راه حلی براش سراغ دارید؟
روش های مختلفی وجود دارد ما در اینجا به صورت کلی به آن پرداخته ایم.
بخشی از کد Initializer را قرار دهید تا بهتر بتونم کمکمتون کنم ولی حتما باید notifyDataSetChanged استفاده شود از کد های زیر استفاده کنید شاید به جواب رسیدید.
توی آداپتورتون کد زیر را قرار دهید.
و در همان جا برای سرچ کردن کد زیر را قرار دهید.
searchField.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { filter(s.toString()); } }); void filter(String text){ List temp = new ArrayList();
for(DataHolder d: displayedList){
if(d.getEnglish().contains(text)){
temp.add(d);
}
}
disp_adapter.updateList(temp);
}
موفق باشید.
ممنون از شما
کدها رو به شکل زیر استفاده کردم اما جوابی نگرفتم
public void updateList(List list){ bankList = list; notifyDataSetChanged();}
کد های mainActivity
void filter(String text){ List temp = new ArrayList(); for(bankAccount_Initalizer d: bAccountList){ temp.add(d); } mBAdapter.updateList(temp); mBAdapter.notifyDataSetChanged(); }کد های کلاس iniatalizer
package ir.m4rzb4ni.demopayment.bankAccount; import android.app.LauncherActivity; /** * Created by M4RZB4Ni on 22/07/2017. */ public class bankAccount_Initalizer extends LauncherActivity.ListItem { private String bankName; private String bAccountNum; private String bCardNum; private String bCardExpDate; private String bNum; public bankAccount_Initalizer() { } public bankAccount_Initalizer(String bNum,String bankName,String bAccountNum,String bCardNum,String bCardExpDate) { this.bNum=bNum; this.bankName=bankName; this.bAccountNum=bAccountNum; this.bCardNum=bCardNum; this.bCardExpDate=bCardExpDate; } public String getBankName() { return bankName; } public String getbAccountNum() { return bAccountNum; } public String getbCardNum() { return bCardNum; } public String getbCardExpDate() { return bCardExpDate; } public String getbNum() { return bNum; } public void setBankName(String bankName) { this.bankName=bankName; } public void setbAccountNum(String bAccountNum) { this.bankName=bAccountNum; } public void setbCardNum(String bCardNum) { this.bCardNum=bCardNum; } public void setbCardExpDate(String bCardExpDate) { this.bCardExpDate=bCardExpDate; } public void setbNum(String bNum) { this.bNum=bNum; } }ممنون که وقت میذارید
یه مطلبی پیدا کردم فکر می کنم مشکل شما را حل می کند از searchview باید استفاده کنید مثل زیر عمل کنید.
در بخشی که می خواید سرچ کنید searchview زیر را قرار دهید.
در آداپتور کد زیر را قرار دهید.
@Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence charSequence) { String charString = charSequence.toString(); if (charString.isEmpty()) { mFilteredList = mArrayList; } else { ArrayList filteredList = new ArrayList<>();
for (AndroidVersion androidVersion : mArrayList) {
if (androidVersion.getApi().toLowerCase().contains(charString) || androidVersion.getName().toLowerCase().contains(charString) || androidVersion.getVer().toLowerCase().contains(charString)) {
filteredList.add(androidVersion);
}
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilteredList = (ArrayList ) filterResults.values;
notifyDataSetChanged();
}
};
}
در بالا mFilteredList شناخته نمی شود شما باید یک آرایه به نام mFilteredList درست کنید مثل زیر
و داده هاتون رو در آن قرار دهید.
کد زیر را void است در جای مناسب همان اکتیویتی قرار دهید.
private void search(SearchView searchView) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { mAdapter.getFilter().filter(newText); return true; } }); }و در نهایت با استفاده از کد زیر آن را فیلتر کنید.
سپس view مربوط به searchview را به دست بیارید مثل زیر
SearchView searchView = (SearchView) findViewByid(search); search(searchView);موفق باشید.
سپاس گذارم خیلی زحمت کشیدید
خواهش می کنم.
با سلام
متد getFilter مربوط به چه کلاسیست؟
چون برنامه من این متد رو نمیشناسه و خطا میده….
کلاس Filterable رو هم import کردم ولی تاثیری نداشت…
سپاس از راهنماییاتون
این یک کلاس Custom است که override شده است.
سلام
کلاس AndroidVersion چه کلاسیست چون برنامه من نمیشناسه این کلاسو؟
اگه کلاس رو خودتون ساختین، برای چه چیزی این کلاس رو ساختین؟
سلام خیر کلاس کاستوم نیست برای اندروید استودیو است.
ممنون سایت فوق العاده ای دارید.
خیلی استفاده کردم.
با سلام و خسته نباشید و تشکر از مطالب مفیدتون
من توی recyclerView یک ستون ادیت قرار دادم که مقدار اون را هنگام اجرای برنامه تغییر میدم
حالا می خواهم به اون ستون دسترسی داشته باشم و مقدارشون را بخونم ولی تنها به چند تا که دیده میشن میشه دسترسی داشت و بقیه را موقع خوندن خطا میده، با دیتایی که هم واسه آداپتور ساختم فقط میشه مقادیر ثابت را بعد از پر کردن خوند و مقادیر همین ستون که تغییر داده میشه خونده نمیشن
با تشکر
شما باید آداپتورتون فابلیت سرچ را داشته باشد و آن بخش را که برای کلید سرچ در نظر گرفته مثلا Title را باید در برنامه نشان دهید ولی اگر می خواهید نشان داده نشود در اداپتور ست کرده فقط آن را نمایش ندهید.
موفق باشید.
سلام
ممنون بابت آموزش
من حرف اول رومیزنم فیلتر میکنه ولی به محض اینکه حرف دوم رو میزنم لیست رو خالی میکنه
تو بعضی مواقع تا 3 حرف هم میزاره بزنم و سرچ میکنه
ولی در کل نمیتونه دقیق سرچ کنه
باید چکار کنم؟