كيفية تحديث ListView ديناميكيًا على Android [مغلق]
-
20-09-2019 - |
سؤال
على نظام Android، كيف يمكنني ListView
التي تقوم بالتصفية بناءً على إدخال المستخدم، حيث يتم تحديث العناصر المعروضة ديناميكيًا بناءً على TextView
قيمة؟
أنا أبحث عن شيء مثل هذا:
-------------------------
| Text View |
-------------------------
| List item |
| List item |
| List item |
| List item |
| |
| |
| |
| |
-------------------------
المحلول
أولا، تحتاج إلى إنشاء تخطيط XML التي تحتوي على حد سواء EDITTEXT، وListView.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<!-- Pretty hint text, and maxLines -->
<EditText android:id="@+building_list/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="type to filter"
android:inputType="text"
android:maxLines="1"/>
<!-- Set height to 0, and let the weight param expand it -->
<!-- Note the use of the default ID! This lets us use a
ListActivity still! -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
</LinearLayout>
وهذا سيضع كل شيء بشكل صحيح، مع EDITTEXT لطيفة فوق يكون ListView. بعد ذلك، إنشاء ListActivity كما تفعل عادة، ولكن إضافة مكالمة setContentView()
في طريقة onCreate()
لذلك نحن نستخدم تخطيط أعلن مؤخرا. نتذكر أننا ID'ed وListView
خصيصا، مع android:id="@android:id/list"
. وهذا يسمح للListActivity
لمعرفة أي ListView
نريد لاستخدامها في تخطيط أعلن لدينا.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.filterable_listview);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}
وتشغيل التطبيق الآن يجب أن تظهر ListView
السابق الخاص، مع مربع لطيفة أعلاه. من أجل جعل هذا المربع تفعل شيئا، نحن بحاجة إلى اتخاذ مدخلات منه، وجعل ذلك تصفية إدخال القائمة. في حين أن الكثير من الناس قد حاول القيام بذلك يدويا، <م> معظم م> دروس ListView
Adapter
تأتي مع كائن Filter
التي يمكن استخدامها لإجراء تصفية التلقائى. نحن بحاجة فقط إلى أنبوب الإدخال من EditText
في Filter
. وتبين أن من السهل جدا. لتشغيل اختبار سريع، إضافة هذا الخط لدعوة onCreate()
بك
adapter.getFilter().filter(s);
لاحظ أنك لن تحتاج إلى حفظ ListAdapter
لمتغير لجعل هذا العمل -. لقد أنقذ بلادي ArrayAdapter<String>
من قبل إلى متغير يسمى "محول"
والخطوة التالية هي الحصول على مدخلات من EditText
. يأخذ هذا الواقع قليلا من التفكير. هل يمكن إضافة OnKeyListener()
إلى EditText
الخاص بك. ومع ذلك، هذا المستمع يتلقى فقط <م> بعض الأحداث الرئيسية م>. على سبيل المثال، إذا كان المستخدم بإدخال "wyw"، والنص التنبؤي من المرجح يوصي 'العين'. حتى يختار المستخدم إما 'wyw "أو" العين "، وOnKeyListener
الخاص بك لا تتلقى الحدث الرئيسي. قد تفضل بعض هذا الحل، ولكنني وجدت أنه من المحبط. كنت أريد كل الحدث الرئيسي، لذلك اضطررت لاختيار ترشيح أو عدم ترشيح. الحل هو TextWatcher
. ببساطة إنشاء وإضافة TextWatcher
إلى EditText
، وتمرير ListAdapter
Filter
مرشح أن يطلب في كل مرة يتغير النص. تذكر لإزالة TextWatcher
في OnDestroy()
! هنا هو الحل النهائي:
private EditText filterText = null;
ArrayAdapter<String> adapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.filterable_listview);
filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}
نصائح أخرى
وتشغيل البرنامج للسيسبب قريب القوة.
وأنا swaped السطر:
<اقتباس فقرة>والروبوت: معرف = "@ + building_list / search_box"
اقتباس فقرة>مع
<اقتباس فقرة>والروبوت: معرف = "@ + معرف / search_box"
اقتباس فقرة>ويمكن أن تكون المشكلة؟ ما هو '@ + building_list "ل؟
واجهت مشكلة في التصفية ، وقد تم تصفية النتائج ، ولكن لم يتم استعادتها!
لذلك قبل التصفية (بدء النشاط) قمت بإنشاء نسخة احتياطية للقائمة..(مجرد قائمة أخرى تحتوي على نفس البيانات)
عند التصفية، يتم توصيل المرشح ومحول القائمة بالقائمة الأساسية.
لكن الفلتر نفسه استخدم البيانات من القائمة المنسوخة احتياطيًا.
وهذا يضمن في حالتي أنه تم تحديث القائمة على الفور وحتى عند حذف أحرف مصطلح البحث، يتم استعادة القائمة بنجاح في كل حالة :)
شكرا لهذا الحل على أي حال.