CustomAdapter getCount()首先返回一个正数,但在

时间:2018-05-10 19:54:36

标签: android android-adapter custom-adapter

我制作了一个自定义适配器,以便我可以创建自定义列表视图。自定义适配器接受我自己的RowItem类的ArrayList,并且应该填充我的活动中的列表视图。

当我尝试使用自定义适配器时,我的活动中没有任何内容。经过一些研究后,我怀疑它可能是我的适配器的getCount函数返回0,所以我添加了一些日志信息来检查它。

它显示的是,起初,我的getCount确实返回一个正值(100),但接下来的下一刻,它返回一个零,然后继续这样做,这意味着我的getView没有被调用,列表仍然是空的。

这是我的活动

package com.example.topsongsbyyear;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


import java.util.ArrayList;

public class SongList extends AppCompatActivity implements Response.ErrorListener, Response.Listener<String> {
    String webUrl;
    String year;
    RequestQueue requestQueue;
    StringRequest stringRequest;
    RowItem row;
    ListView list;
    ArrayList<RowItem> rows;
    ListAdapter customAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        year = getIntent().getStringExtra("year");
        webUrl = "https://www.billboard.com/charts/year-end/" + year + "/hot-100-songs";
        setContentView(R.layout.activity_song_list);
        rows = new ArrayList<RowItem>();
        list = (ListView) findViewById(R.id.all_list);
        list.setAdapter(customAdapter);
        requestQueue = Volley.newRequestQueue(this);
        stringRequest = new StringRequest(Request.Method.GET, webUrl, this, this);
        requestQueue.add(stringRequest);
        requestQueue.start();
    }

    @Override
    public void onErrorResponse(VolleyError error) {
        Log.i("----------------", "onErrorResponse executed");
    }

    @Override
    public void onResponse(String response){
        int rank = 1;
        Log.i("----------------", "onResponse executed");
        Document doc = Jsoup.parse(response);
        parseHtml(doc);
        //call setData function in adapter
        //in setData, save the data and call notifyDataSetChanged (adapter method), which updates list view
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }

    public void parseHtml(Document doc){
        ArrayList<String> songList = new ArrayList<>();
        ArrayList<String> artistList = new ArrayList<>();
        ArrayList<String> imageUrls = new ArrayList<>();
        rows = new ArrayList<RowItem>();
        Elements songs = doc.select(".ye-chart-item__title");
        for(Element song : songs){
            songList.add(song.text().toString());
        }
        Elements artists = doc.select(".ye-chart-item__artist");
        for(Element artist : artists){
            artistList.add(artist.text().toString());
        }
        Elements images = doc.select("div.ye-chart-item__image > img");
        for (Element image : images) {
            imageUrls.add(image.attr("src"));
        }
        for(int i = 0; i < songList.size(); i++){
            RowItem row = new RowItem(Integer.toString(i+1), songList.get(i), artistList.get(i), imageUrls.get(i));
            rows.add(row);
        }
        Log.i("----------------", "Just added to rows arrayList with songList size: " + songList.size() + " artistList size: " + artistList.size() + "and imageUrls size: " +imageUrls.size());
        Log.i("----------------", "Just before setting making customAdapter instance with row count " + rows.size());
        customAdapter = new CustomAdapter(this, R.layout.row_layout, rows);
        list.setAdapter(customAdapter);
        if (customAdapter instanceof CustomAdapter){
            ((CustomAdapter) customAdapter).setData(rows);
        }
        Log.i("----------------","Adapter set after html parsed, with row count " + rows.size());




    }
}

这是我的自定义适配器类

package com.example.topsongsbyyear;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;


import com.bumptech.glide.Glide;

import java.util.ArrayList;

public class CustomAdapter extends ArrayAdapter<RowItem> {
    Context context;
    ArrayList<RowItem> rows;
    TextView songName;
    TextView artist;
    TextView rank;
    ImageView image;

    public CustomAdapter(@NonNull Context context, int resource, ArrayList<RowItem> rows) {
        super(context, resource, rows);
        this.rows = rows;
        Log.i("--------------", "row filled with " + this.rows.size() + " elements");
        notifyDataSetChanged();
        //setData(rows);
    }

    public void setData(ArrayList<RowItem> rows){
        clear();
        addAll(rows);
        Log.i("----------------", "setData called, cleared and then addAll(rows) with row count: " + rows.size());
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        Log.i("----------------", "CustomAdapter getCount called, returning rows.size() which is: " + rows.size());
        return rows.size();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.i("---------------", "entered getView function");
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View customView = convertView;
        if (convertView == null)
            customView = inflater.inflate(R.layout.row_layout, parent, false);

        //setData(rows);
        String singleSong = rows.get(position).getSong();
        String singleArtist = rows.get(position).getArtist();
        String singleRank = rows.get(position).getRank();
        String singleImage = rows.get(position).getPicUrl();
        songName = (TextView) customView.findViewById(R.id.title);
        artist = (TextView) customView.findViewById(R.id.artist);
        rank = (TextView) customView.findViewById(R.id.rank);
        Log.i("----------------", "ADDED: " + singleRank + " " + singleSong + " by " + singleArtist +" TO LIST");
        image = (ImageView) customView.findViewById(R.id.list_image);

        songName.setText(singleSong);
        artist.setText(singleArtist);
        rank.setText(singleRank);

        Glide.with(context).
                load(singleImage).
                into(image);

        return customView;
    }

}

这是包含我的消息的日志,如果有帮助

05-10 19:49:54.610 29217-29217/com.example.topsongsbyyear I/----------------: onResponse executed
05-10 19:49:54.657 29217-29217/com.example.topsongsbyyear I/----------------: Just added to rows arrayList with songList size: 100 artistList size: 100and imageUrls size: 100
05-10 19:49:54.658 29217-29217/com.example.topsongsbyyear I/----------------: Just before setting making customAdapter instance with row count 100
05-10 19:49:54.658 29217-29217/com.example.topsongsbyyear I/--------------: row filled with 100 elements
05-10 19:49:54.658 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 100
    CustomAdapter getCount called, returning rows.size() which is: 100
05-10 19:49:54.659 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 0
05-10 19:49:54.659 29217-29217/com.example.topsongsbyyear I/chatty: uid=10086(com.example.topsongsbyyear) identical 2 lines
05-10 19:49:54.660 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 0
    setData called, cleared and then addAll(rows) with row count: 0
    CustomAdapter getCount called, returning rows.size() which is: 0
    CustomAdapter getCount called, returning rows.size() which is: 0
    Adapter set after html parsed, with row count 0
05-10 19:49:54.675 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 0
05-10 19:49:54.681 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 0
05-10 19:49:54.842 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 0
05-10 19:49:54.844 29217-29217/com.example.topsongsbyyear I/----------------: CustomAdapter getCount called, returning rows.size() which is: 0
05-10 19:49:55.057 29217-29241/com.example.topsongsbyyear I/chatty: uid=10086(com.example.topsongsbyyear) RenderThread identical 2 lines

另外,如果我的setData函数没有在任何地方调用(在我的parseHtml或自定义适配器构造函数中),我的应用程序崩溃了。

有谁知道我做错了什么?感谢。

1 个答案:

答案 0 :(得分:0)

尝试设置this.rows = rows;在你的setData方法中,你可以随时更新它。

请注意,您只在CustomAdapter的构造函数中设置this.rows,而当您执行setData时,您没有设置它。另外,调用clear();在setData中,正在清除this.rows列表,因为数组适配器包含对您在构造函数中通过super的列表的引用。