Пользовательский адаптер - что делать?

Я провел все утро на этом. Не смог найти ни одного полезного решения, хотя я прошел через множество проблем. Я просто собираюсь опубликовать свой код.

Что я хочу? У меня есть 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());
Другие вопросы по тегам