غير قادر على استخدام layoutinflater في محول مخصص
-
29-09-2019 - |
سؤال
أنا أبحث في كتابة محول مخصص لإلغاء عرض قائمة مع 3 TextViews لكل سطر. لقد وجدت الكثير من الكود على سبيل المثال للقيام بذلك ، لكن الكود الذي بدا أنه الأفضل في: http://www.anddev.org/custom_widget_adapters-t1796.html
بعد بضع تعديلات طفيفة لإصلاح بعض مشكلات التحويل البرمجي مع أحدث Android SDK ، قمت بتشغيلها ، فقط للحصول على الاستثناء:
خطأ/AndroidRuntime (281): java.lang.unsupportedOperationException: addview (view ، layoutparams) غير مدعوم في AdapterView
لذلك قمت بالكثير من الأبحاث ووجدت الكثير من الأسباب والإصلاحات المحتملة لهذا الغرض. لم يغير أي شيء شيئًا. رمز المحول الخاص بي حاليا:
public class WeatherAdapter extends BaseAdapter {
private Context context;
private List<Weather> weatherList;
public WeatherAdapter(Context context, int rowResID,
List<Weather> weatherList ) {
this.context = context;
this.weatherList = weatherList;
}
public int getCount() {
return weatherList.size();
}
public Object getItem(int position) {
return weatherList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
Weather weather = weatherList.get(position);
//LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.weather_row, null, true);
TextView cityControl = (TextView)v.findViewById( R.id.city );
TextView temperatureControl = (TextView)v.findViewById( R.id.temperature );
ImageView skyControl = (ImageView)v.findViewById( R.id.sky );
return v;
}
}
لذلك جربت الطريقة التي تم التعليق عليها للحصول على الإضافات ، والخروج حاليًا. لقد حاولت تمرير "الوالد" للتضخيم وكذلك الفارغ ، وتمرير "True" ، "False" وحذف المعلمة الأخيرة تمامًا. لم ينجح أي منهم ، وجميع الأمثلة التي وجدتها حتى الآن منذ عام 2008 والتي أشعر أنها قديمة بعض الشيء.
إذا كان بإمكان أي شخص المساعدة في هذا ، فأنا أحب حل المشكلة.
المحلول
أنا مبتدئ أيضًا ، لذا خذ هذه الإجابة بقليل من الملح - إذا لم ينجح ، فانتقل إلى Google أكثر. لست على دراية AdapterView
منذ أن لدي تقليديا ListView
أو GridView
ومحول مخصص مدد من أ BaseAdapter
وثم listView.setAdapter(myCustomAdapter)
.
يمكنك محاولة صنع شيء مثل هذا داخل WeatherAdapter
صف دراسي:
public void addToList(Weather mWeather) {
weatherList.add(mWeather);
}
ثم في الفصل الذي يتصل WeatherAdapter
:
weatherAdapter.addToList(weatherToAdd);
weatherAdapter.notifyDataSetChanged();
كما تحتاج إلى تحسينه أكثر في طريقة GetView:
نصائح أخرى
أعتقد أن هذا الخط على خطأ:
View v = inflater.inflate(R.layout.weather_row, null, true);
تحتاج بدلاً من ذلك:
View v = inflater.inflate(R.layout.weather_row, parent, false);
يجعل الخاطئة الرأي المتضخم مستقلاً عن الوالد ، غير مرتبط به ، والذي يبدو أنه من الغريب أن التصميم المقبول لوجهات النظر المخصصة في الداخل AdapterView
س. لماذا هذا الأمر ، أجد محيرًا تمامًا ، لكن النمط أعلاه عمل بالنسبة لي.
ل AdaptertView addView
طريقة:
void addview (عرض الطفل)
هذه الطريقة غير مدعومة وتلقي بعدم دعمها عند استدعاء. "(من وثائق Android)
ربما يستدعي إجراء التضخم addView
الطريقة وهذا غير ممكن من AdapterView
, ، أو AdapterView
.
من الوثائق:
"يعمل كائن محول كجسر بين محول وبيانات أساسية لهذا العرض. يوفر المحول إمكانية الوصول إلى عناصر البيانات. المحول مسؤول أيضًا عن تقديم طريقة عرض لكل عنصر في مجموعة البيانات".
أعتقد أنه يمكن إجراء عملية التضخمة من نشاط بسيط يصمم عرضك وجميع العمليات الأخرى ، على سبيل المثال ، استرداد البيانات وإظهار البيانات في فئات أخرى.
نأمل أن تكون مفيدة!
إجابة @Axel22 هي المفتاح ، ولكن هناك بعض الأشياء الأخرى المفقودة من الكود الخاص بك. أولاً ، يجب أن تمتد إما BaseAdapter أو ArrayAdapter ، اعتمادًا على تفضيلاتك. ثانياً ، تريد الحصول على ممارسة استخدام حامل Viewhold لتجنب إجراء مكالمات مفرطة إلى FindViewById ، (الأهم من ذلك) إعادة تدوير وجهة نظرك.
private Class ViewHolder {
public TextView cityControl;
public TextView temperatureControl;
public ImageView skyControl;
public ViewHolder(TextView cityControl, TextView temperatureControl, ImageView skyControl) {
this.cityControl = cityControl;
this.temperatureControl = temperatureControl;
this.skyControl = skyControl;
}
يمكن لوظيفة GetView إعادة تدوير المشاهدات واستخدامها ViewHolder
الفصل على النحو التالي:
public View getView(int position, View convertView, ViewGroup parent) {
Weather weather = weatherList.get(position);
// This is how you attempt to recycle the convertView, so you aren't
// needlessly inflating layouts.
View v = convertView;
ViewHolder holder;
if (null == v) {
v = LayoutInflater.from(getContext()).inflate(R.layout.weather_row, parent, false);
TextView cityControl = (TextView)v.findViewById( R.id.city );
TextView temperatureControl = (TextView)v.findViewById( R.id.temperature );
ImageView skyControl = (ImageView)v.findViewById( R.id.sky );
holder = new ViewHolder(cityControl, temperatureControl, skyControl);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.cityControl.setText("Metropolis");
holder.temperatureControl.setText("78");
holder.skyControl.setImageResource(R.drawable.daily_planet);
return v;
}
للحصول على المزيد من الأمثلة (ونصائح التحسين الأخرى) ، انظر منشور المدونة هذا (أو مجرد Google لـ ViewHolder).