پروژه اتصال به برد arduino با استفاده از پورت سریال با سی شارپ
پروژه اتصال به برد arduino با استفاده از پورت سریال در سی شارپ
۱۳۹۶-۱۱-۰۷

جستجو پیشرفته در ریسایکلر ویو (RecyclerView)

جستجو پیشرفته در ریسایکلر ویو (RecyclerView) ، در این آموزش میخوایم جستجو پیشرفته در ریسایکلر ویو (جستجوی زنده یا آنی) با استفاده از کتایخانه هایی مثل Retrofit, Rxbinding , Gson کار کنیم

نتیجه نهایی این آموزش بصورت زیر خواهد بود …

 

روی تصویر زیر کلیک کنید

جستجو پیشرفته در ریسایکلر ویو

جستجو پیشرفته در ریسایکلر ویو

جستجو پیشرفته در ریسایکلر ویو

خب اولین کاری که باید بکنیم مسلما اینکه کتابخونه های مورد نیاز رو به گردل پروژه اضافه کنیم که ما برای این پروژه از این کتابخونه ها استفاده میکنیم

// views
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'

//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

//rxjava
implementation 'com.jakewharton.rxbinding:rxbinding:0.4.0'

 

به علاوه این خط کدرو هم به بخش defaultConfig گردل برای اجرای بدون مشکل وکتور ها اضافه میکنیم

defaultConfig {

....

//https://stackoverflow.com/a/35795933 ,for show vector in apis bellow 5
vectorDrawables.useSupportLibrary = true

خب طبیعتا اقدام بعدی نوشتن کدهای کاتلینه.
اولین کلاسی که باید بنویسیمش کلاس ServiceGenerator هست که بیس اصلی ارتباط ما با سرور رو فراهم میکنه و در ادامه برای هر درخواست فقط کافیه که صداش بزنیم و درخواست رو ارسال کنیم

package dn.marjan.realtimesearch

import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
* Created by Marjan.Dnejad
* on 4/17/2018.
*/
class ServiceGenerator
{

private val URL: String = "http://10.0.3.2/"
private var apiService: TaskService?= null

init {

val okClient = OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS) // for handle timeout exception
.readTimeout(10, TimeUnit.SECONDS)
.build()

val gson = GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.setLenient()
.create()

val restAdapter = retrofit2.Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okClient)
.build()

apiService = restAdapter.create(TaskService::class.java)
}

fun getService() : TaskService = apiService!!
}

کلاس بعدی که باید ایجاد شه و باز هم مرتبط هست به درخواست های ارسالی به سرور
کلاس TaskService که فقط مشخصه های درخواست ارسالی به سرور رو مشخص میکنه مثل آدرس endpoint یو ار ال ها و Get یا Post بودن آنها و … (برای اطلاعات بیشتر در باره درخواست های retrofit به سایت مرجع رتروفیت برید و مطالعه کنید )

package dn.marjan.realtimesearch

import retrofit2.Call
import okhttp3.ResponseBody
import retrofit2.http.GET

/**
* Created by Marjan.Dnejad
* on 4/17/2018.
*/
interface TaskService {

@GET("getData.php")
fun getStudents(): Call<ResponseBody>
}

رتروفیت کارها میدونن که دیگه تو رتروفیت خبری از JsonObject و JsonArray نیست !!
اینجا فقط کافیه از annotation یا حاشیه نویس@SerializedName(“”) استفاده کنیم و هر فیلدی که بصورت جیسون از سرور میاد رو به یک متغیر اختصاص بدیم
و فقط کافیه جیسون رو با کتابخونه Gson تبدیل کنیم به یک شی یا آرایه تروتمیز و ازش استفاده کنیم !!

رتروفیت = ته خوشبختی

 

package dn.marjan.realtimesearch

import android.app.Activity
import android.content.Context
import android.support.v7.app.AlertDialog
import com.google.gson.Gson
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import com.google.gson.reflect.TypeToken
import kotlinx.android.synthetic.main.view_dialog_item.view.*

class Students {

@SerializedName("ID")
@Expose
var iD: String? = null
@SerializedName("Name")
@Expose
var name: String? = null
@SerializedName("Family")
@Expose
var family: String? = null
@SerializedName("Age")
@Expose
var age: String? = null
@SerializedName("Average")
@Expose
var average: String? = null
@SerializedName("City")
@Expose
var city: String? = null

companion object {

//get student list from json data came from server
fun getStudentsFromJson(value: String): List<Students> {
val gson = Gson()
val listType = object : TypeToken<List<Students>>() {}.type
val data = gson.fromJson<List<Students>>(value, listType)

return data
}

//search a char in student list compair with student name
fun searchStudent(context: Context, text: String, stuList: ArrayList<Students>): ArrayList<Students> {

val searchRes: ArrayList<Students> = ArrayList()
for (i in 0 until stuList.size) {
stuList[i].name.let {
if (stuList[i].name!!.contains(text))
searchRes.add(stuList[i])
}
}

return searchRes
}

//when click on a student item to show dialog of student info
fun studentItemClick(stud: Students, context: Context, activity: Activity) {
val builder = AlertDialog.Builder(context)

val view = activity.layoutInflater.inflate(R.layout.view_dialog_item, null)
builder.setView(view)

view.txv_name.text = stud.name
view.txv_family.text = stud.family
view.txv_age.text = stud.age
view.txv_avr.text = stud.average
view.txv_city.text = stud.city

builder.create().show()
}
}

}

من یک سری متد های مخصوص کلاس student رو گذاشتم داخل کلاس خودش و از companion object استفاده کردم که در جاوا کارهمون static رو انجام میده
اینکه هرمتد چکاری رو انجام میده بصورت شفاف کامنت شده
لایه ای که در دیالوگ نمایش داده میشه هم بدین صورت هست

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_stud"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="@string/name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/txv_name"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView2"
app:layout_constraintEnd_toStartOf="@+id/textView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView2" />

<TextView
android:id="@+id/txv_family"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView6"
app:layout_constraintEnd_toStartOf="@+id/textView6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView6" />

<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="@string/family"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />

<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="@string/age"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6" />

<TextView
android:id="@+id/txv_age"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView7"
app:layout_constraintEnd_toStartOf="@+id/textView7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView7" />

<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="@string/average"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView7" />

<TextView
android:id="@+id/txv_avr"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
android:textColor="@android:color/holo_red_dark"
app:layout_constraintBottom_toBottomOf="@+id/textView9"
app:layout_constraintEnd_toStartOf="@+id/textView9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView9" />

<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:text="@string/city"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView9"
app:layout_constraintVertical_bias="0.0" />

<TextView
android:id="@+id/txv_city"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
android:textColor="@android:color/holo_green_light"
app:layout_constraintBottom_toBottomOf="@+id/textView11"
app:layout_constraintEnd_toStartOf="@+id/textView11"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView11" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>

حالا کلاس آداپتر لیست میمونه که که قطعا نیاز به یک لایه برای اتچ شدن در لیست داره

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.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"
android:id="@+id/card_stud"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="@string/name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/txv_name"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView2"
app:layout_constraintEnd_toStartOf="@+id/textView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView2" />

<TextView
android:id="@+id/txv_family"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView6"
app:layout_constraintEnd_toStartOf="@+id/textView6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView6" />

<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="@string/family"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />

<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:text="@string/average"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6" />

<TextView
android:id="@+id/txv_avr"
style="@style/MyTextViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="TextView"
android:textColor="@android:color/holo_red_dark"
app:layout_constraintBottom_toBottomOf="@+id/textView9"
app:layout_constraintEnd_toStartOf="@+id/textView9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView9" />

</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>

و در نهایت خود کلاس اداپتر

package dn.marjan.realtimesearch.adapter

import android.content.Context
import android.support.annotation.Nullable
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import dn.marjan.realtimesearch.R
import dn.marjan.realtimesearch.Students
import kotlinx.android.synthetic.main.view_list_item.view.*

/**
* Created by Marjan.Dnejad
* on 4/24/2018.
*/
class StudentsAdapter( val interactor: StudentsAdapterInteractor)
: RecyclerView.Adapter<StudentsAdapter.StudentsViewHolder>() {

private var mList: ArrayList<Students> =ArrayList()

fun setItems(@Nullable mList: ArrayList<Students>){
this.mList=mList
notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StudentsViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.view_list_item, parent, false)
return StudentsViewHolder(view)
}

override fun getItemCount(): Int = mList.size

override fun onBindViewHolder(holder: StudentsViewHolder, position: Int) {
val student=mList[position]

//bind data to item
holder.bindItems(student)

//when click on an item
holder.itemView.card_stud.setOnClickListener {
interactor.setStudentsItemClick(student)
}
}

class StudentsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(stud: Students){
itemView.txv_name.text = stud.name
itemView.txv_avr.text = stud.average
itemView.txv_family.text = stud.family

}
}

}

interface StudentsAdapterInteractor{
fun setStudentsItemClick(student: Students)

}

خب حالا دیگه چیزی نمونده جز لایه اصلی که فایل 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"
android:id="@+id/dynamic_view"
tools:context=".MainActivity">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="@string/toolbar_title"
android:textColor="?attr/colorBackgroundFloating"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.92"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="8dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_keyboard_arrow_left_black_24dp" />

<EditText
android:id="@+id/edt_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:background="@android:color/background_light"
android:ems="10"
android:inputType="textPersonName"
android:paddingTop="3dp"
android:paddingRight="35dp"
android:paddingBottom="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />

<ImageView
android:id="@+id/imageView2"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="@+id/edt_search"
app:layout_constraintEnd_toEndOf="@+id/edt_search"
app:layout_constraintTop_toTopOf="@+id/edt_search"
app:srcCompat="@drawable/ic_search_black_24dp" />

</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.Toolbar>

<android.support.v7.widget.RecyclerView
android:id="@+id/rcv_list"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
</android.support.constraint.ConstraintLayout>

و فایل اکتیویتی لانچر یا MainActivity هم بدین صورت هست

 

package dn.marjan.realtimesearch

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import com.jakewharton.rxbinding.widget.RxTextView
import dn.marjan.realtimesearch.adapter.StudentsAdapter
import dn.marjan.realtimesearch.adapter.StudentsAdapterInteractor
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Response
import rx.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit

class MainActivity : AppCompatActivity(), StudentsAdapterInteractor {

private lateinit var mAdapter: StudentsAdapter

private var mList = ArrayList<Students>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

configViews()

getStudentsData()
}

// config all views in layout
private fun configViews(){

mAdapter = StudentsAdapter(this)

rcv_list.layoutManager = LinearLayoutManager(this)
rcv_list.adapter = mAdapter

//search editText config for realtime search
RxTextView.textChanges(edt_search)
.debounce(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.subscribe { charSequence ->
if (charSequence.toString().isNotEmpty())
mAdapter.setItems(Students.searchStudent(this,charSequence.toString(),mList))
else
mAdapter.setItems(mList)
}
}

// get data from server
private fun getStudentsData(){
ServiceGenerator().getService().getStudents().enqueue(object : retrofit2.Callback<ResponseBody>{
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
Log.d("SERVER ERROR",t.message)
}

override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
val students = Students.getStudentsFromJson(response.body().string())

mList = students as ArrayList<Students>
mAdapter.setItems(mList) // set data to list
}

})
}

//when click on an item in adapter
override fun setStudentsItemClick(stud: Students) {
Students.studentItemClick(stud,this,this)
}
}

نکته قابل توجه در این فایل تکه کد زیر هست

 //search editText config for realtime search
        RxTextView.textChanges(edt_search)
                .debounce(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
                .subscribe { charSequence ->
                    if (charSequence.toString().isNotEmpty())
                        mAdapter.setItems(Students.searchStudent(this,charSequence.toString(),mList))
                    else
                        mAdapter.setItems(mList)
                }

خب حالا این کد داره چیکار میکنه؟ طبیعیه یکی دیگه از معجزات RX !
درواقع به جای TextWacher که اونم یه سری آپشنا کم داشت نسبت به این , از RxBinding استفاده شده
توضیح کلی این تکه کد :
ابتدا با اپراتور textChanges مشخص میکنیم که حواست به کدوم ادیت تکست باشه و تمام فعالیت های اونو بشدت ریز رسد کن !
بعد با اپراتور debounce مشخص میکنیم بعد از گذشت چه مدت (میلی ثانیه ٫ ثانیه ٫ دقیقه و …) به تغییرات روی ادیت تکست مشخص شده واکنش نشون بده که ما ۵۰۰ میلی ثانیه رو مشخص کردیم و پارامتر دوم هم مشخص میکنه ک این عملیات در ترد اصلی انجام شه
اپراتور subscribe مشخص کننده عملیاتی ست که باید پس از گذشت زمان مشخص شده انجام شود.

بقیه متدها و دستورات هم که با کامنت مشخص شده
حالا برنامه رو ران کنیم شاهد این هستیم که برنامه بی عیب کار میکنه و میتونید لیستی که از سرور میاد رو ببینید و سرچ بزنید و نتیجه سرچ رو بصورت آنی ببینید

دستورات سرور :

اگر مایل هستید که بدونید سمت سرور چه اتفاقی داره میوفته و این اطلاعات با چه دستوراتی از سرور برمیگرده
دستورات سرور بدین صورت هست

<?php
$con = mysqli_connect("localhost", "", "", "test");

// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

mysqli_set_charset($con,"utf8");

$sql = "SELECT * FROM tbl_students";
$result = $con->query($sql);

if ($result->num_rows > 0) {
$stus = array();
while ($row = $result->fetch_assoc()) {
$arr = array(
"ID"=>$row['ID'],
"Name"=>$row['Name'],
"Family"=>$row['Family'],
"Age"=>$row['Age'],
"Average"=>$row['Average'],
"City"=>$row['City']
);

array_push($stus, $arr);
}

echo json_encode($stus);
} else {
echo "0 results";
}
$con->close();

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *