Пользовательский адаптер - что делать?
Я провел все утро на этом. Не смог найти ни одного полезного решения, хотя я прошел через множество проблем. Я просто собираюсь опубликовать свой код.
Что я хочу? У меня есть RSS Reader, который получает новости с сайта, сохраняет их в специальном классе. Я хочу создать ListView с индивидуальным дизайном, который отображает заголовок каждого элемента новостей. Это работает отлично, если я просто использую по умолчанию simple_list_view_1 от Android, но я хочу индивидуальный дизайн в ListView.
Вот мой код:
ArrayList<SingleNewsItem> newsList = new ArrayList<SingleNewsItem>();
Это SingleNewsItem:
public class SingleNewsItem
{
private String pubDate;
private String title;
private String description;
private String link;
public String getPubDate()
{
return pubDate;
}
public String getTitle()
{
return title;
}
public String getDescription()
{
return description;
}
public String getLink()
{
return link;
}
public SingleNewsItem(String _pubDate, String _title, String _description, String _link)
{
pubDate = _pubDate;
description = _description;
title = _title;
link = _link;
}
@Override
public String toString()
{
return title;
}
}
Вот пользовательский адаптер, который я пытался создать:
public class NewsAdapter extends ArrayAdapter<ArrayList<SingleNewsItem>>
{
Context context;
int layoutResourceId;
ArrayList<SingleNewsItem> news;
LayoutInflater inflater;
public NewsAdapter(Context context, int textViewResourceId, ArrayList<SingleNewsItem> objects)
{
super(context, textViewResourceId, objects);
this.context = context;
this.layoutResourceId = textViewResourceId;
this.news = objects;
inflater = LayoutInflater.from(context);
}
@Override
public View getView( int position, View convertView, ViewGroup parent)
{
convertView = (RelativeLayout) inflater.inflate(layoutResourceId, null);
ArrayList item = getItem(position);
TextView title = (TextView) convertView.findViewById(R.id.text1);
title.setText(item.toString());
return parent;
}
}
Это мой пользовательский просмотр списка. У него есть только один TextView, который мне нужен для заголовка:
<View
android:id="@+id/view1"
android:layout_width="15dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@android:color/holo_blue_bright" />
<View
android:id="@+id/view2"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignParentLeft="true"
android:layout_below="@+id/view1"
android:background="#660000" />
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/view1"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/view1"
android:gravity="center_vertical"
android:textSize="16dp"
android:paddingLeft="10dp"
android:background="@android:color/darker_gray"
android:textColor="#ffffff" />
Вот последние строки:
myListView.setAdapter(new NewsAdapter(this, R.layout.listview, newsList));
Это не работает Прямо сейчас ошибка находится в классе NewsAdapter. Это говорит:
The constructor ArrayAdapter<ArrayList<SingleNewsItem>>(Context, int, ArrayList<SingleNewsItem>) is undefined
EDIT / UPDATE
После запуска приложения появляется следующая ошибка принудительного закрытия:
FATAL EXCEPTION: main
java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams
at android.widget.ListView.measureScrapChild(ListView.java:1152)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1235)
at android.widget.ListView.onMeasure(ListView.java:1144)
at android.view.View.measure(View.java:8366)
at android.widget.RelativeLayout.measureChild(RelativeLayout.java:566)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:381)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
at android.view.View.measure(View.java:8366)
at android.view.ViewRoot.performTraversals(ViewRoot.java:844)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
1 ответ
ArrayList item = getItem(position);
должно быть
SingleNewsItem item = (SingleNewsItem) getItem(position);
И если вы переопределите getItem()
способ заставить его вернуть SingleNewsItem
вместо Object
Вам даже не придется его разыгрывать.
Затем просто попытайтесь сохранить все ваши исходные файлы, обновить + очистить ваш проект, это может быть именно так (это случается чаще, чем вы думаете).
РЕДАКТИРОВАТЬ Также ваш код не оптимизирован, потому что getView()
метод может вызываться несколько раз даже для представления, которое уже было создано, например, при прокрутке ListView. Поэтому вам следует сначала проверить, является ли ваш convertView нулевым или нет:
SingleNewsItem item = getItem(position); //You should override this method
TextView tv;
if (convertView != null) { //View already created
tv = (TextView) convertView.getTag();
}
else { //View already created
convertView = this.inflater.inflate(layoutResourceId, null);
tv = (TextView) convertView.findViewById(R.id.text1);
convertView.setTag(tv);
}
tv.setText(item.toString());